8bitme
8bitme

Reputation: 947

Unix Find Passing Filename to Exec and In Output Redirect

I want to base64 encode a directory of images removing newlines in the base64 output. I then save this as <imageName>.base64.txt.

I can do this using the following for loop:

  for file in $(find path/to/images -name "*.png"); do
    base64 "$file" | tr -d "\n" > "$file".base64.txt
  done

How would I do this with find using xargs or -exec?

Upvotes: 2

Views: 574

Answers (1)

Inian
Inian

Reputation: 85580

This is very closely a dupe of How do I include a pipe | in my linux find -exec command?, but does not cover the case you are dealing with.

To get the filename, you can run a -exec sh -c loop

find path/to/images -name "*.png" -exec sh -c '
     for file; do 
         base64 "$file" | tr -d "\n" > "${file}.base64.txt" 
     done' _ {} +

Using find -exec with + puts all the search results from find in one shot to the little script inside sh -c '..'. The _ means invoke an explicit shell to run the script defined inside '..' with the filename list collected as arguments.

An alternate version using xargs which is equally expensive as the above loop would be to do below. But this version separates filenames with NUL character -print0 and xargs reads it back delimiting on the same character, both GNU specific flags

find path/to/images -name "*.png" -print0 |
    xargs -0 -I {} sh -c 'base64 {} | tr -d "\n" > {}.base64.txt'

Upvotes: 2

Related Questions