【问题标题】:Replace using gsub in awk在 awk 中使用 gsub 替换
【发布时间】:2015-09-15 12:29:27
【问题描述】:

尝试在 awk 中执行 gsub。 我想用下划线替换单个空格,但是相邻的字符被替换了

awk -F"  +" 'NF > 1  {gsub(/[[:alnum:]][ ][[:alnum:]]/, "_")}1' file

输入:

this is example

ca                                 bc           dec cat
251                          otg          op con

这是我得到的:

this is example

ca                                 bc           de_at
251                          otg          o_on

期望的输出:

this is example

ca                                 bc           dec_cat
251                          otg          op_con

【问题讨论】:

    标签: awk


    【解决方案1】:

    这是一个领域,其中(非 GNU)awk 不是完成这项工作的最佳工具。我建议改用 sed:

    $ sed '/  / s/\([[:alnum:]]\) \([[:alnum:]]\)/\1_\2/g' file
    this is example
    
    ca                                 bc           dec_cat
    251                          otg          op_con
    

    这会对包含 2 个或更多空格的行执行替换,这与给定字段分隔符的NF > 1 等效。

    这里的关键是捕获空格前后的字符,然后在替换中使用。这也可以在 GNU awk 中完成,使用 gensub:

    $ gawk -F"  +" 'NF > 1 { $0 = gensub(/([[:alnum:]]) ([[:alnum:]])/, "\\1_\\2", 1) }1' file
    this is example
    
    ca                                 bc           dec_cat
    251                          otg          op_con
    

    gensub 返回替换的结果,因此必须将其重新分配给$0 才能影响输出。

    【讨论】:

    • 您可以使用/ / 而不是2,$ 来过滤具有两个或多个字段的行,这些字段给出了" +" 字段分隔符(每个字段中有两个空格;注释布局会吞下它们)。不过,我会考虑使用perl -pe 's/\S\K (?=\S)/_/g if / /'(同样,/ / 中有两个空格)。
    • 谢谢,我已经按照您的建议编辑了条件。您建议的 perl 代码看起来可以完成这项工作,但我想这取决于“字母数字”要求的严格程度。
    • 啊,我没有仔细阅读那里。不过,修复起来很简单:将 \S 替换为 \w
    • 关于被吞噬的空白,看起来这是另一个问题“修复”的结果:meta.stackoverflow.com/a/272194/2088135 :)
    猜你喜欢
    • 2019-04-21
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 2017-07-12
    • 2017-05-20
    • 1970-01-01
    • 2018-10-19
    相关资源
    最近更新 更多