我有一个NUL定界输出,来自以下命令:
some commands | grep -i -c -w -Z 'some regex'
输出包含以下格式的记录:
[file name]\0[pattern count]\0
我想使用文本处理工具(例如sed / awk)将记录更改为以下格式:
[file name]:[pattern count]\0
但是,似乎sed / awk通常只处理以"换行符"分隔的记录。 我想知道如何使用sed / awk实现我的目的,或者如果sed / awk无法处理这种情况,我应该使用其他Linux工具。
感谢您的任何建议。
劳伦斯
那你怎么看这个文件?用十六进制编辑器?它怎么知道在哪里打破界限?为什么不将 0转换为 n并拥有一个可以使用标准unix范例进行处理的易于阅读的文件呢?否则,在每一步中,您都将与unix的基本定律"每个记录都按自己的路线行事"! ;-)生命太短了,还有很多有趣的问题需要解决。您能否获得使用 n或...颤抖 r n的原始输出源?祝好运。
输出将不显示,而是通过管道传递到另一个命令中。我使用NUL作为分隔符,因为Linux文件名中可以??包含"换行符"。我同意,对于我们来说,为我们的问题找出所有解决方案的时间太短了。
但是文件名是与管道中包含的数据不同的数据。 2仅在将数据写入文件中且名称可能带有 n的情况下碰面。祝好运。
我终于弄清楚了grep -c -Z只会在[pattern count]之后放置一个"换行"字符。我现在选择不使用grep -Z选项,但是TejasPs的答案对于以后使用awk解析NUL分隔文件仍然很有帮助。谢谢大家
从版本4.2.2开始,GNU sed具有-z或--null-data选项来执行此操作。例如:
sed -z 's/old/new' null_separated_infile
默认情况下,记录分隔符是换行符,将一条记录定义为一行文本。您可以通过更改内置变量RS使用其他字符。 RS的值是一个字符串,说明如何分隔记录;默认值为" n",该字符串仅包含换行符。
awk 'BEGIN { RS ="/" } ; { print $0 }' BBS-list
我已经测试过命令awk BEGIN { RS ="\0" } ; { print $0 }可以用NUL字符分隔记录。 但是GNU Awk用户指南说RS =" 0"是不可移植的。 无论如何,在我的情况下,我可以从此命令开始尝试将[pattern count]之前的NUL字符更改为":"字符。
是的,gawk可以做到,将记录分隔符设置为\0。例如命令
gawk 'BEGIN { RS="\0"; FS="=" } $1=="LD_PRELOAD" { print $2 }'
将打印出LD_PRELOAD变量的值:
/usr/lib/x86_64-linux-gnu/libjemalloc.so.1
/proc/$PID/environ文件是由NUL分隔的环境变量列表。我以它为例,因为在Linux系统上尝试很容易。
BEGIN部分将记录分隔符设置为\0,字段分隔符设置为=,因为我也想基于=之前的部分提取=之后的部分。
如果第一个字段具有我感兴趣的键,则$1=="LD_PRELOAD"将运行该块。
print $2块在=之后打印出字符串。
但是mawk无法解析用NUL分隔的输入文件。这记录在man mawk中:
BUGS
mawk cannot handle ascii NUL \0 in the source or data files.
mawk将停止读取第一个\0字符之后的输入。
您还可以使用xargs来处理NUL分隔的输入,这有点不直观,就像这样:
xargs -0 -n1
xargs使用echo作为默认命令。
-0将输入设置为NUL分隔。
-n1将echo的max参数设置为1,这样输出将由换行符分隔。
正如Graeme的答案所示,sed也可以做到这一点。
使用sed删除null字符-
sed 's/\x0/ /g' infile > outfile
或通过做文件内替换(这将备份原始文件并用替换覆盖原始文件)。
sed -i.bak 's/\x0/ /g' infile
使用tr:
tr -d"\000" < infile > outfile
或tr"\000""
" < infile > output:-?)
@shellter你是对的。 我不确定OP是否要用换行符替换它们或删除它们... :)
但是我的目的是仅替换[pattern count]之前的NUL字符,而不是替换所有NUL字符。
@ user1129812在这种情况下,您可以使用sed命令并从中删除g选项。 g选项用于进行全局替换。 删除后,只会在每行的第一次出现时进行更改。