在sed替换中添加前导0

时间:2012-08-26 10:33:38

标签: sed

我有输入数据:

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

问候。

6 个答案:

答案 0 :(得分:4)

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

$ 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如果找到要替换的内容。请参阅sed here中有关流量控制的更多信息。

答案 1 :(得分:1)

使用两个替代命令:第一个将搜索一个数字,并且将在之前插入两个零,第二个将搜索具有两个数字的数字,并且将在之前插入一个零。需要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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

这可能适合你(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'

答案 4 :(得分:0)

我发现以下 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

答案 5 :(得分:0)

首先添加最大数量的前导零,然后从末尾开始添加此数量的字符:

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

00000055