A reader writes:
“I figured that this would be right up your alley. If I want to move any document that contains “agreen” to another folder, what commands would I use on the command line?”
Hmmm…. let’s see…
find . -print | xargs grep -il "agreen"
would produce a list of all files from the current point in the file system “down” (e.g., within this subdirectory), so wrap that in a for loop and you have something like:
target="~/newdir"for name in $(find . -print | xargs grep -il "agreen")
do
echo moving file $name to $target
mv $name $target
done
You’ll want to make sure that ‘newdir’ exists first, or the ‘mv’ will successively step on and remove all of your files. Maybe a safer snippet would be:
target="~/newdir"if [ ! -d $target ] ; then
echo "Failed: target directory $target not found." 2>1
exit 1
fifor name in $(find . -print | xargs grep -il "agreen")
do
echo moving file $name to $target
mv $name $target
done
There! That should do the trick.
-print????
Why? It’s pointless. Banish it from your mind.
How about this? It works fine for reasonable values of x:
for x in `find . -exec grep -l agreen {} \;`
> do
> mv -i $x /tmp/agreen.files/
> done
Commentary:
I leave off the -i option to grep as that wasn’t asked for (I’m such a pedant!).
I add a -i option to mv because if there are 5 different files found that all have the same name, you may not want to end up with just the last one.
Notice my use of a trailing / on the directory name. If the directory doesn’t exist, you just get error(s). Example:
# mv .CFUserTextEncoding nonexistantdirectory/
mv: rename .CFUserTextEncoding to nonexistantdirectory/: No such file or directory
To explain the form I am using, putting commands in back ticks makes the shell evaluate that command first and put its output in the command’s place. This also means it finds all the filenames THEN acts on them, preventing the situation where the file is found again after being moved.