Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.

share|improve this question
up vote 3 down vote accepted

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
share|improve this answer
    
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 '12 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 '12 at 14:32
    
Thank you - it helps a lot. – szamasz Mar 9 '12 at 8:11

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.

share|improve this answer
    
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 '12 at 13:58
    
Nope, I haven't got a clue what happened to it. – Magnus Mar 11 '12 at 21:11

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
share|improve this answer

You must log in to answer this question.

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