我对这个实验(在 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第一行末尾的实际值,仅关闭第二行的单引号。
让我们创建一个名为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)