I\'m trying to write a bash script that will process a list of files whose names are stored one per line in an input file, something the likes of
find . -type f
You could use the -exec
parameter of find
and use the file names directly:
find . -type f -mtime +15 -exec <your command here> {} \;
The {}
is a placeholder for the file name.
You can do this without a temporary file using process substitution:
while read F
do
...
done < <(find . -type f -mtime +15)
I believe you can skip the temporary file entirely and just directly iterate over the results of find, i.e.:
for F in $(find . -type f -mtime +15) ; do
...
done;
No guarantees that my syntax is correct but I'm pretty sure the concept works.
Edit: If you really do have to process the file with a list of filenames and can't simply combine the commands as I did above, then you can change the value of the IFS
variable--it stands for Internal Field Separator--to change how bash determines fields. By default it is set to whitespace, so a newline, space, or tab will begin a new field. If you set it to contain only a newline, then you can iterate over the file just as you did before.
Use read
:
while read F ; do
echo $F
done </tmp/filelist.txt
Alternatively use IFS to change how the shell separates your list:
OLDIFS=$IFS
IFS="
"
for F in $(cat /tmp/filelist.txt) ; do
echo $F
done
IFS=$OLDIFS
Alternatively (as suggested by @tangens), convert the body of your loop into a separate script, then use find
's -exec option to run if for each file found directly.
I'm not a bash expert by any means ( I usually write my script in ruby or python to be cross-platform), but I would use a regex expration to escape spaces in each line before you process it.
For Bash Regex: http://www.linuxjournal.com/node/1006996
In a similar situation in Ruby ( processing a csv file, and cleaning up each line before using it):
File.foreach(csv_file_name) do |line|
clean_line = line.gsub(/( )/, '\ ')
#this finds the space in your file name and escapes it
#do more stuff here
end
use while read
echo $FILE | while read line
do
echo $line
done
You can do redirect instead of echo