【问题标题】:splitting a data field into two based on a charatcer count根据字符数将数据字段一分为二
【发布时间】:2013-08-16 09:24:21
【问题描述】:

我的问题是:

我的数据如下所示:

>header_GH_X
12 15 53 43 23 25 45 56 4544 32 3 42 53
>header2
15 34 155 6 54 7 66 8888 23 12 23 45

但它应该是这样的:

>header_GH_Y
12 15 53 43 23 25 45 56 45 44 32 3 42 53
>header2
15 34 15 5 6 54 7 66 88 88 23 12 23 45

每第二行都包含数字只能是一位或两位数字的字段。有没有人一个简单的 awk 解决方案去每隔一行,计算每个字段中的字符,当有超过 2 个字符时,将字段分成两个,例如245 变成 24 5 和 2345 变成 23 45

【问题讨论】:

    标签: sed awk


    【解决方案1】:

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

    sed '/^>/!s/\S\S\B/& /g' file
    

    对于所有不以> 开头的行,在单词内的 2 个非空格后添加一个空格。

    【讨论】:

      【解决方案2】:

      一个 sed 单线可以做到这一点

      sed -r 's/([0-9]{2})([0-9]+)/\1 \2/g'
      

      测试

      kent$  echo ">header_GH_X
      12 15 53 43 23 25 45 56 4544 32 3 42 53
      >header2
      15 34 155 6 54 7 66 8888 23 12 23 45"|sed -r 's/([0-9]{2})([0-9]+)/\1 \2/g'
      >header_GH_X
      12 15 53 43 23 25 45 56 45 44 32 3 42 53
      >header2
      15 34 15 5 6 54 7 66 88 88 23 12 23 45
      

      【讨论】:

      • 这完美地完成了工作。谢谢。
      • @user1308144 你确定吗?您的输入是否包含超过 4 位的数字,并且标头的数量是否超过 100?
      • @sudo_O 在这种情况下,它永远不会超过 4 位数。在这种情况下,标题也不会导致问题(遵循示例中第一个标题的样式),但感谢您指出它,因为它会在按顺序编号的标题的情况下导致问题。
      【解决方案3】:

      @Kent 几乎就在那里,但他的解决方案在两种情况下都失败了。如果标头 ID 大于 2 位,它将被拆分,大于 4 的数字不会被拆分为 2 组。例如,将以下内容作为输入文件:

      $ cat file
      >header_GH_X
      12 15 53 43 23 25 45 56 4544 32 3 42 53
      >header2
      15 34 155 6 54 7 66 8888 23 12 23 45
      >header102
      15 34 155 6 54 7 66 88888888 23 12 23 45
      

      通过一些小的改动很容易解决这个问题:

      $ sed -r ':a;2~2s/([0-9]{2})([0-9]+)/\1 \2/g;ta' file
      >header_GH_X
      12 15 53 43 23 25 45 56 45 44 32 3 42 53
      >header2
      15 34 15 5 6 54 7 66 88 88 23 12 23 45
      >header102
      15 34 15 5 6 54 7 66 88 88 88 88 23 12 23 45
      

      【讨论】:

        【解决方案4】:

        这是一个 awk 解决方案,(因为问题被标记为 awk):

        awk '!/^>/{for (i=1; i<=NF; i++) do {printf "%s ", substr($i,0,2); $i=substr($i,3)} while ($i != ""); print "" }/^>/' file
        

        或以更易读的格式:

        awk '
            !/^>/{
                for (i=1; i<=NF; i++) 
                    do {
                        printf "%s ", substr($i,0,2); 
                        $i=substr($i,3)
                    } while ($i != ""); 
                print "" 
            }
            /^>/
        ' file
        

        【讨论】:

          【解决方案5】:

          awk

          awk '/^[0-9]/ {gsub(/[0-9][0-9]/,"& ");$1=$1}1' file
          >header_GH_X
          12 15 53 43 23 25 45 56 45 44 32 3 42 53
          >header2
          15 34 15 5 6 54 7 66 88 88 23 12 23 45
          

          【讨论】:

            猜你喜欢
            • 2018-10-10
            • 2012-08-09
            • 1970-01-01
            • 2015-10-08
            • 1970-01-01
            • 1970-01-01
            • 2015-06-06
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多