Sed:替代模式,不限于匹配线,而是另一种模式

时间:2014-08-01 07:45:14

标签: xml sed substitution

我想用引号括住多个单词。 使用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>

2 个答案:

答案 0 :(得分:1)

sed ":a
/having/ {
   s/\"\(\( *'[^ ]\{1,\}'\)* *\)\([^ '\"]\{1,\}\)\([^\"]*\)\"/\"\1'\3'\4\"/
   t a
   }" YourFile

将每个单词组(不是空格或引号或双引号的单词)单独替换为简单引号。使用recursif来更改在简单引号包围的所有单词组之后的双引号之间的单词。这是因为,选项g不能与后向引用一起使用,因此通过使用之前引用的所有单词的大组来循环使用groupe,循环直到不再是不带引号的单词

我假设内容在1行(因为sed默认行为)和having

相同的行

答案 1 :(得分:0)

我决定放弃使用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