【问题标题】:Sed: substitute pattern, not limited to matching line, but to another patternsed:替代模式,不限于匹配行,而是到另一个模式
【发布时间】:2014-08-01 21:06:59
【问题描述】:

我想用引号括住多个单词。 使用 sed 和分组轻松完成任务。

除了我的话位于xml标签的一个属性中。

<daddy>
    <son name="blabla">
        <belongs having="car cat doll" color="yellow" />
    </son>
</daddy>

我希望将having 属性后处理为"'car' 'cat' 'doll'"having 是唯一受影响的属性名称。 所以,只匹配这个词没有危险,它会自动成为belongs标签的一部分。 我认为这是一个能够在这里使用 sed 的良好开端,并且不要使用繁重的工具和 xml 阅读器来做艰苦的事情。

我的第一次尝试是匹配模式以过滤行,并尝试包围单词。但它围绕着它们,在整行中匹配,而不仅仅是在第一个模式中。这正是我想要的。

sed "/having=\"[a-z ]\+\"/ s/\([a-z]\+\)/'\1'/g"

.

<daddy>
    <son name="blabla">
        <'belongs' 'having'="'car' 'cat' 'doll'" 'color'="'yellow'" />
    </son>
</daddy>

我的第二次尝试,组匹配让我不再走得更远......

sed "s/havings=\"\(\([a-z]\+\) \?\)*\"/havings=\"'\2'\"/g"

.

<daddy>
    <son name="blabla">
        <belongs having="'doll'" color="yellow"/>
    </son>
</daddy>

【问题讨论】:

    标签: xml sed substitution


    【解决方案1】:
    sed ":a
    /having/ {
       s/\"\(\( *'[^ ]\{1,\}'\)* *\)\([^ '\"]\{1,\}\)\([^\"]*\)\"/\"\1'\3'\4\"/
       t a
       }" YourFile
    

    用简单的引号将每组单词(不是空格或引号或双引号的字符)替换为自身。在所有由简单引号包围的单词组之后,使用递归来更改双引号之间的单词。这是因为,选项 g 不能与反向引用一起使用,因此通过取一大组之前引用的所有单词来解决使用 groupe 的问题,循环直到没有更多未引用的单词

    我假设内容在 1 行(因为 sed 默认行为)并且与 having 在同一行

    【讨论】:

    • 我对您的 sed 技能感到惊讶...我还有很多东西要学!问题是您的命令会影响所有双引号字段。而且我的示例没有提到它(我的不好),但该行中可能还有其他属性。不过,您对其他事情的假设很好。谢谢 !我编辑我的问题。
    • 抱歉,正在放假(八月中旬),现在有点赶时间,所以我没有时间适应。我认为在子组中排除" 的小调整将解决问题(并在第一部分中包含having= 以隔离该行的其余部分)就足够了
    【解决方案2】:

    我决定放弃只使用 sed... 我做了一些很糟糕的事情,而且往往会在替换时产生错误...... 但我会在之后区分我的输出。

    #!/bin/bash
    
    O=$IFS
    
    # For every file passed in argument
    for f in "$@"
    do
        IFS=$(echo -en "\n\b")
        # For every field content
        for p in $(egrep -o 'having="[^"]*"' $f | egrep -o '".*"' | grep -v '&quote;' | sort -u);
        do
            # Match every occurrence of this content on the lines of "having" and surround its words
            sed "/having/ s/$p/$(echo $p | sed 's/\([a-z]\+\)/\&quote;\1\&quote;/g')/" $f -i
        done
        IFS=$O
    done
    

    【讨论】:

      猜你喜欢
      • 2021-04-02
      • 1970-01-01
      • 1970-01-01
      • 2014-08-19
      • 1970-01-01
      • 2016-12-17
      • 1970-01-01
      • 1970-01-01
      • 2018-04-30
      相关资源
      最近更新 更多