【问题标题】:Add leading 0 in sed substitution在 sed 替换中添加前导 0
【发布时间】:2012-08-26 10:33:37
【问题描述】:

我有输入数据:

foo 24
foobar 5 bar
bar foo 125

我想要输出:

foo 024
foobar 005 bar
bar foo 125

所以我可以使用这个 sed 替换:

s,\([a-z ]\+\)\([0-9]\)\([a-z ]*\),\100\2\3,
s,\([a-z ]\+\)\([0-9][0-9]\)\([a-z ]*\),\10\2\3,

但是,我可以做一个替换,那会做同样的事情吗?比如:

if (one digit) then two leading 0
elif (two digits) then one leading 0

问候。

【问题讨论】:

    标签: sed


    【解决方案1】:

    我怀疑是否可以在 one 替换命令中合并“if - else”逻辑而不保存中间数据(例如匹配的长度)。但这并不意味着你不能轻易做到这一点。例如:

    $ N=5
    $ sed -r ":r;s/\b[0-9]{1,$(($N-1))}\b/0&/g;tr" infile
    foo 00024
    foobar 00005 bar
    bar foo 00125
    

    它使用递归,在循环中所有小于$N 数字的数字添加一个零,当无法进行更多替换时结束。 r 标签基本上说:尝试进行替换,然后 goto r 如果找到可以替换的东西。在sedhere 中查看更多关于流量控制的信息。

    【讨论】:

    • @Artur 我已经添加了简要说明和链接,欢迎提问。
    • 12,345 和 123.45 怎么样?
    • @potong 这个例子只有整数,所以我认为这个正则表达式就足够了。您是对的,答案不适用于您的示例,因为每个都将被视为两个数字而不是一个。
    【解决方案2】:

    首先添加前导零的最大数量,然后从末尾取这个字符数:

    echo 55 | sed -e 's:^:0000000:' -e 's:0\+\(.\{8\}\)$:\1:'
    
    00000055
    

    【讨论】:

      【解决方案3】:

      使用两个替换命令:第一个将搜索一个数字并在前面插入两个零,第二个将搜索一个有两个数字的数字并在前面插入一个零。需要GNU sed,因为我使用单词边界命令来搜索数字(\b)。

      sed -e 's/\b[0-9]\b/00&/g; s/\b[0-9]\{2\}\b/0&/g' infile
      

      编辑以添加测试:

      infile的内容:

      foo 24 9
      foo 645 bar 5 bar
      bar foo 125
      

      使用以下输出运行上一个命令:

      foo 024 009
      foo 645 bar 005 bar
      bar foo 125
      

      【讨论】:

        【解决方案4】:

        您似乎涵盖了sed 选项,这是awk 的一种方式:

        BEGIN      { RS="[ \n]"; ORS=OFS=""   }
        /^[0-9]+$/ { $0 = sprintf("%03d", $0) } 
                   { print $0, RT             }
        

        【讨论】:

          【解决方案5】:

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

          echo '1.23 12,345 1 12 123 1234 1' | 
          sed 's/\(^\|\s\)\([0-9]\(\s\|$\)\)/\100\2/g;s/\(^\|\s\)\([0-9][0-9]\(\s\|$\)\)/\10\2/g' 
          1.23 12,345 001 012 123 1234 001
          

          或者可能会更容易一些:

          sed -r 's/(^|\s)([0-9](\s|$))/\100\2/g;s/(^|\s)([0-9][0-9](\s|$))/\10\2/g'
          

          【讨论】:

            【解决方案6】:

            我发现以下 sed 方法可以非常简单地将一个用零填充到 5 (n) 位的整数:

            sed -e "s/\<\([0-9]\{1,4\}\)\>/0000\1/; s/\<0*\([0-9]\{5\}\)\>/\1/"
            
            1. 如果有至少一个,最多 4 (n-1) 个数字,则在其中添加 4 (n-1) 个零 正面
            2. 如果在第一次转换后有任意数量的零后跟 5 (n) 位数字,则只保留最后 5 (n) 位数字

            当碰巧有超过 5 (n) 个数字时,此方法的行为方式与通常相同 - 没有任何内容被填充或修剪。

            输入:

            0
            1
            12
            123
            1234
            12345
            123456
            1234567
            

            输出:

            00000
            00001
            00012
            00123
            01234
            12345
            123456
            1234567
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-02-04
              • 2022-10-23
              • 2016-06-17
              • 2014-09-21
              • 2012-03-02
              • 2013-02-27
              • 1970-01-01
              • 2019-05-16
              相关资源
              最近更新 更多