如何删除awk过滤掉的文件

如何删除awk过滤掉的文件

我在目录中有以下文件:

-rw-r--r-- 1 smsc sys  46 Apr 22 12:09 bills.50.1.3G.MO.X.20120422120453.Z
-rw-r--r-- 1 smsc sys  28 Apr 22 12:15 bills.50.1.3G.MO.X.20120422120953.Z
-rw-r--r-- 1 smsc sys  46 Apr 22 12:20 bills.50.1.3G.MO.X.20120422121453.Z
-rw-r--r-- 1 smsc sys  46 Apr 22 12:25 bills.50.1.3G.MO.X.20120422121953.Z

其中第五列是文件的大小。我希望删除所有大小为 46 的文件。为了过滤掉这些文件,我使用了以下命令:

ls -ltr | awk '$5 ~ /46/ {print $0}'

效果很好。但现在我想删除所有被过滤掉的文件,所以我在上面的命令中添加以下内容:

ls -ltr | awk '$5 ~ /46/ {print $0}' | xargs rm

但是它给了我以下错误:

rm: invalid option -- w

看来我必须使用findoverls所以我会得到以下格式的输出:

./bills.50.1.3G.MO.X.20120421050453.Z
./bills.50.1.3G.MO.X.20120421154953.Z
./bills.50.1.3G.MO.X.20120419133452.Z

但是我无法通过文件的参数来过滤文件。这个任务怎么能完成呢?

答案1

你有两个错误:

  1. 您正在比较的尺寸是包含 46;你希望它是等于46.

  2. 当您只需要文件名时,您正在打印整行。

还有一个额外的问题:当您不使用排序顺序时,对输出-ltr进行排序有什么意义?ls

你想做类似的事情

ls -l | awk '$5 == "46" {print $9}' | xargs rm

除了你想要这样做,因为虽然目前可能是安全的,但解析ls输出是不可靠的。使用适当的工具,例如

find . -maxdepth 1 -size 46c -delete # requires GNU find

(可移植地执行此操作更烦人,因为 POSIXfind没有-maxdepth-size以块以外的单位运行。最好在 Perl/Python/Ruby/等中编写一个脚本,该脚本可以使用适当的目录扫描,而不会得到文件名中的特殊字符有问题。)

答案2

在 zsh 中,要删除当前目录(第一行)或当前目录及其子目录(第二行)中所有大小为 26 的文件,请使用L 全局限定符:

rm *(L26)
rm **/*(L26)

使用 GNU 或 FreeBSD/NetBSD/OSX 查找:

find . -name . -o -type d -prune -o -type f -size 26c -exec rm {} +
find . -type f -size 26c -exec rm {} +

便携:

find . -name . -o -type d -prune -o -type f -exec sh -c '[ $(wc -c <"$0") -eq 26 ] && rm -- "$0"' {} \;
find . -type f -exec sh -c '[ $(wc -c <"$0") -eq 26 ] && rm -- "$0"' {} \;

答案3

find是这里最好的选择。您可以使用stat查找文件大小而不使用ls

for file in *; do
  (( $(stat -c %s "$file") == 46 )) && rm "$file"
done

相关内容