如何递归列出全部内容恰好为“\n”的所有文件

如何递归列出全部内容恰好为“\n”的所有文件

我有一些失败的实验结果文件,它们的内容恰好是一个\n(换行符)。

我想将它们全部列出(也许使用类似find或 之类的东西grep),以了解这些文件是什么,然后删除它们。

答案1

在搜索路径之外创建一个参考文件(它将.在示例中):

echo >/tmp/reference

现在我们有一个与您要查找的文件相同的已知文件。然后将搜索路径(.此处)下的所有常规文件与参考文件进行比较:

find . -type f -size 1c -exec cmp -s -- /tmp/reference {} \; -print

-size 1c不是必须的,可以省略;只是为了提高性能。这是一个快速的初步测试,可以拒绝大小错误的文件,而不会产生额外的进程。cmp …仅针对大小合适的文件创建相对昂贵的进程。

-scmp自己沉默。我们不需要它的输出,只需要退出状态。

--解释如下:“--”(双破折号)是什么意思?在我们的示例中确实不需要它,即如果参考文件指定为/tmp/reference并且搜索路径为..我用于防止有人不小心选择了否则会导致行为不当或失败的--路径;cmp有了--它应该就可以了。

-exec用作测试,当且仅当cmp返回退出状态为零时,它才会成功;对于经过测试的文件,如果该文件与/tmp/reference.这样,find将为您提供与参考文件相同的文件的路径名。

该方法可用于查找任意固定内容的文件;您只需要一个包含确切内容的参考文件(-size …如果您使用它,请不要忘记进行调整;-size "$(</tmp/reference wc -c)c"会很方便)。在我们的特定情况下,echo使用一个简单的方法来创建文件,因为它打印一个换行符,这正是您想要查找的内容。

find尝试删除每个匹配的文件,请使用-delete(异-exec rm -- {} +或)-print

答案2

搜索单字节文件。将它们与已知值进行比较。如果匹配则打印和/或删除

find /path/to/files -type f -size 1c -exec sh -c 'printf "\n" | cmp -s -- - "$1"' _  {} \; -print

如果您想要静默运行,可以选择附加-delete到删除,然后删除。-print

答案3

使用 GNU grep,您可以-z将整个文件视为单行(-z使用grepNUL 作为行终止符,因此只要您的文件实际上不包含 NUL,\0它就具有将整个文件视为单个行的效果线)。如果我们将其与-l仅打印文件名并-P供 PCRE 使用\n,我们可以搜索只有一个\n而没有其他内容的“行”:

grep -lPz '^\n$' *

例如,给定这三个文件:

printf 'foo\n' > good_file_1
printf '\n\n\n\n' > good_file_2
printf '\n' > bad_file

运行grep上面给出:

$ grep -lPz '^\n$' *
bad_file

globstar您还可以使用 bash选项(来自 man )使其递归bash

环球星

如果设置,路径名扩展上下文中使用的模式 ** 将匹配所有文件以及零个或多个目录和子目录。如果模式后跟 /,则仅目录和子目录匹配。

例如,在这种情况下:

$ mkdir -p ./some/long/path/here/
$ cp bad_file some/long/path/here/bad_file_2
$ tree
.
├── bad_file
├── good_file_1
├── good_file_2
└── some
    └── long
        └── path
            └── here
                └── bad_file_2

5 directories, 4 files

启用globstar并运行grep**/*发现两个坏文件(我正在重定向标准错误,因为 grep 抱怨给出的目录而不是文件进行搜索;此类错误是预期的并且可以安全地忽略):

$ grep -lPz '^\n$' **/* 2>/dev/null 
bad_file
some/long/path/here/bad_file_2

或者,find仅用于搜索文件:

$ find . -type f -exec grep -lPz '^\n$' {} +
./some/long/path/here/bad_file_2
./bad_file

答案4

find . -size 1c -exec sh -c '[ -z "$(< $1)" ]' sh '{}' ';' -print

查找大小恰好为一个字节的文件,其中(在 shell 中)读取文件的结果为空—— sh 从命令替换中删除尾随换行符。

相关内容