【问题标题】:Text processing command: If 'x' but not 'y' then add 'z' at the end of line文本处理命令:如果是 'x' 而不是 'y' 则在行尾添加 'z'
【发布时间】:2016-04-03 01:50:39
【问题描述】:

假设我有以下输入:

CH12
CH23au
RCH34
CH99de
ZE33a
CH88aude
CHa

我希望输出是这样的:

CH12au
CH23au
RCH34
CH99deau
ZE33a
CH88aude
CHaau

基于行必须以“CH”开头且不具有模式“au”的规则。

我将如何做到这一点?

我假设我必须使用 sed?或者可能是 awk?

【问题讨论】:

  • 在我了解补丁之前解决我的情况的确切命令:export PATH=${PATH}:/var/lib/npm/.npm-global/bin && \ grep -q "^PATH " /etc/security/pam_env.conf && \ sudo sed -i.bak 's@^PATH.*@PATH DEFAULT='"${PATH}"'@g' /etc/security/pam_env.conf || \sudo sed -i.bak '$a\PATH DEFAULT='"${PATH}"'' /etc/security/pam_env.conf

标签: bash awk sed


【解决方案1】:

这是一个简单的 Awk 脚本,它在没有 au 的行的开头查找 CH。最后的1 是“打印所有输入行”的常用习语,$0 是当前输入行。

awk '/^CH/ && ! /au/ { $0 = $0 "au" }1' file

如果您希望在外部变量中添加后缀,则需要进行少量重构。

awk -v suf="au" '/^CH/ && $0 !~ suf { $0 = $0 suf } 1' file

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed '/^CH/{/au/!s/$/au/}' file
    

    关注以CH 开头的行,如果它们不包含au,则追加它。

    【讨论】:

    • 我应该提到这实际上是关于一个变量,但多亏了你,我设法解决了它: sed -i.bak '/^CH/{\|'"$foo"'| ! {s|$|'"$foo"'|}}' 文件
    【解决方案3】:

    使用 sed :

    sed '/au/!s/^CH\(.*\)/CH\1au/' file
    
    • /au/!:在不包含 au 的行中
    • s:替代
    • ^CHCH 开头的行
    • \(.*\) 后跟任意字符(使用 \( \) 捕获
    • CH\1au 将匹配模式替换为 CH,后跟捕获的字符,然后是结尾 au

    【讨论】:

      【解决方案4】:

      你可以试试这个:

      awk '
      {
          if(substr($0, 0, 2) == "CH")
          {
              if(index($0, "au") == 0)
                  printf("%sau\n",$0)
              else
                  print $0
          }
          else
              print $0
      }' file
      

      【讨论】:

      • @EdMorton - 感谢您的建议,我将阅读《Effective Awk Programming》一书。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-26
      • 2016-02-16
      • 1970-01-01
      相关资源
      最近更新 更多