如果特定行之间不存在,则在文件中的一行上设置键值,或者设置特定值

如果特定行之间不存在,则在文件中的一行上设置键值,或者设置特定值

给定以下配置文件:

    shape {
        visible: true
        type: rectangle
        ...
    }
    
    shape {
        type: circle
        visible: isRound === "true"
        ...
    }
    
    shape {
        // comment: "visible" not set, default "true" 
    }

如何设置使用键(属性)bash的所有值to ,而不触及注释,但保留旧值作为注释?新内容应该是:visiblefalse

    shape {
        visible: false
        type: rectangle
        ...
    }
    
    shape {
        type: circle
        visible: false // visible: isRound === "true"
        // ideally, above, the old value is kept as a comment...
        ...
    }
    
    shape {
        visible: false
        // comment: "visible" not set, default "true" 
    }

该文件不仅仅是shape结构列表,还可能包含其他条目。这应该是质量管理语言符合。

awk显示:

awk --version
GNU Awk 5.2.1, API 3.2
Copyright (C) 1989, 1991-2022 Free Software Foundation.

编辑

我想我可以用这个PCRE regex

(\s*shape\s*\{\n)(\s*)(.*?)(visible\:.*\n?)?(.*?)(\n\s*\})

替换表达式为:

$1$2visible: false // $4\n$2$5$6

或者

\1\2visible: false // \4\n\2\5\6

但我需要一个工具来应用它。它并不完美,仍然需要不要评论两次。

答案1

我会用于perl这种事情:

perl -0777 -pe '
  s{shape\s*\{.*?\}}{
    $& =~ s{(//.*)|\b(visible:\s*+)(?!true\s*$).*}{$1 ? $1 : "${2}true // $&"}gmre
  }gse' your-file

答案2

awk -v key='visible:' -v value='false' '
    /{/ {
        found=0 # reset flag
    }
    $1==key {
        found=1 # set flag
        
        # change true to value
        if ($2=="true") { sub($2, value, $0) }

        # if not value, replace property with key-value and comment
        else if ($2!=value) { sub($1, $1 " " value " // " $1, $0) }
    }
    /}/ && !found {
        # get indentation of }
        indent=$0; sub(/}.*/, "", indent)
        
        # insert property
        print indent indent key " " value
    }
    { print }
' file

您的属性/评论中不得有任何其他开头{或结尾,}否则插入将不起作用。它们还必须出现在不同的行上。

在关闭之前插入缺失的属性},并将缩进设置为 的缩进的两倍}。我不确定这是否总是正确的或如何确定它(两个选项卡?)。

如果某个属性已经具有正确的值,则保持不变。

如果您不想在注释中重复属性名称,请将命令更改为sub($1, $1 " " value " //", $0)。结果将是visible: false // isRound === "true"

输出:

    shape {
        visible: false
        type: rectangle
        ...
    }
    
    shape {
        type: circle
        visible: false // visible: isRound === "true"
        ...
    }
    
    shape {
        // comment: "visible" not set, default "true" 
        visible: false
    }

相关内容