我使用“find -print0”有什么问题?

Met*_*hic 7 find filenames

我对这个实验(在 Bash 中)感到困惑:

$ mkdir 'foo\n'
$ find . -print0 | od -c
0000000   .  \0   .   /   f   o   o   \   n  \0
0000012
Run Code Online (Sandbox Code Playgroud)

如您所见,“find”正确地用空字符分隔输出,但它将目录名称中的换行符转义为“foo\n”,并带有反斜杠“n”。为什么要这样做?我告诉它“-print0”,它说“这允许包含换行符的文件名......被处理查找输出的程序正确解释。” 转义应该是不必要的,因为“\0”是分隔符,而不是“\n”。

fil*_*den 20

问题不在于find,而在于您如何创建此目录。单引号字符串'foo\n'实际上是一个 5 个字符的字符串,其中最后两个是一个反斜杠和一个小写的“n”。

双引号也无济于事,因为 shell 中的双引号字符串使用反斜杠作为转义字符,但并没有真正解释任何 C 风格的反斜杠序列。

在 bash 或 zsh 等 shell 中(但不是来自 Debian/Ubuntu 的破折号),您可以使用$'...',它会解释这些序列:

$ mkdir $'foo\n'
Run Code Online (Sandbox Code Playgroud)

(有关此功能,请参阅 bash 的文档,称为“ANSI C Quoting”)。

另一个选项,应该在与 bourne shell 兼容的任何 shell 中工作是插入一个实际的换行符:

$ mkdir 'foo
'
Run Code Online (Sandbox Code Playgroud)

这是Return第一行末尾的实际值,仅关闭第二行的单引号。


Joh*_*024 6

让我们创建一个名为foo加换行符的目录:

$ mkdir $'foo\n'
Run Code Online (Sandbox Code Playgroud)

现在,让我们使用查找:

$ find .  -print0 | od -c
0000000   .  \0   .   /   f   o   o  \n  \0
0000011
Run Code Online (Sandbox Code Playgroud)

\n 没有逃脱。

问题在于mkdir 'foo\n'名称被解释为foo后跟\后跟n。我们可以通过以下方式验证:

$ printf '%s' 'foo\n' | od -c
0000000   f   o   o   \   n
0000005
Run Code Online (Sandbox Code Playgroud)