2

This question already has an answer here:

None of answers that I've seen works for me, I have code like this

OLDVER=`readlink current`
OLDDATA=`find ! -newer $OLDVER

And I want to get only third match from FIND statement, because I need this name file to my script.

marked as duplicate by DopeGhoti, Stephen Rauch, G-Man, Jeff Schaller, αғsнιη Nov 9 '17 at 3:18

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

1

If you know that your file names don't contain any newline characters then the following commands will work:

Extract the 3rd result of find using head and tail:

find <PATH> <EXPRESSION> | head -n 3 | tail -n 1

Extract the 3rd result of find using sed:

find <PATH> <EXPRESSION> | sed '3q;d'

Extract the 3rd result of find using awk:

find <PATH> <EXPRESSION> | awk 'NR==3{print;exit}'

Here is what it might look like using the commands in your post:

find ! -newer "$(readlink current)" | sed '3q;d'

If you want to handle files whose names might contain newlines then you could use the -print0 option and loop over the results, e.g. something like the following:

find . -print0 | (\
    IFS=$'\0' \
    n=0; \
    while read -r -d '' line; do \
        ((n++)); if [[ $n -eq 3 ]]; then \
        echo "${line}"; \
        break; \
    fi; \
done)

To check that this works, you could performing something like the following experiment:

mkdir /tmp/test

cd /tmp/test

touch $'file1 line1\012file1 line2'

touch $'file2 line1\012file2 line2'

touch $'file3 line1\012file3 line2'

find . -print0 | (\
    n=0; \
    while read -r -d '' line; do \
        ((n++)); if [[ $n -eq 3 ]]; then \
        echo "${line}"; \
        break; \
    fi; \
done)

This produces the following output (as expected):

./file3 line1
file3 line2

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