【问题标题】:Bash Script - split string using regex delimiterBash 脚本 - 使用正则表达式分隔符拆分字符串
【发布时间】:2014-05-31 15:06:21
【问题描述】:

我想拆分类似'substring1 substring2 ONCE[0,10s] substring3'的字符串。预期的结果应该是(带分隔符'ONCE[0,10s]'):

substring1 substring2
substring3

问题是分隔符中的数字是可变的,例如'ONCE[0,1s]'或'ONCE[0,3m]'或'ONCE[0,10d]'等等。

如何在 bash 脚本中执行此操作?有什么想法吗?

谢谢

【问题讨论】:

    标签: regex string bash split sh


    【解决方案1】:

    您可以使用awk。指定字段分隔符为:

    'ONCE[[]0,[^]]*[]] *'
    

    例如,使用您的示例输入:

    $ awk -F 'ONCE[[]0,[^]]*[]] *' '{for(i=1;i<=NF;i++){printf $i"\n"}}' <<< "substring1 substring2 ONCE[0,10s] substring3"
    substring1 substring2 
    substring3
    

    【讨论】:

      【解决方案2】:

      重击:

      s='substring1 substring2 ONCE[0,10s] substring3'
      
      if [[ $s =~ (.+)" ONCE["[0-9]+,[0-9]+[smhd]"] "(.+) ]]; then
          echo "${BASH_REMATCH[1]}"
          echo "${BASH_REMATCH[2]}"
      else 
          echo no match
      fi
      
      substring1 substring2
      substring3
      

      【讨论】:

        【解决方案3】:

        OP 中提供的示例(以及@GlennJackman 和@devnull 提供的两个答案)假设实际问题可能是:

        在 bash 中,如何用换行符替换字符串中正则表达式的匹配项。

        这实际上与“使用正则表达式拆分字符串”不同,除非您添加字符串不包含任何换行符的约束。即便如此,它实际上并没有“拆分”字符串。假设其他进程将使用换行符来拆分结果。

        一旦重新提出问题,解决方案就不再具有挑战性。你可以使用任何支持正则表达式的工具,例如sed:

        sed 's/ *ONCE\[[^]]*] */\n/g' <<<"$variable"
        

        (如果您只想替换第一个序列,请删除g;您可能需要调整正则表达式,因为不太清楚所需的约束是什么。)

        bash 本身不提供使用正则表达式的replace all 原语,尽管它确实具有“模式”,并且如果设置了选项extglob(这是某些发行版的默认设置),模式就足够了强大的表达模式,所以你可以使用:

        echo "${variable//*( )ONCE\[*([^]])]*( )/$'\n'}"
        

        同样,您可以通过将 // 更改为 / 来使替换只发生一次,您可能需要更改模式以满足您的精确需求。

        这留下了一个问题,即如何使用正则表达式指定的分隔符实际拆分 bash 变量,以获取“拆分”的某些定义。一种可能的定义是“以字符串的部分作为参数调用函数”;这就是我们在这里使用的:

        # Usage:
        # call_with_split <pattern> <string> <cmd> <args>...
        # Splits string according to regular expression pattern and then invokes
        # cmd args string-pieces
        call_with_split () { 
          if [[ $2 =~ ($1).* ]]; then
            call_with_split "$1" \
                            "${2:$((${#2} - ${#BASH_REMATCH[0]} + ${#BASH_REMATCH[1]}))}" \
                            "${@:3}" \
                            "${2:0:$((${#2} - ${#BASH_REMATCH[0]}))}"
          else
            "${@:3}" "$2"
          fi
        }
        

        例子:

        $ var="substring1 substring2 ONCE[0,10s] substring3"
        $ call_with_split " ONCE\[[^]]*] " "$var" printf "%s\n"
        substring1 substring2
        substring3
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-11-22
          • 2011-02-24
          • 1970-01-01
          • 2015-05-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多