recursive - bash find-exec example

find-exec with multiple commands (7)

1st answer of Denis is the answer to resolve the trouble. But in fact it is no more a find with several commands in only one exec like the title suggest. To answer the one exec with several commands thing we will have to look for something else to resolv. Here is a example:

Keep last 10000 lines of .log files which has been modified in the last 7 days using 1 exec command using severals {} references

1) see what the command will do on which files:

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "echo tail -10000 {} \> fictmp; echo cat fictmp \> {} " \;

2) Do it: (note no more "\>" but only ">" this is wanted)

find / -name "*.log" -a -type f -a -mtime -7 -exec sh -c "tail -10000 {} > fictmp; cat fictmp > {} ; rm fictmp" \;

I am trying to use find -exec with multiple commands without any success. Does anybody know if commands such as the following are possible?

find *.txt -exec echo "$(tail -1 '{}'),$(ls '{}')" \;

Basically, I am trying to print the last line of each txt file in the current directory and print at the end of the line, a comma followed by the filename.

find accepts multiple -exec portions to the command. For example:

find . -name "*.txt" -exec echo {} \; -exec grep banana {} \;

Note that in this case the second command will only run if the first one returns successfully, as mentioned by @Caleb. If you want both commands to run regardless of their success or failure, you could use this construct:

find . -name "*.txt" \( -exec echo {} \; -o -exec true \; \) -exec grep banana {} \;

I don't know if you can do this with find, but an alternate solution would be to create a shell script and to run this with find.

echo $(tail -1 $1),$1

Make the script executable

chmod +x

Use find:

find . -name "*.txt" -exec ./ {} \;

One of the following:

find *.txt -exec awk 'END {print $0 "," FILENAME}' {} \;

find *.txt -exec sh -c 'echo "$(tail -n 1 "$1"),$1"' _ {} \;

find *.txt -exec sh -c 'echo "$(sed -n "\$p" "$1"),$1"' _ {} \;

There's an easier way:

find ... | while read -r file; do
    echo "look at my $file, my $file is amazing";


while read -r file; do
    echo "look at my $file, my $file is amazing";
done <<< "$(find ...)"

should use xargs :)

find *.txt -type f -exec tail -1 {} \; | xargs -ICONSTANT echo $(pwd),CONSTANT

another one (working on osx)

find *.txt -type f -exec echo ,$(PWD) {} + -exec tail -1 {} + | tr ' ' '/'

find . -type d -exec sh -c "echo -n {}; echo -n ' x '; echo {}" \;