我目前正在尝试通过将其传送到 sed 来修改回显的字母数字字符串。我有兴趣修改的区域是一个数字块,我想通过在其前面插入适当数量的零来使其长度为 8 个字符。例如:
输入:
loremipsumdolorsit2367amet
期望的输出:
loremipsumdolorsit00002367amet
用 sed 可以做到这一点吗?我正在处理的数字块少于 8 个字符。我不确定是否这帖子很有用。
编辑:每个字符串中只有一组数字。
答案1
这假设数字后面有一些非数字文本:
echo "loremipsumdolorsit2367amet" \
| sed -r -e 's/[0-9]/0000000&/' -e 's/0*([0-9]{8}[^0-9])/\1/'
结果:loremipsumdolorsit00002367amet
这并不假设:
... | sed -r -e 's/[0-9]/0000000&/' -e 's/0*([0-9]{8}([^0-9]|$))/\1/'
它们使用 sed 的 ERE 模式。许多 sed 实现使用该-r
标志来指定这一点;有些使用旗帜-E
;有些同时使用。目前,在 sed 中使用 ERE 模式的能力并不是 POSIX 标准的一部分,但有人讨论将其添加到标准中。我还没有遇到过不能以某种方式使用 ERE 模式的现代 sed 实现。
在某些情况下,有些事情可以使用 ERE 模式完成,而使用默认 sed 模式 (BRE) 则无法完成。看对这个答案的评论。但在目前的情况下,使用 ERE 模式只是为了方便。正如 sch 在评论中所说,您可以省略-r
(或-E
) 标志,只需替换(...)
with\(...\)
和{8}
with \{8\}
。我最初的答案使用了+
,这也不是 BRE 模式的一部分;但事实上这对于解决方案来说并不是必需的。
答案2
对于任何 sed:
sed 's/[0-9]\{1,\}/0000000&/g;s/0*\([0-9]\{8,\}\)/\1/g'
答案3
这可以用 perl 实现:
perl -e 'my $a="loremipsumdolorsit2367amet"; $a =~ s/([0-9]+)/sprintf("%010d",$1)/e; print $a'
得到:
loremipsumdolorsit0000002367amet
处理所有输入行:
perl -pe 's/([0-9]+)/sprintf("%010d",$1)/e'
答案4
也不是 sed,但这里有一个稍微复杂的 (GNU) awk 替代方案:
echo loremipsumdolorsit2367amet | awk '{gsub( /[0-9]+/, sprintf( "%08d", gensub(/[^0-9]/, "","g"))); print}'
loremipsumdolorsit00002367amet