一个非常简单的任务非常复杂的标题(至少是teorically) 我希望编写一个sed脚本,在一定条件下,用匹配的第一个数字的第一个数字替换所有数字。那样:
12345成为11111
我无法弄清楚我应该在替换部分写些什么 第一个猜测是使用像这样的反射
s/([0-9])/\1/g
这匹配每个数字但当然用相同的数字替换它,因为每个匹配都是不同的,并且引用在规则上而不是匹配。我如何保留有关第一场比赛的信息,以及我们在线上更换数字?
答案 0 :(得分:4)
我认为没有简单的解决方案,如单行正则表达式替换。
假设<>
是输入中没有出现的一系列字符,您可以使用以下短sed程序
echo '1234 abc 456' | \
sed -e 's/\(^[^0-9]*\)\([0-9]\)/\1\2<>/g ; tLOOP bEND
:LOOP s/\([0-9]\)<>\([^0-9]*\)[0-9]/\1\2\1<>/g; tLOOP s/<>//g ; :END'
最初在第一个数字后插入标记<>
。如果已插入标记,则输入循环(tLOOP
),其中标记后的第一个数字被替换为前一个数字,并且标记在循环中移动数字序列。最后删除标记。
(如果前一个替换(t
)匹配,则s
命令跳转到标签。b
无条件跳转。)
如果您调试了循环(在l0;
之后使用:LOOP
命令),您将获得以下调试输出:
1<>234 abc 456$
11<>34 abc 456$
111<>4 abc 456$
1111<> abc 456$
1111 abc 1<>56$
1111 abc 11<>6$
1111 abc 111<>$
如果您更关注“如何拖动有关替换的信息”,那么您可以稍微修改上述解决方案,使其更加通用,标记成为一种“遍历背景”:
echo '1234 abc 456' | \
sed -e 's/\(^[^0-9]*\)\([0-9]\)/\1<\2>\2/g ; tLOOP bEND
:LOOP s/<\([^>]*\)>\([^0-9]*\)[0-9]/\2\1<\1>/g; tLOOP s/<[^>]*>//g ; :END'
这个信息抓取信息(第一个数字),将其放入<>
并在移动线路时保留它。调试输出将是:
<1>1234 abc 456$
1<1>234 abc 456$
11<1>34 abc 456$
111<1>4 abc 456$
1111<1> abc 456$
1111 abc 1<1>56$
1111 abc 11<1>6$
1111 abc 111<1>$
一般的想法是你可以使用替换来操纵循环中的模式空间和“遍历conext”。遍历不仅限于向右移动,也不限于一个位置等(例如,你可以用这种方式实现图灵机......)
答案 1 :(得分:2)
只需使用awk:
$ echo '1234 abc 456' | awk '{gsub(/[0-9]/,substr($0,1,1))} 1'
1111 abc 111
或者您的行可以以非数字开头:
$ echo 'foo 1234 abc 456' | awk 'match($0,/[0-9]/){gsub(/[0-9]/,substr($0,RSTART,1))} 1'
foo 1111 abc 111
使用GNU awk进行第3次arg到match()
稍微简短:
$ echo 'foo 1234 abc 456' | awk 'match($0,/[0-9]/,d){gsub(/[0-9]/,d[0])} 1'
foo 1111 abc 111
如果你想让自己弄清楚gsub()中substr()内的匹配()是什么,你也可以写:
$ echo 'foo 1234 abc 456' | awk '{gsub(/[0-9]/,substr($0,match($0,/[0-9]/),1))} 1'
foo 1111 abc 111
答案 2 :(得分:2)
这可能适合你(GNU sed):
ERROR: Target of URI does not exist: 'package:rails_ujs/rails_ujs.dart' ([dart_app] dart_app.dart:1)
使用换行符替换除第一个数字之外的所有数字(由seds定义的字符不能存在于纯粹的行中)。然后它使用一个循环来向后处理文件,用行中找到的唯一数字替换每个换行符。
答案 3 :(得分:1)
如果您对GNU Awk感到满意,可以使用以下脚本:
<强> script.awk 强>
{ if( match( $0, /^[^0-9]*([0-9])/, inf ) ) {
$0=gensub( /[0-9]/, inf[1], "g")
}
print $0
}
像这样使用:awk -f script.awk yourfile
match
函数匹配,inf[1]
inf[1]
函数gensub
中的数字
答案 4 :(得分:0)
echo '1234 abc 456' | awk '{gsub(/234|456/,"111")}1'
1111 abc 111