我对这个实验(在 Bash 中)感到困惑:
$ mkdir 'foo\n'
$ find . -print0 | od -c
0000000 . \0 . / f o o \ n \0
0000012
正如您所看到的,“find”正确地使用空字符分隔输出,但它使用反斜杠“n”将目录名称中的换行符转义为“foo\n”。它为什么要这样做?我告诉它“-print0”,它表示“这允许包含换行符的文件名......由处理查找输出的程序正确解释。”转义应该不是必需的,因为“\0”是分隔符,而不是“\n”。
答案1
问题不在于find
,而在于您如何创建此目录。单引号字符串'foo\n'
实际上是一个5个字符的字符串,其中最后两个是反斜杠和小写“n”。
双引号也没有帮助,因为 shell 中的双引号字符串使用反斜杠作为转义字符,但并不真正解释任何 C 风格的反斜杠序列。
在 bash 或 zsh 等 shell 中(但不是 Debian/Ubuntu 中的 dash),您可以使用$'...'
,它解释这些序列:
$ mkdir $'foo\n'
(参见 bash 的文档此功能称为“ANSI C 引用”)。
另一个选项,应该在任何与 bourne shell 兼容的 shell 中工作,是插入一个实际的新队:
$ mkdir 'foo
'
Return这是第一行末尾的实际值,仅在第二行结束单引号。
答案2
让我们创建一个名为foo
加上换行符的目录:
$ mkdir $'foo\n'
现在,让我们使用查找:
$ find . -print0 | od -c
0000000 . \0 . / f o o \n \0
0000011
\n
没有逃脱。
问题是该mkdir 'foo\n'
名称被解释foo
为\
后跟n
。我们可以通过以下方式验证:
$ printf '%s' 'foo\n' | od -c
0000000 f o o \ n
0000005