Sed:替代图案,不限于匹配的线条,而是另一种图案



我想用引号将多个单词括起来。使用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>
sed ":a
/having/ {
   s/"(( *'[^ ]{1,}')* *)([^ '"]{1,})([^"]*)"/"1'3'4"/
   t a
   }" YourFile

将每组单词(不是空格、引号或双引号的字符(本身替换为简单引号。使用recursif来更改在被单引号包围的所有单词组之后的双引号之间的单词。这是因为,选项g不能与反向引用一起使用,所以通过将之前引用的所有单词组成一大组,循环使用组e,直到不再有未引用的单词

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

我决定放弃只使用sed。。。我做了一件很糟糕的事情,在换人时容易出错。。。但我会在之后改变我的观点。

#!/bin/bash
O=$IFS
# For every file passed in argument
for f in "$@"
do
    IFS=$(echo -en "nb")
    # 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

最新更新