【问题标题】:sed: Extract version number from stringsed:从字符串中提取版本号
【发布时间】:2011-07-11 19:19:53
【问题描述】:

输入:adcheck (CentrifyDC 4.4.3-421)

所需输出:4.4.3

我认为可行的方法:

/usr/share/centrifydc/bin/adcheck --version | sed -n '/Centrify DC /,/-/p'

但这什么也没输出??

谢谢!

【问题讨论】:

    标签: sed


    【解决方案1】:

    “您认为可行的方法”的更正版本:

    /usr/share/centrifydc/bin/adcheck --version | sed 's|.*CentrifyDC \([0-9\.]*\).*|\1|'
    

    输出:

    4.4.3
    

    【讨论】:

      【解决方案2】:

      您的解决方案不起作用,因为您试图使用地址来选择一行,但地址只是选择了一堆行。您的代码/Centrify DC /,/-/p 将打印包含Centrify DC 的一行和包含- 的另一行之间的所有行。但是,它不能只在一行内工作

      您想要的是从该行中删除除版本号之外的所有内容。我建议您将版本号分组并用它替换该行的所有内容:

      $ echo "adcheck (CentrifyDC 4.4.3-421)" | sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/'
      4.4.3
      

      这里我们用\([0-9]*\.[0-9]*\.[0-9]*\)将版本号放在一个组中,并用组替换所有行(由\1引用)。

      如果您的输入多于一行,则可能需要一些隧道:

      $ cat file
      adcheck (CentrifyDC 4.4.3-421)
      another line
      still another line
      $ sed 's/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/' file
      4.4.3
      another line
      still another line
      

      在这种情况下,将-n 标志传递给 sed 以禁止默认打印。然后,为s/// 命令(如/adcheck (CentrifyDC /)提供一个地址,以保证替换只会发生在与地址匹配的行中。最后将p 标志添加到s/// 命令 - 它会在替换后打印该行:

      $  sed -n '/adcheck (CentrifyDC /s/^.*[^0-9]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/p' file
      4.4.3
      

      【讨论】:

        【解决方案3】:

        一行脚本

        perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' YOURFILE.TXT
        

        或更长一点,但可以处理多个版本:

        perl -nle 'print $v if ($v)=/([0-9]+([.][0-9]+)+)/' YOURFILE.TXT
        

        使用第一个命令行的示例

        $> V=$(perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'<<<'adcheck (CentrifyDC 4.4.3-421)')
        $> echo "$V"
        4.4.3
        
        $> V=$(perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' <<< 'dos2unix-8.2.3-beta.zip')
        $> echo "$V"
        8.2.3
        
        $> echo 'A2 33. Z-0.1.2.3.4..5' | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
        0.1.2.3.4
        
        $> gcc --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
        4.7.3
        
        $> bash --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
        4.2.45
        
        $> meld --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
        1.6.1
        
        $> uname -a | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/'
        3.8.0
        
        $> perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' /etc/issue
        13.04
        

        注意:第一个命令行提取的版本没有最后的回车符(我的意思是\n)。如果这是一个问题,请使用第二个版本或将第一个命令行包含在 echo 中:

        $> echo $( perl --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' )
        5.14.2
        

        不幸的是,如果有多行包含版本号,这些版本号将被连接:

        $> echo $(gwenview --version | perl -pe '($_)=/([0-9]+([.][0-9]+)+)/' )
        

        4.8.44.10.54.10.4

        为了每行提取一个版本,必须更改一行脚本:

        perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}'
        

        示例:

        $> gwenview --version | perl -pe 'if(($_)=/([0-9]+([.][0-9]+)+)/){$_.="\n"}' 
        4.8.4
        4.10.5
        4.10.4
        

        仅提取第一个版本号并附加回车(我的意思是换行\n),我建议:

        perl -pe 'if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v\n";exit}$_=""'
        

        示例:

        $> gwenview --version | perl -pe 'if(($v)=/([0-9]+([.][0-9]+)+)/){print"$v\n";exit}$_=""'
        4.8.4
        

        关于信息,我的 尝试不太好。谁知道如何获得与我的perl 脚本相同的行为但使用sed

        sed 's/\([0-9][0-9]*[.][0-9][0-9.]*\)/\n\1/'
        

        如果您认为可以改进这些脚本,请随时发表评论:)

        【讨论】:

          【解决方案4】:
          sed 's/[[:alpha:]|(|[:space:]]//g' | awk -F- '{print $1}' <<< "(CentrifyDC 4.4.3-421)"
          

          输出:4.4.3

          使用[:space:] 删除多余的空格。

          sed 用于删除不需要的字符,awk -F- 表示使用- 作为字段分隔符

          【讨论】:

          • 不需要括号表达式内的管道,因为括号表达式表示“任何这些字符”。可能是sed 's/[[:alpha:]([:space:]]//g'
          • 每次我们吹管这么多,一只小猫就死了。 echo | sed | awk太多了,当awk一个人可以做到。
          【解决方案5】:

          这是 Perl 中的一个解决方案:

          echo "adcheck (CentrifyDC 4.4.3-421)" | perl -ne 'm/adcheck \(CentrifyDC (.*?)\)/; print "$1\n" '
          /usr/share/centrifydc/bin/adcheck --version | perl -ne 'm/adcheck \(CentrifyDC (.*?)\)/; print "$1\n" '
          

          【讨论】:

            【解决方案6】:

            仅使用awk 的另一种方法:

            $ echo "adcheck (CentrifyDC 4.4.3-421)" | awk '{sub(/-.*/,"",$3);print $3}'
            4.4.3
            

            ...或者cut的组合:

            $ echo "adcheck (CentrifyDC 4.4.3-421)" | cut -d' ' -f3 | cut -d'-' -f1
            4.4.3
            

            【讨论】:

              【解决方案7】:

              例如,这可以完成工作

              wget -V|head -n1|sed 's/[[:alpha:]|(|[:space:]]//g' | awk -F- '{print
              > $1}'
              

              【讨论】:

              • 这与接受的答案相比如何?为什么有人会更喜欢这种方法?
              猜你喜欢
              • 2013-05-24
              • 1970-01-01
              • 1970-01-01
              • 2020-03-08
              • 2022-12-23
              • 2015-06-07
              • 1970-01-01
              • 2017-01-31
              • 1970-01-01
              相关资源
              最近更新 更多