bash 0子字符串上的填充数字

时间:2016-04-22 09:01:33

标签: bash substring pad

我的长列表如下:

D6N
T69TN
K70R
M184V
T215FEG

结果必须如下:

D006N
T069TN
K070R
M184V
T215FEG

我是关于bash的新手,我尝试了基于将其拆分为列并重新格式化的方法。但是,第2和第3个推定列的位置和长度不固定。 谢谢你的帮助!

6 个答案:

答案 0 :(得分:2)

您可以使用内置的match函数使用awk执行此操作:

awk 'match($0, /[0-9]+/) { printf "%s%03d%s\n", 
substr($0, 0, RSTART - 1), substr($0, RSTART, RLENGTH), substr($0, RSTART + RLENGTH) }' file

match成功后,它会设置两个变量RSTARTRLENGTH,可用于提取子字符串。中间子字符串使用%03d格式化,以填充前导零。

不会打印任何与图案不匹配的行。

使用perl的另一个选项:

perl -pe 's/\d{1,3}/sprintf("%03d", $&)/eg' file

这将使用零填充三位数替换任意一到三位数的序列。在此版本中,所有行都会打印出来。

答案 1 :(得分:0)

使用sed的正则表达式会稍微长一点,但这里有Perl

echo "D6N" | perl -pe 's/(\D)(\d)(\D)/${1}0$2$3/g; s/(\D)(\d\d)(\D)/${1}0$2$3/g;'

它会填充由非数字包围的零和2位数字。它通过一个简单的技巧来实现:填充1位数字(一位数字,因此1位数字变为2位数字),然后将2位数字填充为另一个零。

答案 2 :(得分:0)

AFAIK,没有简单的纯Bash解决方案。因此,我更喜欢Perl,因为Perl的表达很简单,Perl无处不在。

s='D6N
T69TN
K70R
M184V
T215FEG'

echo "$s" | perl -ne '/^(\D*)(\d{1,2})(\D*)$/m and printf "%s%03s%s", $1, $2, $3 or print'

答案 3 :(得分:0)

另一个基于sed的实施:

$ cat testfile
D6N
T69TN
K70R
M184V
T215FEG

$ sed -r 's/[0-9]+/00&/g; s/0?0?([0-9]{3})/\1/g' testfile
D006N
T069TN
K070R
M184V
T215FEG

逻辑:无条件地将2个零前缀加到数字&删除前导零,直到数字长度为3位。

答案 4 :(得分:0)

这个gnu awk也可以完成工作:

src

答案 5 :(得分:0)

使用Bash正则表达式:

#!/bin/bash

re='([[:alpha:]]*)([[:digit:]]*)([[:alpha:]]*)'

while IFS= read -r line; do
    [[ $line =~ $re ]]
    printf "%s%03d%s\n" "${BASH_REMATCH[1]}" "${BASH_REMATCH[2]}" "${BASH_REMATCH[3]}"
done < infile

这匹配正则表达式的每一行并捕获三个组:字母,数字,字母。 printf格式字符串可确保数字组在短于三位数时填充为零。

相关问题