在文本文件test.txt中有许多行文本,我想从中提取一行匹配:
blabla 28.40.00 blabla
我想把中间数字的第一位数字(在这个例子中是4)换成3,也就是说,无论中间数字是什么(40、41、52、63等),我都想把它换成以3开头的数字(40变成30、41变成31、52变成32、63变成33等)。
下面的行匹配中间的数字,并将其替换为数字3
:
cat test.txt |awk '/blabla/'|sed -E s_[[:digit:]][[:digit:]]_3_2
output: blabla 28.3.00 blabla
但是当我只想替换第一个数字时,sed就不起作用了:
cat test.txt |awk '/blabla/'|sed -E s_[[:digit:]]\([[:digit:]]\)1_3\1_2
output: blabla 28.40.00 blabla
我哪里做错了?
7条答案
按热度按时间6ju8rftf1#
始终替换行中的第三位数字:
如果
.
前面的数字可以超过2位,则有一个解决方法:在第二次尝试时,应该将命令引起来并使用不转义的圆括号。在捕获组后面似乎还有一个额外的
1
。另外,在这种情况下不需要
awk
,也可以在sed
中添加filter:roejwanj2#
这将匹配.“"之间的两个数字,并将第一个数字替换为3。
退货
amrnrhlw3#
我认为主要的问题是表达式中的杂散
1
(就在_3
之前)。但是
sed
在这方面似乎有些笨拙。你想用3位数做什么?假设你想把129改成39,你可能更喜欢不那么笨拙的:(This将更改行中的空格,您需要考虑如何处理“blabla”包含
.
的行,但该问题并没有给予足够的信息来了解如何处理这些情况。如果blahblah
包含数字对,则sed
解决方案也会出现类似的问题。)tuwxkamq4#
首先,
cat
是不必要的,因为awk/sed
可以直接对文件进行操作。其次,由于您已经在使用
awk
,因此可以在awk
中完成这项工作,而无需执行awk | sed
。请考虑以下
gnu-awk
解决方案:此
gensub
函数在捕获组中匹配0个或多个非数字,后跟1+数字和点。最后,我们匹配要替换的数字。在替换中,我们使用\\1
替换回原始捕获值,后跟所需的新数字,即3
。a64a0gku5#
由于您有许多行,并且希望替换中间数字的第一个数字,因此可以将该格式的数字与中间2个点匹配。
使用替换
\13\2
中的2个捕获组。模式匹配
^
字符串开始([0-9]\.)
捕获组1,匹配一位数字和一个点[0-9]
匹配单个数字(替换)([0-9]*\.[0-9])
捕获组2,匹配可选数字,然后.
和一个数字产出
bsxbgnwa6#
c3frrgcw7#
这可能对您有用(GNU sed):
关注包含
blabla
的行。在第二次出现的两个或更多数字中,将两个或更多数字的第一个数字替换为
3
。