Could somebody please provide the code to do the following:
Assume there is a directory of files, all of which need to be run through a program. The program outputs the results to standard out. I need a script that will go into a directory, execute the command on each file, and concat the output into one big output file.
For instance, to run the command on 1 file:
$ cmd [option] [filename] > results.out
The following bash code will pass $file to command where $file will represent every file in /dir
for file in /dir/*
do
cmd [option] "$file" >> results.out
done
Example
el@defiant ~/foo $ touch foo.txt bar.txt baz.txt
el@defiant ~/foo $ for i in *.txt; do echo "hello $i"; done
hello bar.txt
hello baz.txt
hello foo.txt
How about this:
find /some/directory -maxdepth 1 -type f -exec cmd option {} \; > results.out
-maxdepth 1
argument prevents find from recursively descending into
any subdirectories. (If you want such nested directories to get processed, you can omit this.)
-type -f
specifies that only plain files will be processed.
-exec cmd option {}
tells it to run cmd
with the specified option
for each file found, with the filename substituted for {}
\;
denotes the end of the command.
- Finally, the output from all the individual
cmd
executions is redirected to
results.out
However, if you care about the order in which the files are processed, you
might be better off writing a loop. I think find
processes the files
in inode order (though I could be wrong about that), which may not be what
you want.
I'm doing this on my raspberry pi from the command line by running:
for i in *;do omxplayer "$i";done
I needed to copy all .md files from one directory into another, so here is what I did.
for i in **/*.md;do mkdir -p ../docs/"$i" && rm -r ../docs/"$i" && cp "$i" "../docs/$i" && echo "$i -> ../docs/$i"; done
Which is pretty hard to read, so lets break it down.
first cd into the directory with your files,
for i in **/*.md;
for each file in your pattern
mkdir -p ../docs/"$i"
make that directory in a docs folder outside of folder containing your files. Which creates an extra folder with the same name as that file.
rm -r ../docs/"$i"
remove the extra folder that is created as a result of mkdir -p
cp "$i" "../docs/$i"
Copy the actual file
echo "$i -> ../docs/$i"
Echo what you did
; done
Live happily ever after
Based on @Jim Lewis's approach:
Here is a quick solution using find
and also sorting files by their modification date:
$ find directory/ -maxdepth 1 -type f -print0 | \
xargs -r0 stat -c "%y %n" | \
sort | cut -d' ' -f4- | \
xargs -d "\n" -I{} cmd -op1 {}
For sorting see:
http://www.commandlinefu.com/commands/view/5720/find-files-and-list-them-sorted-by-modification-time
One quick and dirty way which gets the job done sometimes is:
find directory/ | xargs Command
For example to find number of lines in all files in the current directory, you can do:
find . | xargs wc -l