AWK – How to Apply the Same Action to Multiple Files

awkshell

I am new in awk and I do not know if it is possible to write an awk script that does this:

I have hundred of data files that I have to sort. For each one I use the following one-liner:

awk 'ORS=NR%3?" ":"\n" ' file1.tex >  file1_sorted.tex
awk 'ORS=NR%3?" ":"\n" ' file2.tex >  file2_sorted.tex
...

and I get the output I need. However I would like to have an script to automate this action, taking each file, applying the action and writing the corresponding sorted file.

I would appreciate your help!

Best Answer

If you modify the awk code, can be solved by a single awk process and no shell loop:

awk 'FNR==1{if(o)close(o);o=FILENAME;sub(/\.tex/,"_sorted.tex",o)}{ORS=FNR%3?" ":"\n";print>o}' *.tex

Not a beauty, just insignificantly faster.

Explanations as requested in comment.

FNR (file number or record) is similar to NR (number or record), but while NR is a continuous sequence number of all input records, FNR is reset to 1 when processing of a new input file is started.

A gawk 4.0 only alternative for the FNR==1 is the BEGINFILE special pattern.

awk '
FNR==1{   # first record of an input file?
  if(o)close(o);   # was previous output file? close it
  o=FILENAME;sub(/\.tex/,"_sorted.tex",o)   # new output file name
}
{
  ORS=FNR%3?" ":"\n";   # set ORS based on FNR (not NR as in the original code)
  print>o   # print to the current output file
}
' *.tex
Related Question