【问题标题】:Could sed or awk use NUL character as record separator?sed 或 awk 可以使用 NUL 字符作为记录分隔符吗?
【发布时间】:2012-02-07 02:12:21
【问题描述】:

我有一个来自以下命令的 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 只会在[file name] 之后放置一个NUL 字符,但会在[pattern count] 之后放置一个“换行符”字符。我现在选择不使用 grep -Z 选项,但 TejasP 的回答仍然对我将来使用 awk 解析 NUL 分隔文件很有帮助。谢谢大家。

标签: sed awk nul


【解决方案1】:

从版本 4.2.2 开始,GNU sed 具有 -z--null-data 选项来执行此操作。例如:

sed -z 's/old/new' null_separated_infile

【讨论】:

    【解决方案2】:

    默认情况下,记录分隔符是换行符,将记录定义为单行文本。您可以通过更改内置变量 RS 来使用不同的字符。 RS 的值是一个字符串,说明如何分隔记录;默认值为\n,该字符串仅包含换行符。

     awk 'BEGIN { RS = "/" } ; { print $0 }' BBS-list
    

    【讨论】:

    • 我已经测试了命令awk 'BEGIN { RS = "\0" } ; { print $0 }'可以用NUL字符分隔记录。但是The GNU Awk User's GuideRS = "\0" 不可移植。无论如何,我可以从这个命令开始尝试将 [pattern count] 之前的 NUL 字符更改为我的情况下的“:”字符。
    【解决方案3】:

    是的,gawk 可以做到这一点,将记录分隔符设置为\0。例如命令

    gawk 'BEGIN { RS="\0"; FS="=" } $1=="LD_PRELOAD" { print $2 }' </proc/$(pidof mysqld)/environ
    

    将打印出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 </proc/$$/environ
    

    xargs 使用echo 作为默认命令。 -0 将输入设置为NUL 分隔。 -n1echo 的最大参数设置为 1,这样输出将由换行符分隔。


    正如Graeme's answer 所示,sed 也可以做到这一点。

    【讨论】:

      【解决方案4】:

      使用sed 删除null 字符-

      sed 's/\x0/ /g' infile > outfile
      

      或通过执行进行文件内替换(这将备份您的原始文件并用替换覆盖您的原始文件)。

      sed -i.bak 's/\x0/ /g' infile
      

      使用tr:

      tr -d "\000" < infile > outfile
      

      【讨论】:

      • tr "\000" "\n" &lt; infile &gt; output :-?)
      • @shellter 你是对的。我不确定 OP 是否想用换行符替换它们或删除它们...... :)
      • 但是我的目的是只替换[pattern count]之前的NUL字符,而不是替换所有的NUL字符。
      • @user1129812 在这种情况下,您可以使用sed 命令并从中删除g 选项。 g 选项用于进行全局替换。删除后,它只会在每行第一次出现时进行更改。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多