regex 如何用sed捕获一个数字并替换另一个?

ds97pgxw  于 2023-02-20  发布在  其他
关注(0)|答案(7)|浏览(157)

在文本文件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

我哪里做错了?

6ju8rftf

6ju8rftf1#

始终替换行中的第三位数字:

$ echo 'blabla 28.40.00 blabla' | sed 's/[0-9]/3/3'
blabla 28.30.00 blabla

如果.前面的数字可以超过2位,则有一个解决方法:

$ echo 'blabla 528.40.00 blabla' | sed 's/\.[0-9]/.3/'
blabla 528.30.00 blabla

在第二次尝试时,应该将命令引起来并使用不转义的圆括号。在捕获组后面似乎还有一个额外的1

$ echo 'blabla 28.40.00 blabla' | sed -E 's_[[:digit:]]([[:digit:]])_3\1_2'
blabla 28.30.00 blabla

另外,在这种情况下不需要awk,也可以在sed中添加filter:

$ echo 'blabla 28.40.00 blabla' | sed -E '/blabla/ s_[[:digit:]]([[:digit:]])_3\1_2'
blabla 28.30.00 blabla
roejwanj

roejwanj2#

这将匹配.“"之间的两个数字,并将第一个数字替换为3。

echo blabla 28.40.00 blabla | sed -n '/blabla/s/\.[0-9]\([0-9]\)\./.3\1./p'

退货

blabla 28.30.00 blabla
amrnrhlw

amrnrhlw3#

我认为主要的问题是表达式中的杂散1(就在_3之前)。

sed -E 's@[[:digit:]]([[:digit:]])@3\1@2'

但是sed在这方面似乎有些笨拙。你想用3位数做什么?假设你想把129改成39,你可能更喜欢不那么笨拙的:

echo 'blabla 28.129.00 blabla' | awk '/blabla/{$2 = 30 + $2 % 10}1' FS=. OFS=.

(This将更改行中的空格,您需要考虑如何处理“blabla”包含.的行,但该问题并没有给予足够的信息来了解如何处理这些情况。如果blahblah包含数字对,则sed解决方案也会出现类似的问题。)

tuwxkamq

tuwxkamq4#

首先,cat是不必要的,因为awk/sed可以直接对文件进行操作。
其次,由于您已经在使用awk,因此可以在awk中完成这项工作,而无需执行awk | sed
请考虑以下gnu-awk解决方案:

awk '/blabla/ {
   $0 = gensub(/([^0-9]*[0-9]+\.)[0-9]/, "\\13", "1")
} 1' test.txt

blabla 28.30.00 blabla

gensub函数在捕获组中匹配0个或多个非数字,后跟1+数字和点。最后,我们匹配要替换的数字。在替换中,我们使用\\1替换回原始捕获值,后跟所需的新数字,即3

a64a0gku

a64a0gku5#

由于您有许多行,并且希望替换中间数字的第一个数字,因此可以将该格式的数字与中间2个点匹配。
使用替换\13\2中的2个捕获组。

sed -E 's/([0-9]\.)[0-9]([0-9]*\.[0-9])/\13\2/' test.txt

模式匹配

  • ^字符串开始
  • ([0-9]\.)捕获组1,匹配一位数字和一个点
  • [0-9]匹配单个数字(替换)
  • ([0-9]*\.[0-9])捕获组2,匹配可选数字,然后.和一个数字

产出

blabla 28.30.00 blabla
bsxbgnwa

bsxbgnwa6#

#!/bin/sh

f1=$(echo "blabla 28.40.00 blabla" | cut -d' ' -f1)
f2=$(echo "blabla 28.40.00 blabla" | cut -d' ' -f2)
f3=$(echo "blabla 28.40.00 blabla" | cut -d' ' -f3)
mf1=$(echo "${f2}" | cut -d'.' -f1) 
mf2=$(echo "${f2}" | cut -d'.' -f2) 
mf3=$(echo "${f2}" | cut -d'.' -f3)
fixed=$(echo "${mf2}" | sed s'@.@3@')

echo "${f1} ${mf1}.${fixed}.${mf3} ${f3}" > output
c3frrgcw

c3frrgcw7#

这可能对您有用(GNU sed):

sed -E '/blabla/s/[0-9]([0-9]+)/3\1/2' file

关注包含blabla的行。
在第二次出现的两个或更多数字中,将两个或更多数字的第一个数字替换为3

相关问题