我对桌面目录中的所有元素执行了文件命令:
~/Desktop > file *
然后我 grep 了描述中包含字符串“image”的所有行:
~/Desktop > file * | grep "image"
然后我只从每一行中删除文件名:
~/Desktop> file * | grep "image" | cut -d: -f1
从这一步开始,我不知道如何将所有获得的文件名移动到一个目录中,我尝试了 xargs,但我认为我对它的理解有误:
~/Desktop> file * | grep "image" | cut -d: -f1 | xargs mv {} ./dirk
答案1
查看--target-directory
选项mv
.
答案2
{}
xargs
除非您传递已弃用的-i
选项或使用 ,否则没有意义-I {}
。
file * | grep "image" | cut -d: -f1 | xargs -I {} mv {} ./dirk
仅当您的文件名不包含任何特殊字符(:\"'
或换行符或首字母-
; 空格使用xargs -I
)时,这才有效。这还包括images
即使不是图像也包含的文件名。这包括该file
命令描述为“图像”的文件,例如“磁盘映像”,而不仅仅是图片中的图像。
过滤内容为图片的文件的更可靠(但不是完美)的方法是使用file -i
并查找描述为.下面的代码片段还转换了引号字符,这些字符会混淆某些版本的¹。FILENAME: image/TYPE
xargs
file -i ./* |
sed -n -e 's/["'\''\\]/\\&/' -e 's/: *image\/[^:]*$//p' |
xargs -I {} mv {} ./dirk
使用最新版本的 GNU 实用程序(即非嵌入式 Linux 系统或 Cygwin),您可以使用空分隔列表来使处理可靠且稍微更快。
file -0i ./* |
sed -z -e 's/: *image\/[^:]*$//p' |
xargs -0 mv -t ./dirk
另一种方法是使用循环或迭代文件,即使file *
由于命令行长度限制而失败,该方法也能正常工作。find
for x in ./*; do
if [ -n "$(file -i "$x" | sed -n '$/: *image\/[^:]*$/ p')" ]; then
mv "$x" ./dirk
fi
done
1 POSIX 表示-I
禁用xargs
的引号处理,但自 findutils 4.4.2 起的 GNU 版本并非如此。