我想用引号将多个单词括起来。使用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 '"e;' | 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]+)/"e;1"e;/g')/" $f -i
done
IFS=$O
done