replace a string with another if a particular stri

2019-09-16 06:03发布

How to replace "if" to "abc if" in multiple file using shell scripting. But I don't want to change if when it preceded by else?

For example:

if (var3 == 4'h0)
   a =    bvec[0];
else
if (var3 == 4'h1)
a =    bvec[1];

should be converted to

abc if (var3 == 4'h0)
   a =    bvec[0];
else
if (var3 == 4'h1)
a =    bvec[1];

Please note: 1.there are can be indefinite space or a new line between else and if. 2. There are more codes present in the file also 3. I wanted the changes to occur in the same file only. 4. I want to pass a list of filename to the script

I have tried with:

sed -r 's/else[[:blank:]]if/temp1/g;s/if/abc if/g;s/temp1/else if/g' file.v

标签: shell unix awk sed
2条回答
闹够了就滚
2楼-- · 2019-09-16 06:22

Here is an example of how to simulate negative variable lookbehind regex in Perl:

#! /usr/bin/env perl

use strict;
use warnings;

my $str = do { local $/; <> };
$str =~ s/((?:else\s*if|if))/my_subst($1)/ge;
print $str;

sub my_subst {
    my $res = $_[0];
    if ( $_[0] !~ /^else/ ) {
        $res = "abc if";
    }
    return $res;
}

Output:

$ p.pl file.txt 
abc if (var3 == 4'h0)
   a =    bvec[0];
else
if (var3 == 4'h1)
a =    bvec[1];

Update:

To use inplace-edit on a list of files:

$^I = '.bak';
$/ = undef;
while (<>) {
    s/((?:else\s*if|if))/my_subst($1)/ge;
    print;
}

Then you can just run p.pl file*.txt and the backup files will get .bak suffix.

查看更多
再贱就再见
3楼-- · 2019-09-16 06:42

WIth GNU awk for multi-char RS, gensub(), and word boundaries:

$ awk -v RS='^$' -v ORS= '{
    gsub(/@/,"@A")
    gsub(/#/,"@B")
    $0 = gensub(/\<else(\s+)if\>/,"#\\1#","g")
    gsub(/\<if\>/,"abc &")
    $0 = gensub(/#(\s+)#/,"else\\1if","g")
    gsub(/@B/,"#")
    gsub(/@A/,"@")
    print
}' file
abc if (var3 == 4'h0)
   a =    bvec[0];
else
if (var3 == 4'h1)
a =    bvec[1];
查看更多
登录 后发表回答