【问题标题】:Conditionally matching numbers from string有条件地匹配字符串中的数字
【发布时间】:2013-03-09 19:34:21
【问题描述】:

我有一串数字格式如下:

24_1_1_1_1_1_12_1_1_13_1_1

下划线是空格

我需要获取 3 个数字。本例中的第一个数字24,然后是后面两个1's 之后的数字,在本例中为1。然后再两个1's 将是12。我尝试了许多sedawkgrep 解决方案来获得答案,但问题是所需的3 个数字中的任何一个都可能是1,2 或3 位数字。

所以在这个例子中,我需要加粗的数字。

24_1_1_1_1_1_12_1_1_13_1_1

【问题讨论】:

    标签: bash shell awk grep pattern-matching


    【解决方案1】:

    您可以将 $IFS 设置为_ 并将字符串拆分为一个数组:

    #!/bin/bash
    string=24_1_1_1_1_1_12_1_1_13_1_1
    OIFS=$IFS
    IFS=_
    ar=($string)
    IFS=$OIFS
    echo ${ar[0]} ${ar[3]} ${ar[6]}
    

    【讨论】:

    • 这只是打印与示例匹配的字段。
    • @sudo_O:这取决于您如何解释规范:“以下两个 1 之后的数字”。
    • @user2152271 您能否澄清一下是否只想打印某些字段 (在本例中为 1、4、7) 或者字段编号是否不固定并且确实取决于如果看到两个1s?
    • @choroba:我也先将 IFS 设置为 _,但后来我注意到在帖子中它说:“下划线是空格”。
    • @Scrutinizer:嗯,我没注意到。奇怪它是如何工作的:)
    【解决方案2】:

    将字符串拆分成一个数组,然后遍历数组:

    str="24_1_1_1_1_1_12_1_1_13_1_1"
    IFS="_" read -ra numbers <<< "$str"
    results=( ${numbers[0]} )
    take_next=0
    for n in "${numbers[@]:1}"; do
        if (( take_next == 2 )); then
            results+=( $n )
            take_next=0
        elif (( n == 1 )); then
            (( take_next++ ))
        else
            take_next=0
        fi
        (( ${#results[@]} == 3 )) && break
    done
    

    【讨论】:

      【解决方案3】:

      下面的awk one-liner 怎么样打印第一个字段,然后是两个字段之后的每个字段:

      $ awk 'NR==1||c==2{print;c=0;next}$1==1{c++}' RS=_ file
      24
      1
      12
      13
      

      如果你想在一定数量的匹配后退出(例如3)

      $ awk 'NR==1||c==2{print;c=0;m++;next}$1==1{c++}m==3{exit}' RS=_ file
      24
      1
      12
      

      【讨论】:

        【解决方案4】:

        使用读取:

        read a x x b x x c x <<< "$str"
        

        -

        $ printf "%s\n" "$a" "$b" "$c"
        24
        1
        12
        

        【讨论】:

        • @user2152271:我没有使用下划线作为字段终止符,因为在您的帖子中说:“下划线是空格”,否则读取语句可以像这样添加:IFS=_ read ....
        猜你喜欢
        • 2020-10-12
        • 1970-01-01
        • 2018-08-05
        • 2012-07-15
        • 1970-01-01
        • 1970-01-01
        • 2019-04-26
        • 1970-01-01
        相关资源
        最近更新 更多