It looks like ‘find’, ‘bash’ and ‘sed’ in some cases does not work as one expects.
The following example should first create file ‘sample.txt’, then find the file and finally process it by ‘-exec’ command. The executed command prints found filename, test specimens, and modified filename. The ‘sed’ command itself is used to replace ‘txt’ to ‘TXT’.
touch sample.txt
find ./ -maxdepth 1 -name "*.txt" -exec echo {} $(echo Specimen_before.txt {} Specimen_after.txt |sed -e "s/txt/TXT/g") ;
The expected output is:
./sample.txt Specimen_before.TXT ./sample.TXT Specimen_after.TXT
Instead it produces:
./sample.txt Specimen_before.TXT ./sample.txt Specimen_after.TXT
(the example has been tested also with old-school command substitution through backquotes ‘`’ with the same result)
What am I doing wrong?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
The command substitution is executed before find even starts. The actual command executed (after substitutions, expansions and quote removals etc.) is
find ./ -maxdepth 1 -name *.txt -exec echo {} Specimen_before.TXT {} Specimen_after.TXT ;
If you need to run anything fancy (pipes or multiple commands) with -exec, then start a separate shell to do it:
find . -maxdepth 1 -type f -name '*.txt'
-exec sh -c 'printf "%s " "$1"; printf "%s %s %sn" "before.txt" "$1" "after.txt" | sed "s/txt/TXT/g"' sh {} ';'
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0