Jef Aime
Jef Aime

Reputation: 33

Design the output with awk or gawk script

I have a awk script which give me the result i want on a .txt file but my concern is how the result is given: I have all of them in a single line and i want to design it.

20140201 -73828274 20140202 7376288374 20140203 3837482437 ....... 20140228 -73629277

I want the output to be displayed in this format

20140201          -73828274
20140202         7376288374
20140203         3837482437
n                  n
n                  n
n                  n
20140228           73629277

I want date one side and the corresponded total in front of the date

Here the awk script used

$ for file in *.txt;do awk -F,'NR==1{header=$0; next} {a[$1]+=$6+$14} END {for (i in a) {print i, a[i]};}' $file; done > red.txt

ANY IDEA ?

Upvotes: 1

Views: 49

Answers (4)

Ed Morton
Ed Morton

Reputation: 203995

You don't need a shell loop, awk is perfectly capable of working on multiple files, e.g. with GNU awk for ENDFILE and delete array:

awk -F, 'FNR>1{a[$1]+=$6+$14} ENDFILE{for (i in a) print i, a[i]; delete a}' *.txt > red.txt

The above is obviously untested since you didn't provide any sample input.

The script you posted CANNOT produce the output you show though. There is something else you are doing after the awk script runs to make it appear to you as if all lines of your output file are on a single line. I suspect you are probably not quoting a variable again (like you didn't quote $file in your script) and doing something like:

var=$(cat red.txt)
echo $var

Once your script is done running simply do cat red.txt and you will see that the content is NOT all on one line as you claim.

Upvotes: 1

Jotne
Jotne

Reputation: 41460

Her is a simple way to do it with awk

awk -v RS=" " 'ORS=NR%2?RS:"\n"' file
20140201 -73828274
20140202 7376288374
20140203 3837482437

First we sett Record Selector to space, so every date is a new line.
Then we change the Output Record Selector to space or newline based on odd and even line number.


You can also use the getline with this, but take care, getline has many pitfall.

awk -v RS=" " '{a=$0;getline;print a,$0}' file
20140201 -73828274
20140202 7376288374
20140203 3837482437

This way you can have more control of the output using printf

Upvotes: 0

Avinash Raj
Avinash Raj

Reputation: 174776

Use grep and tr like below,

$ grep -oP '\S+\s+\S+' file | tr ' ' '\t'
20140201    -73828274
20140202    7376288374
20140203    3837482437
20140228    -73629277

Upvotes: 1

chaos
chaos

Reputation: 9302

Instead of print you can use printf. Change the END{} part of your awk script as follows:

END {for (i in a) {printf "%d\t%d\n", i, a[i]};}

Between the two values (%d) it prints a tab (\t) and at the end a newline (\n).

Or your complete command:

for file in *.txt;do awk -F,'NR==1{header=$0; next} {a[$1]+=$6+$14} END {for (i in a) {printf "%d\t%d\n", i, a[i]};}' $file; done > red.txt

Upvotes: 1

Related Questions