5

I'd like to limit output of find command. In the past I used to use for this ls command, e.g:

ls *tgz|head -100|xargs -i mv "{}" ../

but I got to know that the result may be unpredictable if name of file contains new line character. So more correct way to do this is something like that:

find ... -print0 | xargs -0

But taking this approach I'm not able to limit output of find with head command - it shows all file names separated with ^@ special sign:

 find . -name '*tgz' -print0|head -2|less

file1.tgz^@file2.tgz^@file3.tgz^@file4.tgz^@file5.tgz^@

Is there a method to work this awkwardness away?

I tried to resolve it with help of awk:

find . -name 'BATCHED*' -print0|awk 'BEGIN{RS=""}'

but it still displays either all or zero lines.

May it be solved with help of awk? Is there better solution?

BTW. I found this very instructive reference but there is not answer on my question.

3 Answers 3

3

Another opportunity for safe find:

while IFS= read -r -d '' -u 9
do
    let ++count
    if [[ count -gt 10 ]]
    then
        unset count
        break
    fi
    printf "$REPLY"
    printf "$\x00"
done 9< <( find /full/path -print0 )

To verify, simply pipe it into this:

while IFS= read -r -d ''
do
    echo "START${REPLY}END"
done
2
  • Thank you very much for this post. It works fine. There is one thing I don't understand: what does done 9< <( find /full/path -print0 ) mean in this context? I'm used to application of done < "Filename" pattern, but I don't know this one. Thank you in advance.
    – szamasz
    Mar 7, 2012 at 13:57
  • 1
    It's using file descriptor number 9 instead of stdin. That way you can use stdin in the loop (cat/ssh) without worrying about your loop terminating after the first file because the whole stream was swallowed.
    – l0b0
    Mar 7, 2012 at 14:32
2

The problem stems from xargs being word-orientated, while commands like head and tail are line-orientated. One solution could be to not use xargs but instead GNU parallel.

2
  • Thank you for your comment. I have never heard about GNU parallel before. BTW - once I checked this webpage I saw one more answer - do you know maybe what happened to it?
    – szamasz
    Mar 7, 2012 at 13:58
  • Nope, I haven't got a clue what happened to it.
    – Magnus
    Mar 11, 2012 at 21:11
0

I believe you're looking for the --max-args or --max-lines argument to xargs, depending on your input format:

# Run less on no more than two files at a time
find . -type f -print0 | xargs --null --max-args=2 less

You must log in to answer this question.

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