我正在尝试使用“文件”的结果,它返回有关我指定的文件的信息。
例如
file *.doc 'all .doc extensions
然后返回有关文件的信息,包括“创建应用程序的名称:Microsoft Word”。现在,我尝试在结果中搜索字符串“Word”。我被困在这里了。我实际上该如何做到这一点?
*这是我经过几个小时的搜索后尝试的。我只是不知道我要找什么词。请指教。
find . -type f -print0 | xargs -0 grep -lh "Microsoft Word" | xargs -I % mv % ../NewDirectory/
我认为这会在文件本身中搜索字符串“Word”并将其移动到新目录。
答案1
如果我理解正确的话,您希望将文件从当前目录及其子目录递归移动到另一个目录,但前提是该file
命令将它们报告为“Microsoft Word”文件。也就是说,您对file "$filename" | grep 'Microsoft Word'
产生一些输出的文件感兴趣。
一个简单的方法是冷静地处理事情并逐一处理。如果您只需要当前目录中的文件,则可以使用for
循环和通配符模式:
for f in *.doc; do
if …
done
条件是什么?我们想要测试是否Microsoft Word
出现在 的输出中file "$f"
。我用来file --
防止名称以-
.
for f in *.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
…
fi
done
我们需要做的就是添加移动文件的命令。
for f in *.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
mv -- "$f" ../NewDirectory/
fi
done
如果您还想在子目录中查找文件,请使用**
通配模式用于递归通配符。在 bash 中,需要使用 来激活shopt -s globstar
(在 ksh93 中,您需要set -o globstar
,而在 zsh 中,它可以开箱即用;其他 shell 缺乏此功能)。请注意,bash ≤4.2 遵循目录的符号链接。
for f in **/*.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
mv -- "$f" ../NewDirectory/
fi
done
请注意,所有移动的文件均以 结尾../NewDirectory/
,不会创建任何子目录。如果你想重现目录树,你可以使用字符串操作结构提取文件名的目录部分并mkdir -p
根据需要创建目标目录。
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
您可能更喜欢解析输出标准化字符串,而不是file
解析有点脆弱的输出。file -i
答案2
由于不匹配的单引号,您的第一个file
示例将不起作用,但我认为您已经因为第二个示例而发现了这一点。
如果你这样做:
find . -type f
你可以看看输出。这些是文件名。如果您想从该输出中选择某些内容,请grep
直接使用
find . -type f | grep "Microsoft Word"
通过文件名进行搜索,而不是通过列出的文件的内容进行搜索。这并不完全准确,因为文件名中可能包含换行符,如果包含“Microsoft Word”的文件名包含换行符作为名称的一部分,则输出不完整。
如果你这样做:
find . -type f -print0 | xargs -0 grep -lh "Microsoft Word"
该xargs
部分实际上将文件名传递给 grep (-print0
forfind
和-0
forxargs
是处理带有换行符的文件名)。这会搜索整个字符串“Microsoft Word”而不仅仅是“Word”在文件中。
指定的-lh
forgrep
列出文件名,并且可能存在问题,因为文件名中的换行符会正常打印,因此您还应该通过指定 -Z 继续使用 NUL 终止的文件名。如果您不指定,-l
您也会得到行匹配的内容,这将使进一步处理(您的mv
)变得不可能。
如果您想将所有文件移到一个目录中,通常更容易使用, mv -t
而不是使用xargs
'-I
选项(它允许您xargs
将从其输入读取的参数放在与默认行尾不同的位置,但速度较慢)因为每个文件都会调用一次 mv ):
find . -type f -print0 | xargs -0 grep -lhZ "Microsoft Word" | xargs -0 mv -t ../NewDirectory/
这会将所有文件移动到当前目录下的某个位置,其中包含“Microsoft Word”内容到NewDirectory
当前目录旁边的 。请注意,它../NewDirectory
必须存在。