Grep识别目录中包含全零的文件并列出或删除它们

时间:2019-05-26 23:38:38

标签: grep

在一个目录中有许多损坏的图像文件,它们仅包含零个十六进制值(尽管有些非常大)-在其他没有损坏的图像中。要搜索目录,请确定仅包含零的文件并删除他们。

我正在从Mac上的终端运行它。

我正在考虑grep,递归,停止搜索并从文件中删除任何包含非零值的文件,并用rm删除零值文件。但是-我是新手,不知道如何将其组合在一起。

或者将零个文件移到我可以从中删除它们的目录中(请注意不要删除任何好的图像文件。)

2 个答案:

答案 0 :(得分:1)

要测试名为$fname的文件是否仅包含十六进制零,请尝试:

head -c "$(wc -c <"$fname")" /dev/zero | cmp -s - "$fname"

在这里,head -c "$(wc -c <"$fname")" /dev/zero创建一个与文件$fname一样长的零字节字符串。 cmp -s - "$fname"将十六进制零字符串与文件本身进行比较。如果它们匹配,则cmp将其退出代码设置为成功(0)。

要列出目录中仅包含十六进制零的所有常规文件:

for fname in ./*
do
   [ -f "$fname" ] && head -c "$(wc -c <"$fname")" /dev/zero | cmp -s - "$fname" && echo "$fname"
done

要删除仅包含十六进制零的目录中的所有常规文件,我们只需将echo替换为rm

for fname in ./*
do
   [ -f "$fname" ] && head -c "$(wc -c <"$fname")" /dev/zero | cmp -s - "$fname" && rm "$fname"
done

在这里,[ -f "$fname" ]测试文件是否为常规文件而不是目录。 head -c "$(wc -c <"$fname")" /dev/zero | cmp -s - "$fname"测试文件中是否只有十六进制零。如果cmp拒绝成功,则rm "$fname"删除该文件。

答案 1 :(得分:1)

findgawkxargs非常有效。

请在确认所需命令后取消echo安全。

#!/bin/bash
mapfile -t Files < <(find . -type f -not -empty)    #1
gawk '
  /[^\x00]/ {f=1; nextfile}                         #2
  ENDFILE {if(!f) print FILENAME; f=0}              #3
' "${Files[@]}" |xargs echo rm                      #4
  1. 将所有非空文件递归存储在数组“文件”的当前目录中
  2. 如果任何行与十六进制零以外的字符匹配,请设置标志并转到下一个文件
  3. nextfile或正常EOF之后,如果未设置标志,则打印文件名,然后打印未设置标志
  4. gawk提供我们的find结果,然后使用xargs构造一个rm命令。