1

In a parent directory, I have several sub-directories, each of them contain one or more space-delimited text files.

I have the following command that outputs what I want, but only for an individual file INPUTFILE.txt

awk '{if (NF>4){print $1, $2, $3 , "0" } else {print $0}}' INPUTFILE.txt

Considering the fact that I have thousands sub-directories, and the file names will vary, how can I apply this command to all sub-directories; from the parent directory?

  • 1. What do you mean by each of them enclose a table. Do you mean every directory contains a tab-delimited file? 2. In each directory is there always only one file, and always named INPUTFILE.txt or could there be one or more files with a variety of file names? – clarity123 Nov 17 '15 at 19:28
  • @user454038 There is just one ascii table (with space delimiter) in each sub-directories. And yes each table has a different name (that´s the point of my question) accordingly with the sub-directory name. – steve Nov 17 '15 at 19:31
  • Apparently, the edition by @user454038, introduces contradictions! (one or more vs one) – JJoao Nov 17 '15 at 23:28
3

First, cd to your desired parent directory.

Then, make use of the find to run your awk command:

find -type f -exec awk '{if (NF>4){print $1, $2, $3 , "0" } else {print $0}}' {} +

Explanation

  • it is already recursive by default so it will carry this out for all sub-directories
  • -type f will limit to finding files , instead of both files and directories
  • the -exec somecommand {} + syntax runs a command, and puts the file paths found where you write {}
  • the + option has been said to be more efficient because it only runs one instance of awk while putting the find results as arguments in {} whereas the other way of running it (not shown here) would run awk once per each file name and is said to be less efficient
1

Ok The quick and dirty way to do this is with a loop but we need to set some things up first. The following will give you a text file with names and paths of the files on which you wish to run the awk command.You will need to run it from the parent directory.

find . -type f -print >> source.txt

Then you run the loop

for i in $(cat source.txt); do 
  awk '{if (NF>4){print $1, $2, $3 , "0" } else {print $0}}' $i >> OUTPUTFILE.txt
done

It wasn't clear whether you wanted a single output file of if you wanted multiple output files.

If you want multiple output files you can do this:

for i in $(cat source.txt); do 
  awk '{if (NF>4){print $1, $2, $3 , "0" } else {print $0}}' $i >> $i.processed.txt
done
1

UPDATE: The question changed after the answer was written...

for a in */INPUTFILE.txt
do 
   cp "$a" "$a.bak" 
   YOUR-AWK "$a.bak" > "$a" 
done

The new question looks strange!! If I understand it correctly

YOUR-AWK */*.txt > output.txt

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.