Max*_*lev 7 bash awk regular-expression
我正在尝试编写一个脚本,将行中的每个数字减少“1”,但我得到的是所有“0”:
awk '{a=gensub(/([0-9]+)/,"\\1","g",$0);
if(a~/[0-9]+/) {gsub(/[0-9]+/,a-1,$0);}
print $0}'
Run Code Online (Sandbox Code Playgroud)
例如,字符串:
1,2,3,4-7
Run Code Online (Sandbox Code Playgroud)
应该导致:
0,1,2,3-6
Run Code Online (Sandbox Code Playgroud)
相反,我得到:
0,0,0,0-0
Run Code Online (Sandbox Code Playgroud)
Sté*_*las 12
awk替代能力相当有限。gawk具有gensub()可在至少包括在替换匹配的部分的部分,但没有操作可在那些来进行。
可以使用awk,但您需要采取不同的方法:
awk '{
text = $0
$0 = ""
while (match(text, /[0-9]+/)) {
$0 = $0 substr(text, 1, RSTART-1) \
(substr(text, RSTART, RLENGTH) - 1)
text = substr(text, RSTART+RLENGTH)
}
$0 = $0 text
print}'
Run Code Online (Sandbox Code Playgroud)
或者使用 GNUawk作为 @jofel 方法的变体:
gawk -v 'RS=[0-9]+' '{printf "%s", $0 (RT==""?"":RT-1)}'
Run Code Online (Sandbox Code Playgroud)
或者
gawk -v 'RS=[^0-9]+' '{printf "%s",($0==""?"":$0 - 1)RT}'
Run Code Online (Sandbox Code Playgroud)
但是,使用以下方法要容易得多perl:
perl -pe 's/\d+/$&-1/ge'
Run Code Online (Sandbox Code Playgroud)
perl可以使用捕获组(as $1, $2... 以及$&整个匹配的部分)并且带有e标志可以perl使用这些来运行任意表达式。
您的 awk 解决方案仅匹配第一个数字,然后将所有其他数字替换为第一个数字减一。
拿你的程序来说,你可以和 GNU 的 awk ( gawk) 一起使用:
awk 'BEGIN { RS="[^0-9]"; OFS=""; ORS=""; } {a=gensub(/([0-9]+)/,"\\1","g",$0);if(a~/[0-9]+/) {gsub(/[0-9]+/,(a-1),$0);} print $0,RT}'
Run Code Online (Sandbox Code Playgroud)
但这可以简化为
awk 'BEGIN { RS="[^0-9]"; OFS=""; ORS=""; } {if(length($0)) {print ($0-1);}print RT}'
Run Code Online (Sandbox Code Playgroud)
或者有评论:
awk '
BEGIN {
RS="[^0-9]"; # set the record separator to a regexp matching all
OFS=""; # no output field separator
ORS=""; # no output record separator (we use RT)
}
{
if(length($0)) { # if number found
print ($0-1); # print it decreased by one
}
print RT # output current field separator (=non-digit).
}'
Run Code Online (Sandbox Code Playgroud)
每个非数字都用作记录分隔符,并与打印语句一起重新插入。
这是python中的解决方案:
python -c 'import re,sys; print re.compile("\d+").sub(lambda i: str(int(i.group())-1),sys.stdin.read()),'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4685 次 |
| 最近记录: |