If I understand correctly, you want to move files from the current directory and its subdirectories recursively to another directory, but only if the file
command reports them as “Microsoft Word” files. That is, you're interested in the files for which file "$filename" | grep 'Microsoft Word'
produces some output.
An easy way is to take things calmly and to it file by file. If you only want the files in the current directory, you can use a for
loop and a wildcard pattern:
for f in *.doc; do if … done
What's the condition? We want to test if Microsoft Word
appears in the output of file "$f"
. I use file --
to protect against files whose name begins with -
.
for f in *.doc; do if file -- "$f" | grep -s 'Microsoft Word'; then … fi done
All we need to do is add the command to move the files.
for f in *.doc; do if file -- "$f" | grep -s 'Microsoft Word'; then mv -- "$f" ../NewDirectory/ fi done
If you want to look for files in subdirectories as well, use the **
wilcdard pattern for recursive globbing. In bash, it needs to be activated with shopt -s globstar
(in ksh93, you need set -o globstar
, and in zsh it works out of the box; other shells lack this feature). Beware that bash ≤4.2 follows symbolic links to directories.
for f in **/*.doc; do if file -- "$f" | grep -s 'Microsoft Word'; then mv -- "$f" ../NewDirectory/ fi done
Note that all moved files end in ../NewDirectory/
, no subdirectories are created. If you want to reproduce the directory tree, you can use string manipulation constructs to extract the directory part of the file name and mkdir -p
to create the target directory if necessary.
for f in ./**/*.doc; do if file "$f" | grep -s 'Microsoft Word'; then d="${f%/*}" mkdir -p ../NewDirectory/"$d" mv "$f" ../NewDirectory/"$d" fi done
Rather than parse the output of file
, which is somewhat fragile, you might prefer to parse file -i
, which prints standardized strings.
file
command on any files that have a .doc extension?