0

Based on the top answer in Running multiple commands with xargs I'm trying to use find / xargs to work upon more files. Why the first file 1.txt is missing in for loop?

$ ls
1.txt  2.txt  3.txt

$ find . -name "*.txt" -print0 | xargs -0
./1.txt ./2.txt ./3.txt

$ find . -name "*.txt" -print0 | xargs -0 sh -c 'for arg do echo "$arg"; done'
./2.txt
./3.txt

3 Answers3

0

Why do you insist on using xargs? You can do the following as well.

while read -r file; do
    echo $file
done <<<$(find . -name "*.txt")

Because this is executed in the same shell, changing variables is possible in the loop. Otherwise you'll get a sub-shell in which that doesn't work.

Bayou
  • 3,293
  • 1
  • 9
  • 22
  • 2
    When a filename has a newline in it, The filename is cut in two parts. That might have been the reason for `print0`. – Walter A May 15 '20 at 22:17
0

When you use your for-loop in a script example.sh, the call example.sh var1 var2 var3 will put var1 in the first argument, not example.sh.
When you want to process one file for each command, use the xargs option -L:

find . -name "*.txt" -print0 | xargs -0 -L1 sh -c 'echo "$0"'
# or for a simple case
find . -name "*.txt" -print0 | xargs -0 -L1 echo
Walter A
  • 19,067
  • 2
  • 23
  • 43
0

I ran across this while having the same issue. You need the extra _ at the end as place holder 0 for xargs

$ find . -name "*.txt" -print0 | xargs -0 sh -c 'for arg do echo "$arg"; done' _
Tomsim
  • 369
  • 3
  • 7