如何在bash中使用sed替换一个字符串的第mth到nth次出现?

问题描述 投票:1回答:3

我一直在寻找一种简单的方法来屏蔽(即用*替换)每行中给定模式的第1到第3次出现。使用 镇静剂.

输入文字的格式是: 。

$ cat input
1234 4321 2356 7890
3456 4567 8765 0981
2345 2167 9876 1234

所需的输出。

**** **** **** 7890
**** **** **** 0981
**** **** **** 1234

经过查找,我找到了将 绝无仅有 的指定模式。这里你如何替换给定输入中每行的第2块。

$ cat input | sed  's/[0-9]\{4\}/****/2'
1234 **** 2356 7890
3456 **** 8765 0981
2345 **** 9876 1234

我们也可以替换 全部出现 样式 起于 n'th发生。这是你的方法。

$ cat input | sed  's/[0-9]\{4\}/****/2g'
1234 **** **** ****
3456 **** **** ****
2345 **** **** ****

P.S 我将感激 憨厚 的解决方案。而不是具有的解决方案。锥体 或标签& 循环中 镇静剂.

sed text-processing
3个回答
1
投票

第一种解决方案。 IMHO如果你问我简单的解决方案,那么我会选择 awk. 如果你的Input_file只包含4个字段,那就简单的做,只需将值分配给3个字段即可。

awk '{$1=$2=$3="****"} 1'  Input_file

第二种解决方案。sed这可能是OP想写的方式)。使用 sed的能力,使用临时缓冲区来存储匹配的regex,并在随后用 **** 而代入。

sed 's/\([^ ]*\) \([^ ]*\) \([^ ]*\) \(.*\)/**** **** **** \4/'  Input_file

第三种解决方案。rev 打印Input_file的反面,然后只抓第一个字段(实际上是Input_file的最后一个字段),然后打印3次。**** 然后再反过来打印,这样就能打印出它的实际形式:)

rev Input_file | sed 's/\([^ ]*\).*/\1 **** **** **** ****/' | rev

第四种解决方案: 更通用的解决方案, 人们可以给出字段号的范围, 从哪个字段到哪个字段, 人们想改变值到哪一个字段 **** 然后尝试着按照(fromto 是可以由人设置的变量,根据字段号改变数值)。)

awk -v from="1" -v to="3" '{for(i=from;i<=to;i++){$i="****"}} 1' Input_file

1
投票

你问 "简单 "和 "愚蠢"。我让你自己来决定这是怎么一回事;)。GNU sed 确实支持一种模式,从 sed /../[n]g但不允许有停止范围。你可以提到 2g从第2次出现开始替换,但不能定义范围,如第1次到第3次出现。

sed -e 's/[0-9]\{4\}/****/; s/[0-9]\{4\}/****/; s/[0-9]\{4\}/****/' file

但是不承认 awk 对于这样一个微不足道的替换,就是 一个好主意。它比你想象的更有用,使用起来也更简单。


1
投票

以你的简单输入为例。

sed -r 's/([0-9]{4} ){3}/**** **** **** /' input

一个更复杂的解决方案是在 https:/unix.stackexchange.coma15581057293。.

另一种简单的解决方法(当你知道线中的nr个图案时)是

rev input | sed -r 's/[0-9]{4}/****/g2' | rev
© www.soinside.com 2019 - 2024. All rights reserved.