Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirecting stdout with find -exec and without creating new shell

Tags:

I have one script that only writes data to stdout. I need to run it for multiple files and generate a different output file for each input file and I was wondering how to use find -exec for that. So I basically tried several variants of this (I replaced the script by cat just for testability purposes):

find * -type f -exec cat "{}" > "{}.stdout" \; 

but could not make it work since all the data was being written to a file literally named{}.stdout.

Eventually, I could make it work with :

find * -type f -exec sh -c "cat {} > {}.stdout" \; 

But while this latest form works well with cat, my script requires environment variables loaded through several initialization scripts, thus I end up with:

find * -type f -exec sh -c "initscript1; initscript2; ...;  myscript {} > {}.stdout" \; 

Which seems a waste because I have everything already initialized in my current shell.

Is there a better way of doing this with find? Other one-liners are welcome.

like image 627
jserras Avatar asked Feb 22 '13 18:02

jserras


2 Answers

You can do it with eval. It may be ugly, but so is having to make a shell script for this. Plus, it's all on one line. For example

find -type f -exec bash -c "eval md5sum {}  > {}.sum " \; 
like image 83
Phillip Jones Avatar answered Oct 02 '22 00:10

Phillip Jones


A simple solution would be to put a wrapper around your script:

#!/bin/sh  myscript "$1" > "$1.stdout" 

Call it myscript2 and invoke it with find:

find . -type f -exec myscript2 {} \; 

Note that although most implementations of find allow you to do what you have done, technically the behavior of find is unspecified if you use {} more than once in the argument list of -exec.

like image 26
William Pursell Avatar answered Oct 01 '22 22:10

William Pursell