使用 AWK 将给定数量的匹配项替换为单独的行

使用 AWK 将给定数量的匹配项替换为单独的行

目前,我正在使用 AWK 查找并替换字符串中某个模式前三次出现后的部分。该字符串的格式如下:func(tempID="39849235",count='12');,文件中有许多这样的字符串,如下所示:

func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');
func(tempID="39849235",count='12');

使用此链接,我找到了一种使用 AWK 查找和替换字符串前三个实例的方法。我将其更改为我需要它执行的操作,我的脚本片段如下:

id=12349876
awk -v id="$id" 'BEGIN {matches=0}
     matches < 3 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id"\""); matches++ }
     { print $0 }' filName.py >filName.py.changed

上述代码的目的是匹配任何包含 tempID 的行,并将分配给 tempID 的数字替换为名为 的变量中保存的值$id。查找和替换工作正常,但现在我想用不同的数字替换实例 4-9。我尝试了以下方法,但它仍然只替换了 tempID 的前 5 个实例:

id2=39843237
awk -v id2="$id2" 'BEGIN {matches=4}
     matches < 9 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id2"\""); matches++ }
     { print $0 }' filName.py >filName.py.changed

有没有其他方法可以实现这一点,以便替换该范围的值?不一定非要使用 AWK,可以使用 sed 或任何其他 Linux 实用程序。此外,解决方案不一定必须在某个点结束,并且可以替换第三行之后的所有实例,但如果有可以做到这一点的解决方案,那将是一个加分项。

答案1

您的matches=4matches < 9的意思是“假设已经有 4 个匹配,然后执行直到总共有 9 个”。这就是前 5 个实例被替换的原因。您需要像以前一样从 0 开始,然后将下限纳入逻辑中:

id2=39843237
awk -v id2="$id2" 'BEGIN {matches=0}
 matches >=3 && matches < 9 && /.*tempID.*/ { sub(/tempID=.[0-9]+./,"tempID=\""id2"\"") }
 /.*tempID.*/ { matches++ }
 { print $0 }' filName.py >filName.py.changed

注意,您需要根据 的值进行替换matches,但每次匹配时都需要增加此值。您的原始代码替换了文本并增加了一个块中的值。当由于matches太高而没有替换时,该值不会进一步增加,但这不再重要。现在你不能用这种简单的方法了。当由于 而没有替换matches太低,如果找到匹配的字符串,则仍然需要增加该值。

因此,这两个{}区块具有不同的条件。

相关内容