I want to iterate over a list of files. This list is the result of a find
command, so I came up with:
getlist() {
for f in $(find . -iname \"f
In some cases, here if you just need to copy or move a list of files, you could pipe that list to awk as well.
Important the \"" "\"
around the field $0
(in short your files, one line-list = one file).
find . -iname "foo*" | awk '{print "mv \""$0"\" ./MyDir2" | "sh" }'
I really like for loops and array iteration, so I figure I will add this answer to the mix...
I also liked marchelbling's stupid file example. :)
$ mkdir test
$ cd test
$ touch "stupid file1"
$ touch "stupid file2"
$ touch "stupid file 3"
Inside the test directory:
readarray -t arr <<< "`ls -A1`"
This adds each file listing line into a bash array named arr
with any trailing newline removed.
Let's say we want to give these files better names...
for i in ${!arr[@]}
do
newname=`echo "${arr[$i]}" | sed 's/stupid/smarter/; s/ */_/g'`;
mv "${arr[$i]}" "$newname"
done
${!arr[@]} expands to 0 1 2 so "${arr[$i]}" is the ith element of the array. The quotes around the variables are important to preserve the spaces.
The result is three renamed files:
$ ls -1
smarter_file1
smarter_file2
smarter_file_3
You could replace the word-based iteration with a line-based one:
find . -iname "foo*" | while read f
do
# ... loop body
done
find . -name "fo*" -print0 | xargs -0 ls -l
See man xargs
.
find
has an -exec
argument that loops over the find results and executes an arbitrary command. For example:
find . -iname "foo*" -exec echo "File found: {}" \;
Here {}
represents the found files, and wrapping it in ""
allows for the resultant shell command to deal with spaces in the file name.
In many cases you can replace that last \;
(which starts a new command) with a \+
, which will put multiple files in the one command (not necessarily all of them at once though, see man find
for more details).