如何将所有文件从管道移动到目录中?

如何将所有文件从管道移动到目录中?

我对桌面目录中的所有元素执行了文件命令:

~/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/TYPExargs

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 版本并非如此。

相关内容