【问题标题】:Replace a string in bash script using regex for both linux and AIX使用 linux 和 AIX 的正则表达式替换 bash 脚本中的字符串
【发布时间】:2014-09-29 15:12:06
【问题描述】:

我有一个 bash 脚本,我可以在 linux 和 AIX 服务器上复制并运行它。
该脚本获取一个代表文件名的“名称”参数,我需要通过正则表达式操作此名称(目的无关紧要,很难解释)。
我需要从名称参数开始,直到第一个“-”字符后跟一个数字,然后将它与最后一个“。”连接起来。直到字符串结尾的字符。

例如:

名称:abcd-efg-1.23.4567-8.jar 将变为:abcd-efg.jar
名称:abc123-abc3.jar 将保留:abc123-abc3.jar
名称:abc-890.jar 将变为:abc.jar

我尝试了以下几种变体:

name=$1
regExpr="^(.*?)-\d.*\.(.*?)$/g"
echo $name 
echo $(printf ${name} | sed -e $regExpr)

我也不能使用sed -r(在某些示例中可以看到),因为 AIX sed 不支持 -r 标志。

最后一行当然是问题;我想我需要以某种方式使用 $1 + $2 占位符,但我似乎无法正确使用。

如何更改我的正则表达式,使其符合我的要求?

【问题讨论】:

    标签: regex linux bash aix


    【解决方案1】:

    给定文件:

    abcd-efg-1.23.4567-8.jar
    abc123-abc3.jar
    abc-890.jar
    

    这是一种改变你给的名字的方法:

    $ sed 's/\(.\?\)-[0-9].*\(\.[a-z]*\)$/\1\2/' file
    abcd-efg.jar
    abc123-abc3.jar
    abc.jar
    

    相当于(如果你可以使用-r):

    $ sed -r 's/(.?)-[0-9].*(\.[a-z]*)$/\1\2/' file
    abcd-efg.jar
    abc123-abc3.jar
    abc.jar
    
    • 它将所有内容都添加到- + digit\1 中的“存储”。
    • 它来自最后一个. + letters\2 中的“商店”。
    • 最后将这些块打印回来。

    请注意,扩展名也可以使用 basename 内置函数或类似 `"${line##*.}" 来获取。

    【讨论】:

    • 我遇到的一个问题是文件名不以字母结尾。例如:abcd-12.war.2。它按原样返回整个名称,而不是 abcd.2
    • @Osher 你能试试sed 's/\(.\?\)-[0-9].*\(\.\w*\)$/\1\2/' file吗?也就是说,将最后一个[a-z]* 更改为\w* 匹配一个单词。它对我有用。
    【解决方案2】:

    当成功匹配正则表达式时,perl 会将括号 (..) 中匹配的内容捕获为 $1、$2 等。

    $ perl -e 'my $arg = $ARGV[0]; $arg =~ /^(.*?)-\d.*\.(.*?)$/; print "$1.$2\n"; ' abc-890.jar
    abc.jar
    

    【讨论】:

      【解决方案3】:

      在 sed 中,您可以简单地使用以下内容。

      #!/bin/sh
      STRING=$( cat <<EOF
      abcd-efg-1.23.4567-8.jar
      abc123-abc3.jar
      abc-890.jar
      EOF
      )
      echo "$STRING" | sed 's/-[0-9].*\(\.[^.]\+\)$/\1/'
      # abcd-efg.jar
      # abc123-abc3.jar
      # abc.jar
      

      这匹配一个连字符后跟一个数字以及后面的所有内容,并替换为文件扩展名。

      或者您可以考虑使用 Perl 单行:

      echo "$STRING" | perl -pe 's/-\d.*(?=\.[^.]+$)//'
      # abcd-efg.jar
      # abc123-abc3.jar
      # abc.jar
      

      【讨论】:

        【解决方案4】:

        你可以用这个:

        perl -F'(-(?:\d)|\.)' -ane 'print "$F[0].$F[$#F]"'
        

        它将输入拆分为任何-,后跟一个数字,或任何.。然后它打印第一个字段,然后是一个点,然后是最后一个字段。

        测试一下:

        $ cat file
        abcd-efg-1.23.4567-8.jar
        abc123-abc3.jar
        abc-890.jar
        $ perl -F'(-(?:\d)|\.)' -ane 'print "$F[0].$F[$#F]"' file
        abcd-efg.jar
        abc123-abc3.jar
        abc.jar
        

        【讨论】:

          猜你喜欢
          • 2013-02-01
          • 2012-12-13
          • 1970-01-01
          • 2015-02-27
          • 1970-01-01
          • 1970-01-01
          • 2019-04-17
          相关资源
          最近更新 更多