using awk with find -exec

What am I doing wrong?

You are using the redirection > ../pos/'{}' as if it was handled by find or awk but redirections are handled by the shell. In your case it means that you can redirect only output of the whole find (not output of awk).

Note that you do not usually need to use wildcard like * for the starting path of find. Is the common way find . what you wanted to do or is there any reason for find *?

Solutions

Here we will keep the flexibility of find in contrast to the solution by Jacobo de Vera. Run awk in a shell loop:

find . -type f -print0 |
  while read -r -d $'\0' x; do
    awk '{print $2}' "$x" > "../pos/$(basename "$x")"
  done

The original way with -exec will be less efficient because for every file a shell will be launched in addition to awk and the multi-level escaping is pretty complicated here:

find . -type f -exec sh -c 'awk "{print \$2}" "{}" > "../pos/{}"' \;

There could also be an alternative solution of doing the redirection inside awk.


You could try without find, if all you want is all the files. While in data/all/, run this:

for file in ./*; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done

If you want to cover the files in the whole hierarchy under /data/all, you can enable the globstar option if you are using bash (I believe this would "just work" on zsh) and then use ** to match all files:

shopt -s globstar
for file in ./**; do awk '{print$2}' "$file" > "../pos/$(basename $file)"; done

Tags:

Unix

Awk

Find