0
touch 1.txt 2.txt
find . -name "[12].txt" -exec sh -c 'echo "${1}"' sh {} + -exec echo {} +
./2.txt
./2.txt ./1.txt

Why echo within sh -c outputs only one file? Today I thought I understood how find works from Understanding the -exec option of `find` but now puzzled again. Got same result for -exec bash. TIA

Alex Martian
  • 1,035

1 Answers1

3

With:

-exec sh -c 'echo "${1}"' sh {} +

find passes as many as possible of the files that it found to sh, and you're asking sh to pass the first one (${1} or $1 for short) to echo. To pass all of them, use "$@" instead:

-exec sh -c 'echo "$@"' sh {} +

Or for sh to call echo once for each of them, use a loop over the positional parameter (positional parameters are what for loops loop over by default):

-exec sh -c 'for file do
               echo "$file"
             done' sh {} +
  • Thanks. Seems I've read not too attentively. Now I face another issue with find {} +: find . -name "[12].txt" -exec cmp {} + -exec sh -c 'if [ "${1}" < "${2}" ] ; then echo "${1}" ; fi' sh {} + even as cmp outputs "files differ" next exec with echo runs. Why? How testing with exec works? P.S. I know it might be another Q. If not answered as comment, I plan to post it. – Alex Martian Jul 27 '23 at 17:14
  • 1
    @AlexMartian https://www.gnu.org/software/findutils/manual/html_mono/find.html#Multiple-Files : "Action: -exec command {} + .... The result is always true." – muru Jul 27 '23 at 18:14
  • Thanks. My bad, trying to grasp new code when tired. In the example {} + was used only at the end, check was done with {} ;. – Alex Martian Jul 28 '23 at 01:08