【问题标题】:Find and replace after n matches and before m matches with AWK在 n 个匹配之后和 m 个匹配之前使用 AWK 查找和替换
【发布时间】:2019-05-05 06:48:32
【问题描述】:

目前我正在使用 AWK 来查找和替换字符串前三个匹配项的一部分。字符串是这样格式化的,文件中有很多这样的字符串:

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

使用this link,我能够找到一种使用AWK 查找和替换字符串的前三个实例的方法。我把它改成了我需要它做的事情,我的脚本的 sn-p 如下:

id=12349876
awk '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。我尝试了以下方法,但它仍然只替换了前 5 个 tempID 实例:

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

是否有另一种方法来实现这一点,以便替换该范围的值?它不必与 AWK 一起使用,它可以与 sed 或任何其他 Linux 实用程序一起使用。

编辑:下面是线条前后的示例:

之前:

func2(blah)
func3(blah)
func(tempID="83747432",count='12');
func(tempID="83747432",count='12');
func(tempID="83747432",count='12');
func(tempID="83747432",count='12');

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

之后:

func2(blah)
func3(blah)
func(tempID="83747432",count='12');
func(tempID="83747432",count='12');
func(tempID="83747432",count='12');
func(tempID="39843237",count='12');

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

注意第三行之后的行是如何改变的,但只有第三行匹配模式.*tempID.*

【问题讨论】:

    标签: linux bash awk sed scripting


    【解决方案1】:

    根据与您的目标函数调用匹配的行用数字组成我自己的示例输入文件,以突出显示相似但不相同的行被忽略:

    $ cat file
    1 func(tempID="39849235",count='12');
    boofunc(tempID="39849235",count='12');
    2 here is one func(tempID="39849235",count='12'); right there
    func(tempID="99999999",count='12');
    func(tempID="39849235",count='123');
    3 and another:           func(tempID="39849235",count='12');
    4 func(tempID="39849235",count='12');
    5 func(tempID="39849235",count='12');
    6 func(tempID="39849235",count='12');
    boofunc(tempID="39849235",count='12');
    7 here is one func(tempID="39849235",count='12'); right there
    func(tempID="99999999",count='12');
    func(tempID="39849235",count='123');
    8 and another:           func(tempID="39849235",count='12');
    9 func(tempID="39849235",count='12');
    10 func(tempID="39849235",count='12');
    

    并使用 GNU awk 作为第三个参数来匹配():

    $ cat tst.awk
    match($0,/(.*\<func\(tempID=")39849235(",count='12'\);.*)/,a) {
        ++cnt
        if ( (cnt >= beg) && (cnt <= end) ) {
            $0 = a[1] id a[2]
        }
    }
    { print }
    

    .

    $ id=12349876
    $ awk -v id="$id" -v beg=1 -v end=3 -f tst.awk file
    1 func(tempID="12349876",count='12');
    boofunc(tempID="39849235",count='12');
    2 here is one func(tempID="12349876",count='12'); right there
    func(tempID="99999999",count='12');
    func(tempID="39849235",count='123');
    3 and another:           func(tempID="12349876",count='12');
    4 func(tempID="39849235",count='12');
    5 func(tempID="39849235",count='12');
    6 func(tempID="39849235",count='12');
    boofunc(tempID="39849235",count='12');
    7 here is one func(tempID="39849235",count='12'); right there
    func(tempID="99999999",count='12');
    func(tempID="39849235",count='123');
    8 and another:           func(tempID="39849235",count='12');
    9 func(tempID="39849235",count='12');
    10 func(tempID="39849235",count='12');
    

    .

    $ id=12349876
    $ awk -v id="$id" -v beg=4 -v end=9 -f tst.awk file
    1 func(tempID="39849235",count='12');
    boofunc(tempID="39849235",count='12');
    2 here is one func(tempID="39849235",count='12'); right there
    func(tempID="99999999",count='12');
    func(tempID="39849235",count='123');
    3 and another:           func(tempID="39849235",count='12');
    4 func(tempID="12349876",count='12');
    5 func(tempID="12349876",count='12');
    6 func(tempID="12349876",count='12');
    boofunc(tempID="39849235",count='12');
    7 here is one func(tempID="12349876",count='12'); right there
    func(tempID="99999999",count='12');
    func(tempID="39849235",count='123');
    8 and another:           func(tempID="12349876",count='12');
    9 func(tempID="12349876",count='12');
    10 func(tempID="39849235",count='12');
    

    【讨论】:

    • 您的答案与我想要的相似,但计数值和 ID 并不总是相同的,所以这不是我想要的。这是我的错,因为不够清楚,所以我会支持你的答案,但让在不同论坛回答我的问题的人在这里回答并接受他们的答案,因为该解决方案对我有用并且是我最终的解决方案一起去。尽管如此,还是感谢您花时间回答!
    • 您看不到计数值和 id 作为参数传递给程序,因此您每次调用时都可以将它们更改为您想要的任何内容?你认为-v id="$id" -v beg=4 -v end=9 是什么意思?
    • 我查看了the answer you accepted on the other forum btw,它存在一些问题,包括:1) 会错误匹配目标行以外的行,2) 在 4 个不同位置复制文本“tempID” , 3) 有基本的正则表达式问题,例如你认为/.*tempID.*/ 会匹配,只是/tempID/ 不会匹配,4)在使用它的值的测试之后增加匹配,因此强制比较的数字不是你想要的数字,5)$0 是什么默认打印,所以你可以说print,6)整个BEGIN部分是多余的。
    • 当然我可以看到 count 和 id 值作为参数传递,这不是我的意思。我的观点是 count 和 tempID 值在您的 AWK 代码中是静态的,分别指定为 39849235 和 count='12',这是我不想要的,因为我的 Python 函数不会具有相同的 tempID 和 count 值每次作为参数传递。正如我所说,我没有澄清它们会有所不同是我的错误。请更改您的答案以考虑变量 tempID 和计数值,我会接受您的答案。
    • 您的问题是要匹配的字符串是func(tempID="39849235",count='12');。我的回答回答了你的问题,除了你写的内容之外,我不知道你可能还有什么意思 - 接受这个答案(或不接受,对我来说都无关紧要),如果你的问题没有,请写一个新问题捕捉您的真实需求。
    猜你喜欢
    • 2015-04-02
    • 2019-11-23
    • 2020-08-26
    • 1970-01-01
    • 2013-02-23
    • 1970-01-01
    • 2021-06-16
    • 1970-01-01
    • 2017-01-31
    相关资源
    最近更新 更多