How to Save the Output of This Awk Command to File

How to save the output of this awk command to file?


awk '{ print $2 }' text.txt > outputfile.txt

> => This will redirect STDOUT to a file. If file not exists, it will create it. If file exists it will clear out (in effect) the content and will write new data to it

>> => This means same as above but if file exists, this will append new data to it.

Eg:

$ cat /etc/passwd | awk -F: '{ print $1 }' | tail -10 > output.txt
$ cat output.txt
_warmd
_dovenull
_netstatistics
_avbdeviced
_krb_krbtgt
_krb_kadmin
_krb_changepw
_krb_kerberos
_krb_anonymous
_assetcache

Alternatively you can use the command tee for redirection. The command tee will redirect STDOUT to a specified file as well as the terminal screen

For more about shell redirection goto following link:

http://www.techtrunch.com/scripting/redirections-and-file-descriptors

How to output awk result to file

Output redirection is generally a feature of the shell you're working with and, given how much use it gets, I'd be pretty amazed if you'd found a bug in it :-)

Are you sure you're not trying to do redirection with awk itself rather than the shell?

What happens when you do:

echo 'hello' | awk '{print}' >qq.tmp

Update:

If this is your code as stated, it's because the $a is not being expanded by your shell script since the awk command is within single quotes.

for a in $(find $OUPUT_DIR/ -maxdepth 1 -mindepth 1 -type d -printf "%P\n")
do
echo $a is a directory
awk -F, '{ if ($10 == '"$a"') print $0 }' $OUPUT_DIR/CDRNOutput_${CDR_DATE}.csv > $OUPUT_DIR/$a/CDR-${CDR_DATE}.csv
done

What I tend to do is pass in specific values to awk using the -v option, something like (in your case):

awk -F, -v a=$a '{ if ($10==a) print $0 }' ...

Then the variables become first-class awk citizens without having to worry about who's doing the expansion.


Further update:

I'm standing behind my original advice. There's something definitely screwy with the method chosen.

I have a directory in my home directory called XpVm (among others) and I've created the file CDRNOutput_X.csv containing the single line:

1,2,3,4,5,6,7,8,9,XpVm,11

When I execute:

for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
echo $a is a directory
awk -F, '{
if ($10 == '"$a"') {
print $0
} else {
print "NO";
}
}' ./CDRNOutput_X.csv
done

(I've stripped out directories starting with . since they were causing another problem), I get this output:

workspace is a directory
NO
Documents is a directory
NO
XpVm is a directory
NO
Downloads is a directory
NO

which is clearly not what is expected. However, when I use the -v option to awk as I originally suggested, the command:

for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
echo $a is a directory
awk -F, -v a=$a '{
if ($10 == a) {
print $0
} else {
print "NO"
}
}' ./CDRNOutput_X.csv
done

(the only difference being the changes to a), I get:

workspace is a directory
NO
Documents is a directory
NO
XpVm is a directory
1,2,3,4,5,6,7,8,9,XpVm,11
Downloads is a directory
NO

which is correct.


Final update (hopefully):

I think I have the problem solved. I'm on a different machine now (so the directory names are simply tmp and tmp2) and, when I run the original script:

for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
echo $a is a directory
awk -F, '{
if ($10 == '"$a"') {
print $0
} else {
print "NO";
}
}' ./CDRNOutput_X.csv
done

with a modified CDRNOutput_X.csv containing tmp instead of XpVm, I get:

tmp is a directory
NO
tmp2 is a directory
NO

That's because the if statement is being seen by awk as:

        if ($10 == tmp) {

(without quotes, since the quotes are actually outside the awk string being used to surround the directory name). This will test $10 for equality against the awk variable called tmp rather than the actual string "tmp". What you need is to make sure that the quotes are inside the awk script, like:

        if ($10 == "tmp") {

and you can do this with the following script (only the if line has changed):

#!/bin/bash
for a in $(find . -maxdepth 1 -mindepth 1 -type d -printf "%P\n" | grep -v '^\.')
do
echo $a is a directory
awk -F, '{
if ($10 == "'"$a"'") {
print $0
} else {
print "NO";
}
}' ./CDRNOutput_X.csv
done

Note that the double quotes are duplicated. I've still kept the double quotes immediately around $a in case someone's committed the heinous crime of creating a file with a space in it :-)

Running that script produces:

tmp is a directory
1,2,3,4,5,6,7,8,9,tmp,11
tmp2 is a directory
NO

which is what I think you were aiming for.

So, the upshot is, if you don't want to use awk variables, you can just change your awk string from:

'{ if ($10 == '"$a"') print $0 }'

to:

'{ if ($10 == "'"$a"'") print $0 }'

and it should function okay.

How to output an awk command into a specific format and save to a file?

You possibly can use awk, but this is easier using shell command:

printf "file %s\n" *.mkv > output.txt

printfis a builtin shell command that outputs the string referred in between double quote for each mkv filename.

Note: Don't parse ls

Write a file using AWK on linux

You need to add proper spaces!

With your erronous awk ' /^-/ {system("echo" $0 ">" "newline.txt")} ', the shell command is essentially echo-xxxxxxxx()xxxxxxxx>newline.txt, which surely doesn't work. You need to construct a proper shell command inside the awk string, and obey awks string concatenation rules, i.e. your intended script should look like this (which is still broken, because $0 is not properly quoted in the resulting shell command):

awk '/^-/ { system("echo " $0 " > newline.txt") }'

However, if you really just need to echo $0 into a file, you can simply do:

awk '/^-/ { print $0 > "newline.txt" }'

Or even more simply

awk '/^-/' > newline.txt

Which essentially applies the default operation to all records matching /^-/, whereby the default operation is to print, which is short for neatly printing the current record, i.e. this script simply filters out the desired records. The > newline.txt redirection outside awk simply puts it into a file.

awk output to a file

I/O redirection are pretty basic when working with the shell. If you want to append lines, use >>. eg

nawk -v file="$FILE" 'BEGIN{RS=";"}
/select/{ gsub(/.*select/,"select");gsub(/\n+/,"");print file,$0;}
/update/{ gsub(/.*update/,"update");gsub(/\n+/,"");print file,$0;}
/insert/{ gsub(/.*insert/,"insert");gsub(/\n+/,"");print file,$0;}
' "$FILE" >> newfile

please spend time reading up on shell scripting if you haven't yet.

how to write finding output to same file using awk command

Not possible per se. You need a second temporary file because you can't read and overwrite the same file. Something like:

awk '(PROGRAM)' testfile.txt > testfile.tmp && mv testfile.tmp testfile.txt

The mktemp program is useful for generating unique temporary file names.

There are some hacks for avoiding a temporary file, but they rely mostly on caching and read buffers and quickly get unstable for larger files.

How do I print this Awk command so I can output to a new file?

The obvious should work:

awk -F '\t'  '{sub(/OriginalShotName/,"Tape")} $1 != "TAPE"' sample.csv > output.csv


Related Topics



Leave a reply



Submit