5

我有输入数据:

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

问候。

4

6 回答 6

7

我怀疑“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如果找到可以替代的东西。sed 在此处查看有关流量控制的更多信息。

于 2012-08-26T10:56:39.270 回答
2

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

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

00000055
于 2019-01-20T16:59:01.117 回答
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
于 2012-08-26T10:45:21.377 回答
1

您似乎已经sed涵盖了这些选项,这是一种方法awk

BEGIN      { RS="[ \n]"; ORS=OFS=""   }
/^[0-9]+$/ { $0 = sprintf("%03d", $0) } 
           { print $0, RT             }
于 2012-08-26T12:25:56.690 回答
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'
于 2012-08-26T13:36:32.880 回答
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
于 2018-09-04T10:29:55.273 回答