【问题标题】:Reprint column with modifications修改后重印专栏
【发布时间】:2019-07-22 18:02:36
【问题描述】:

我有一个如下所示的文件:

lbsrv_standards-d
lbsrv_standards-t
lbsrv_standards

期望的输出:

rename lbsrv_standards-d lb_standards-d
rename lbsrv_standards-t lb_standards-t
rename lbsrv_standards lb_standards

所以我需要打印 $1,一个空格,然后打印 $1 的修改版本,我一直在使用 awk,但如果不在原始 $1s 和修改后的 $1s 之间添加换行符,我无法弄清楚替换。

解决方案:

awk '{print "rename "$1} ; { gsub("lbsrv", "lb", $1) ; print }'

输出:

rename lbsrv_standards-d 
lb_standards-d
rename lbsrv_standards-t 
lb_standards-t
rename lbsrv_standards 
lb_standards

任何帮助将不胜感激

谢谢

【问题讨论】:

    标签: awk sed cut tr


    【解决方案1】:

    你可以使用

    awk  '{a=$0; sub(/^lbsrv/, "lb", a); print "rename "$0" "a }'
    

    online demo

    详情

    • a=$0 - 用整行的值声明一个临时变量
    • sub(/^lbsrv/, "lb", a) - 字符串开头的 lbsrv 替换为 lb
    • print "rename "$0" "a - 打印结果:rename、空格、整行、空格以及a 变量的内容。

    sed 可以提供更简单的解决方案(特别是如果字符串单独出现):

    sed 's~^lbsrv\(.*\)~& lb\1~' file > newfile
    

    this sed demo

    这是一个基于 BRE POSIX 模式的 sed 命令,用于查找

    • ^ - 行首
    • lbsrv - 子字符串
    • \(.*\) - 第 1 组:任何 0 个或更多字符,直到行/输入的末尾。

    & lb\1 是一种替换模式,它首先取整行,然后附加一个空格,lb,然后是第 1 组的内容。

    【讨论】:

      【解决方案2】:

      第一种解决方案:请您尝试以下方法。

      awk 'BEGIN{FS="_"}{print "rename",$0,"lb_"$2}'  Input_file
      

      说明:现在添加上述代码的说明。

      awk '                           ##Starting awk program from here.
      BEGIN{                          ##Starting BEGIN section here.
        FS="_"                        ##Setting field separator as _ here.
      }                               ##Closing BEGIN section of awk command here.
      {
        print "rename",$0,"lb_"$2     ##Printing string rename then complete line then lb_ string with 2nd column here as per OP need.
      }'  Input_file                  ##Mentioning Input_file name here.
      

      第二个解决方案:现在添加一个sed 解决方案。

      sed 's/\([^_]*\)_\(.*\)/rename \1_\2 lb_\2/'   Input_file
      

      输出如下。

      rename lbsrv_standards-d lb_standards-d
      rename lbsrv_standards-t lb_standards-t
      rename lbsrv_standards lb_standards
      

      【讨论】:

        【解决方案3】:

        其他答案都很好,但是您可以看到您需要做的就是使用printf 而不是print

        $ awk '{printf "rename %s ", $1} ; { gsub("lbsrv", "lb", $1) ; print }' file
        rename lbsrv_standards-d lb_standards-d
        rename lbsrv_standards-t lb_standards-t
        rename lbsrv_standards lb_standards
        

        当然,通常您会将命令组合在一个操作中:

        $ awk '{printf "rename %s ", $1; gsub("lbsrv", "lb", $1) ; print }' file
        

        另外,gsub 默认在$0 上运行,使用尾随1 而不是print 很流行,所以最后:

        $ awk '{printf "rename %s ", $1; gsub("lbsrv", "lb")}1' file
        

        【讨论】:

          【解决方案4】:

          如果创建输出意味着结束实际重命名文件,您可以改为这样做:

          $ rename lbsrv_ lb_ lbsrv_standards{-d,-t,}
          

          将对指定的三个文件进行前缀重命名(在 bash 大括号扩展之后)。

          【讨论】:

            【解决方案5】:

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

            sed 's/lbsrv\(.*\)/rename & lb\1/p;d' file
            

            使用模式匹配来识别需要复制的行部分并打印成功匹配,否则删除该行。

            【讨论】:

              【解决方案6】:

              使用 Perl

               perl -pe ' s/lb(?:srv)(.*)/rename $& lb$1/g '
              

              用你给定的输入

              $ cat jim.txt
              lbsrv_standards-d
              lbsrv_standards-t
              lbsrv_standards
              
              $ perl -pe ' s/lb(?:srv)(.*)/rename $& lb$1/g ' jim.txt
              rename lbsrv_standards-d lb_standards-d
              rename lbsrv_standards-t lb_standards-t
              rename lbsrv_standards lb_standards
              
              $
              

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2016-07-12
                • 2023-03-18
                • 1970-01-01
                • 1970-01-01
                • 2015-12-16
                • 2010-09-11
                相关资源
                最近更新 更多