2

I have a directory and many more subdirectories like the following -

file with spaces.txt
filewithsuperlonglines.txt
ordinaryfile.txt
binaryfile.bin

The command -

find . -type f -print0 | xargs -0 file | grep text | grep -v long | cut -d: -f1

produces the correct list of files (i.e. text files that do not contain very long lines)

./file with spaces.txt
./ordinaryfile.txt

But when I add another xargs to the end of the command I get errors -

find . -type f -print0 | xargs -0 file | grep text | grep -v long | cut -d: -f1 | xargs -0 awk -f someprocessing.awk

gawk: someprocessing.awk:3: fatal: cannot open file `./file' for reading (No such file or directory)

The content of someprocessing.awk is not relevant as I get the same error if I use the cat command instead.

How do I get the command after the last pipe to work with files with spaces in their names?

2 Answers 2

2

find -print0 produces output with null characters as delimiters. xargs -0 requires input with null characters as delimiters. Your first xargs command gets its null characters from find; the second one sees newline characters instead.

Try this:

find . -type f -print0 | \
    xargs -0 file | \
    grep text | \
    grep -v long | \
    cut -d: -f1 | \
    tr '\n' '\0' | \
    xargs -0 awk -f someprocessing.awk

(This should work for the GNU Coreutils version of tr; I'm not certain about other tr implementations.)

0
0

The solution accepted will screw up if the file name contains ':'. The following will only fail if the file names contain ': ' and avoids the \0 manipulation:

find . -type f | parallel file | grep text | grep -v long |\
parallel --colsep ': ' awk -f someprocessing.awk {1}

It uses GNU Parallel so you get the awk done in parallel for free.

Watch the intro videos to learn more: http://www.youtube.com/watch?v=OpaiGYxkSuQ

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .