shell 中有处理 NULL 字符的可移植方法吗?
一个典型的示例是将 with shell(并且仅 shell)的输出拆分find ... -print0
为管道或命令替换结果。我所说的便携式理想情况下是指炮弹不像例如那样强大bash
或zsh
不会被卡住的东西。这在“裸 POSIX shell”(任何 POSIX 版本)中可能吗?
答案1
POSIX 没有设想处理文本嵌入null
字符的标准实用程序。-print0
您使用的选项本身find
就是一个GNU
不受POSIX
.
null
使用 shell 脚本处理包含 s 的数据流的一种方法POSIX
是首先将其转换为真实文本od
并处理该文本。
无论如何,如果您有GNU find
,那么您可能还有其他GNU
实用程序,这些实用程序一开始就没有该限制。
答案2
Bash 可以使用read
's-d
选项来处理它,例如
find . -print0 | while read -r -d '' line; do
# something with $line
done
但不知道这是否是 POSIX。
答案3
后找到类似的问题,这是我在一段时间后想出的...不确定这在 POSIX shell 中是否可行。在 Cygwin 中尝试过这个。只是为了好玩,用空字符弥补了一个问题。
想象的问题如下:您有(一些)文件中包含空字符。您不确切知道这些文件是什么或它们位于何处。您的任务是删除所有此类可能文件的空字符。
下面,第一个命令将显示包含空字符的行,然后另一个命令将空字符转换为换行符(最后一个命令删除临时文件):
find . ! -type d -exec perl -ne '/\000/ and print;' {} \; > /tmp/null-lines
tr -s '\000' '\n' < /tmp/null-lines > with-null-lines.txt
rm /tmp/null-lines
之后,需要读取结果行的每一行并查找该行属于哪个文件。为此,我首先保存需要检查的所有文件,然后查看其中是否有匹配的行:
find . ! -type d -print > files.txt
while read line; do while read line2; do if grep -q "$line2" "$line"; then echo "$line" >> examination.txt; fi; done < with-null-lines.txt; done < files.txt
(重新运行循环之前,删除文件“examination.txt”)
现在,我们计算出现的次数,如果出现的次数超过 1,则很可能有多个空字符(当然,如果只有一个,查找起来就会变得更加困难)。
uniq -c examination.txt | grep -v "1"
它应该在那里列出(大多数)包含空字符的文件。忽略“with-null-lines.txt”这一行。此外,如果文件中存在相同的文本,那么您可能还会在其中看到一些无辜的文件,需要从列表中手动清除。
如果空字符不在换行符的位置,只需删除它们:
uniq -d examination.txt > files-to-clean.txt while read line; do ex -s +"%s/\%x00//g" -cwq $line; done < files-to-clean.txt
或者使用
tr
, 对于文件:tr -d '\000' < inputfile > outputfile
要清除文件中的空字符(假设它们都位于换行符的位置),请使用以下命令:
tr -s '\000' '\n' < inputfile > outputfile
tr
没有过多地研究如何一次处理多个文件。