首页 > 解决方案 > awk 命令中的多个条件 + 正则表达式

问题描述

我正在使用以下 awk 命令替换 swift 源文件中的字符串:

awk '
    BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
    s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
    { print }
' "$old" "$new" "$file" > ./temp

尽量不编辑注释掉的值。至少,需要忽略以“//”开头的行,但似乎可以忽略内联注释(例如,当该行仅部分注释为"MATCH // <- Ok"or时"foo // MATCH <- Not Ok")。

就像是...

    s=index($0,old) && !($0 =~ "^//") { ... }

样本输入:

old="\"Some \(value) with %@ special \n characters\""
new="\"some_key\".localized"

file {contents}...
    /// - Returns: "Some \(value) with %@ special \n characters"
    static let someValue = "Some \(value) with %@ special \n characters" // <-- This should change

    static let otherValue = "This line does NOT change" // "Some \(value) with %@ special \n characters"

预期输出:

    /// - Returns: "Some \(value) with %@ special \n characters"
    static let someValue = "some_key".localized // <-- This should change

    static let otherValue = "This line does NOT change" // "Some \(value) with %@ special \n characters"

编辑

尽管@RavinderSingh13 的答案与预期的输出不匹配,但它很接近,我用它来修改我的命令,如下所示:

BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
s=index($0,old) { if (!(match($0,/.*\/\//))) $0 = substr($0,1,s-1) new substr($0,s+len) }
{ print }' "$old" "$new" "$file"

这符合原始要求,但忽略了任何有两个斜杠的行。这是有问题的,因为它不支持行注释(例如,上述命令不会编辑任何示例输入;除非删除“// <-- This should change”注释。如果没有人回复,我'我会用这个作为答案,但我会等一天左右,以防有人发布满足所有要求的命令版本。会接受这个答案。

会是这样的……

s=index($0,old) { if (!(match($0,/.*\/\//)) || (match($0,/"$old".*\/\//))) $0 = substr($0,1,s-1) new substr($0,s+len) }

标签: swiftregexawkzsh

解决方案


考虑到您想跳过所有从开始的行,//并且您还想打印//内联注释之间的内容。由于未提供样品,因此未测试公平警告。

awk '
    BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
    /^\/\//{ next }
    match($0,/.*\/\//){ $0 = substr($0,RSTART,RLENGTH-2) }
    s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
    { print }
' "$old" "$new" "$file" > ./temp


//如果要打印它们,上面将忽略以开头的行,然后执行以下操作。

awk '
    BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
    /^\/\//{ print; next }
    match($0,/.*\/\//){ $0 = substr($0,RSTART,RLENGTH-2) }
    s=index($0,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
    { print }
' "$old" "$new" "$file" > ./temp

推荐阅读