在sed中添加前导0

时间:2017-11-27 18:38:07

标签: linux bash sed

我想将前导零添加到一串数字中,以便正好有三位数。考虑例如

echo "hello_1"   | sed -E 's/([0-9]+)/00\1/'  # hello_001
echo "hello_12"  | sed -E 's/([0-9]+)/0\1/'   # hello_012
echo "hello_123" | sed -E 's/([0-9]+)/\1/'    # hello_123

现在,问题在于我在这里使用了三个不同的表达式,而我在一条线路上传送了sed几行。像

这样的东西
printf "hello_1\nhello_12\nhello_123\n" | sed -E 's/([0-9]+)/0\1/'
hello_01
hello_012
hello_0123

结果不是我要找的那个。预期的输出是

hello_001
hello_012
hello_123

我试过

printf "hello_1\nhello_12\nhello_123\n" |  sed -r ":r;s/\b[0-9]{1,$((3-1))}\b/0&/g;tr"
hello_1
hello_12
hello_123

我是从this post获得的,但它不起作用,我不明白它是如何运作的。

我在Linux上使用GNU sed version 4.2.1

1 个答案:

答案 0 :(得分:1)

为什么它不起作用

您尝试过的sed程序对您不起作用,因为它会将字边界(\b)上的数字左右固定,并且 _被认为是单词字符(单词字符是字母,数字和下划线)。如果您将_替换为-(或空格),您会发现它有效:

$ printf "hello-1\nhello-12\nhello-123\n" | sed -E ':a; s/\b[0-9]{1,2}\b/0&/g; ta'
hello-001
hello-012
hello-123

一般sed解决方案

要修复一般情况(以及您的示例输入),您可以在左侧和左侧使用非数字字符[^0-9]代替\b 正确(与^$结合使用来处理行的开头和结尾):

$ printf "hello_1\nhello_12\nhello_123\n" | sed -E ':a; s/(^|[^0-9])([0-9]{1,2})([^0-9]|$)/\10\2\3/g; ta'
hello_001
hello_012
hello_123

这与原始表达式的工作方式类似:它以递归方式将数字零前置为1 - 2个数字的任何隔离序列。只要存在替换,分支命令t就会循环到开头(标签:a) - 即只要存在一个孤立的数字组,短于3个字符。

捕获群组\1\3只是通过\2中捕获的数字周围的上下文传递。我们只需要它们来匹配孤立数字组。