gpt4 book ai didi

bash - 使用 sed 将字符范围的所有其他匹配项替换为该范围内行中的第一个字符

转载 作者:行者123 更新时间:2023-11-29 09:35:07 28 4
gpt4 key购买 nike

一个非常简单的任务的非常复杂的标题(至少在理论上)我希望编写一个 sed 脚本,在特定条件下,用第一个匹配的数字的第一个数字替换所有数字。这样:

12345 变成 11111

我不知道我应该在替换部分写什么第一个猜测是使用这样的反向引用

s/([0-9])/\1/g

这匹配每个数字,但当然,用相同的数字替换它,因为每个匹配都是不同的,并且引用在规则上而不是匹配上。我怎样才能保留有关第一个匹配项的信息,并用它来替换行中后面的数字?

最佳答案

我认为没有像一行正则表达式替换这样简单的解决方案。

假设 <> 是您输入中不出现的字符序列,您可以使用以下简短的 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>$

一般的想法是,您可以使用替换来操纵循环中的模式空间和“遍历上下文”。遍历不限于向右移动或移动一个位置等。(例如,您可能可以通过这种方式实现图灵机..​​....)

关于bash - 使用 sed 将字符范围的所有其他匹配项替换为该范围内行中的第一个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37632197/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com