【问题标题】:multiple conditions + regex in awk commandawk 命令中的多个条件 + 正则表达式
【发布时间】:2020-09-20 01:36:05
【问题描述】:

我正在使用以下 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

尽量不编辑注释掉的值。至少,需要忽略以“//”开头的行,但似乎可以忽略内联 cmets(例如,当行仅部分注释时,如 "MATCH // <- Ok""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"

这符合原始要求,但会忽略任何包含两个斜杠的行。这是有问题的,因为它不支持行内 cmets(例如,上述命令不会编辑任何示例输入;除非删除“//

应该是这样的……

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

【问题讨论】:

  • 请在您的问题中添加示例输入(无描述、无图像、无链接)以及该示例输入所需的输出(无评论)。
  • 还有你的意思是说你不想在//之后得到值,请确认一下。
  • @RavinderSingh13,是的,如果它位于斜线的右侧(已注释掉),我不想更改它,但如果它位于斜线的左侧(不是注释掉)。
  • @Cyrus 我刚刚添加了一些示例输入/输出

标签: swift regex awk zsh


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    仅在每行注释开始前的部分中查找“旧”,例如:

    awk '
        BEGIN { old=ARGV[1]; new=ARGV[2]; ARGV[1]=ARGV[2]=""; len=length(old) }
        { preCmt = $0; sub("//.*","", preCmt) }
        s=index(preCmt,old) { $0 = substr($0,1,s-1) new substr($0,s+len) }
        { print }
    ' "$old" "$new" file
        /// - 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
    

    【讨论】:

      猜你喜欢
      • 2021-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-22
      • 2015-05-03
      • 1970-01-01
      • 2014-09-15
      • 1970-01-01
      相关资源
      最近更新 更多