【问题标题】:replace a string with another if a particular string is not preceding it [closed]如果特定字符串不在其前面,则用另一个字符串替换它[关闭]
【发布时间】:2017-07-06 18:08:07
【问题描述】:

如何使用 shell 脚本将多个文件中的“if”替换为“abc if”。但是我不想改变 if 之前的 else 吗?

例如:

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

应该转换成

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

请注意: 1.else和if之间可以有不定的空格或者换行。 2.文件中还有更多代码 3. 我希望更改只发生在同一个文件中。 4. 我想将文件名列表传递给脚本

我试过了:

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

【问题讨论】:

  • 中间可以换行吗?
  • 可以有更长的代码,例如{ ...; ...; ...;} ?
  • 好吧,那么你对你的问题的尝试是什么?
  • 我想做X”不是问题。

标签: shell unix awk sed


【解决方案1】:

使用 GNU awk 实现多字符 RS、gensub() 和字边界:

$ 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];

【讨论】:

    【解决方案2】:

    这是一个如何在 Perl 中模拟负变量lookbehind regex 的示例:

    #! /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;
    }
    

    输出

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

    更新

    在文件列表上使用就地编辑:

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

    然后你可以只运行p.pl file*.txt,备份文件将得到.bak后缀。

    【讨论】:

    • 能否请您更新代码,以便更改仅在同一个文件中生效,我想传递我想要这些更改的文件名列表。
    • @JayeshRanjan 您可以使用&gt;将输出重定向到终端中的文件
    • 因为我在要传递的文件中有一个文件名列表。无法使用 >
    • 你能解释一下你在脚本中使用的东西吗
    • 参见perlvar 获取$^I$/ 以及perlreperlop 获取正则表达式替换修饰符
    猜你喜欢
    • 2021-03-04
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 2015-01-26
    相关资源
    最近更新 更多