我想用相等数量的X替换标签之间的值。例如
1
<Name> Jason </Name>
to
<Name> XXXXX </Name>
2。 (见无空间)
<Name>Jim</Name>
to
<Name>XXX</Name>
3
<Name Jason />
to
<Name XXXXX />`
4
<Name Jas />
to
<Name XXX />
开始标记,值和结束标记都可以有不同的行
5
<Name>Jim
</Name>
to
<Name>XXX
</Name>
6
<Name>
Jim
</Name>
to
<Name>
XXX
</Name>
7
<Name
Jim
/>
to
<Name
XXX
/>
8
<Name> Jason </Name> <Name> Ignacio </Name>
to
<Name> XXXXX </Name> <Name> XXXXXX </Name>
9
<Name> Jason Ignacio </Name>
to
<Name> XXXXX XXXXXXX </Name>
or
<Name> XXXXXXXXXXXXX </Name>
两者都很好
我尝试了这个,但它没有用
file=mylog.log
search_str="<Name>"
end_str="</Name>"
sed -i -E ':a; s/('"$search_str"'X*)[^X'"$end_str"']/\1X/; ta' "$file"
请告诉我如何在bash脚本中执行此操作....
更新
我也尝试了这个,但没有为6和7个案件工作。案例1至5工作。
sed -i -E '/<Name>/{:a; /<\/Name>/bb; n; ba; :b; s/(<Name>X*)[^X\<]/\1X/; tb; }' "$file"
sed -i -E '/<Name[[:space:]]/{:a; /\/>/bb; n; ba; :b; s/(<Name[[:space:]]X*)[^X\/]/\1X/; tb; }' "$file"
答案 0 :(得分:3)
这扩展了首次提供的产品。下面并处理案例1,2,5,6,8,9。它不处理存在一个或多个完整<Name>…</Name>
条目以及没有匹配{{1}的起始<Name>
的情况在同一行。坦率地说,我甚至不确定如何开始解决这个问题。
未处理的案例3,4,7不是有效的XML - 我也不相信它们是有效的HTML(或XHTML)。我相信它们可以通过类似(但更简单)的机制来处理完全</Name>
版本所示的机制。我将此作为练习留给读者(请注意角色类中的<Name>…</Name>
- 它需要成为<
)。
/
script.sed
第一行&#39;跳过&#39;处理不包含/<Name>/! b
/<Name>.*<\/Name>/{
: l1
s/\(<Name>[[:space:]]*\(X[X[[:space:]]*\)\{0,1\}\)[^X<[:space:]]\(.*[[:space:]]*<\/Name>\)/\1X\3/
t l1
b
}
/<Name>/,/<\/Name>/{
# Handle up to 4 lines to the end-name tag
/<\/Name>/! N
/<\/Name>/! N
/<\/Name>/! N
/<\/Name>/! N
# s/^/ZZ/; s/$/AA/p
# s/^ZZ//; s/AA$//
: l2
s/\(<Name>[[:space:]]*\(X[X[[:space:]]*\)\{0,1\}\)[^X<[:space:]]\(.*[[:space:]]*<\/Name>\)/\1X\3/
t l2
}
的行(它们被打印并读取下一行)。接下来的6行是来自&#39;首次提供的剧本&#39;除了有一个<Name>
跳到处理结束。
新部分是b
代码。这将自己查找/<Name>/,/<\/Name>/
,并连接最多4行,直到模式空间中包含<Name>
。这两条注释行用于调试 - 它们让我可以看到被视为一个单元的内容。除了使用标签</Name>
代替l2
之外,其余部分与首次提供时完全相同 - l1
正则表达式已经适应新行。
这是重型sed
脚本,而不是我想要使用或维护的脚本。我会使用一个使用XML解析器的Perl解决方案(因为我比Python更了解Perl),但Python也可以通过适当的XML解析器完成工作。
sed
略微扩展的数据文件。
data
没有声称<Name> Jason </Name>
<Name>Jim</Name>
<Name> Jason Bourne </Name>
<Name> Elijah </Name> <Name> Dennis </Name>
<Name> Elijah Wood </Name> <Name> Dennis The Menace </Name>
<Name>Elijah Wood</Name> <Name>Dennis The Menace</Name>
<Name> Jason
</Name>
<Name>
Jim</Name>
<Name>
Jim
</Name>
<Name> Jason
Bourne </Name>
<Name>
Jason
Bourne
</Name>
<Name> Elijah </Name>
<Name>
Dennis
</Name>
<Name> Elijah
Wood </Name>
<Name> Dennis
The Menace </Name>
<Name>Elijah
Wood</Name>
<Name>Dennis The
Menace</Name>
<Name> Jason </Name>
to
<Name> XXXXX </Name>
2. (see no space)
<Name>Jim</Name>
to
<Name>XXX</Name>
3.
<!--Name Jason /-->
to
<!--Name XXXXX /-->`
4.
<!--Name Jas /-->
to
<!--Name XXX /-->
starting tag, value and closing tag can all come in different line
5.
<Name>Jim
</Name>
to
<Name>XXX
</Name>
6.
<Name>
Jim
</Name>
to
<Name>
XXX
</Name>
7.
<!--Name
Jim
/-->
to
<!--Name
XXX
/-->
8.
<Name> Jason </Name> <Name> Ignacio </Name>
to
<Name> XXXXX </Name> <Name> XXXXXX </Name>
9.
<Name> Jason Ignacio </Name>
to
<Name> XXXXX XXXXXXX </Name>
or
<Name> XXXXXXXXXXXXX </Name>
文件包含最少的案例;这是重复的。它包括问题的材料,除了非正统的&#39;像data
这样的XML元素将转换为XML注释<Name Value />
。映射实际上并不重要;开场部分与<!--Name Value /-->
不匹配(并且尾部与<Name>
不匹配),因此无论如何都不会处理它们。
</Name>
部分答案 - 但它说明了您面临的问题。处理案件1&amp;在问题2中,加上多字变体,您可以使用脚本:
$ sed -f script.sed data
<Name> XXXXX </Name>
<Name>XXX</Name>
<Name> XXXXX XXXXXX </Name>
<Name> XXXXXX </Name> <Name> XXXXXX </Name>
<Name> XXXXXX XXXX </Name> <Name> XXXXXX XXX XXXXXX </Name>
<Name>XXXXXX XXXX</Name> <Name>XXXXXX XXX XXXXXX</Name>
<Name> XXXXX
</Name>
<Name>
XXX</Name>
<Name>
XXX
</Name>
<Name> XXXXX
XXXXXX </Name>
<Name>
XXXXX
XXXXXX
</Name>
<Name> XXXXXX </Name>
<Name>
XXXXXX
</Name>
<Name> XXXXXX
XXXX </Name>
<Name> XXXXXX
XXX XXXXXX </Name>
<Name>XXXXXX
XXXX</Name>
<Name>XXXXXX XXX
XXXXXX</Name>
<Name> XXXXX </Name>
to
<Name> XXXXX </Name>
2. (see no space)
<Name>XXX</Name>
to
<Name>XXX</Name>
3.
<!--Name Jason /-->
to
<!--Name XXXXX /-->`
4.
<!--Name Jas /-->
to
<!--Name XXX /-->
starting tag, value and closing tag can all come in different line
5.
<Name>XXX
</Name>
to
<Name>XXX
</Name>
6.
<Name>
XXX
</Name>
to
<Name>
XXX
</Name>
7.
<!--Name
Jim
/-->
to
<!--Name
XXX
/-->
8.
<Name> XXXXX </Name> <Name> XXXXXXX </Name>
to
<Name> XXXXX </Name> <Name> XXXXXX </Name>
9.
<Name> XXXXX XXXXXXX </Name>
to
<Name> XXXXX XXXXXXX </Name>
or
<Name> XXXXXXXXXXXXX </Name>
$
script.sed
这是相当扭曲的,对它有礼貌。它查找/<Name>.*<\/Name>/{
: l1
s/\(<Name>[[:space:]]*\(X[X[[:space:]]*\)\{0,1\}\)[^X<[:space:]]\(.*[[:space:]]*<\/Name>\)/\1X\3/
t l1
}
后跟零个或多个空格。接下来可以是<Name>
,这意味着出现0或者一次X后跟一系列X或空格。所有这些都在替换中被捕获为\(X[X[[:space:]]*\)\{0,1\}
。然后,单个字符不是\1
,X
或空格,后跟零个或多个任何字符,零个或多个空格,以及<
。中间的单个字符由X替换。重复整个替换,直到通过标签</Name>
和条件分支: l1
没有更多匹配。所有这些只能在同时包含t l1
和<Name>
的行中运行。
</Name>
data
<Name> Jason </Name>
<Name>Jim</Name>
<Name> Jason Bourne </Name>
<Name> Elijah </Name> <Name> Dennis </Name>
<Name> Elijah Wood </Name> <Name> Dennis The Menace </Name>
<Name>Elijah Wood</Name> <Name>Dennis The Menace</Name>
<Name> Jason
</Name>
<Name>
Jim</Name>
<Name> Jason
Bourne </Name>
<Name> Elijah </Name> <Name> Dennis
</Name>
<Name> Elijah
Wood </Name> <Name> Dennis
The Menace </Name>
<Name>Elijah
Wood</Name> <Name>Dennis The
Menace</Name>
注意更换部分到最后。这条线将导致更多的麻烦。
我还没有弄清楚脚本如何处理各种分割线情况,除了它几乎肯定需要连接线,直到$ sed -f script.sed data
<Name> XXXXX </Name>
<Name>XXX</Name>
<Name> XXXXX XXXXXX </Name>
<Name> XXXXXX </Name> <Name> XXXXXX </Name>
<Name> XXXXXX XXXX </Name> <Name> XXXXXX XXX XXXXXX </Name>
<Name>XXXXXX XXXX</Name> <Name>XXXXXX XXX XXXXXX</Name>
<Name> Jason
</Name>
<Name>
Jim</Name>
<Name> Jason
Bourne </Name>
<Name> XXXXXX </Name> <Name> Dennis
</Name>
<Name> Elijah
Wood </Name> <Name> Dennis
The Menace </Name>
<Name>Elijah
Wood</Name> <Name>Dennis The
Menace</Name>
$
被捕获。然后它会处理与已经显示的处理密切相关的处理,但它需要允许匹配材料中的换行符。
答案 1 :(得分:1)
试试这个python脚本:
$ cat script.py
#!/usr/bin/python
import re
from bs4 import BeautifulSoup
soup = BeautifulSoup(open('allcases'), features="xml")
for tag in soup.findAll('Name'):
for name in 'Jason Ignacio', 'Jason', 'Jim':
tag.string = re.sub(r'\b%s\b' % name, len(name)*'X', tag.string)
print(str(soup))
此代码与python2或python3兼容。
要使其正常工作,您可能需要安装BeautifulSoup模块。在类似debian的系统上:
apt-get install python-bs4
或者,对于python3:
apt-get install python3-bs4
让我们考虑一下这个输入文件:
$ cat cases
<page>
<p>Jason</p>
<Name> Jason </Name>
<p>Jason</p>
<Name>Jim</Name>
<p>Jim</p>
<Name>Jim
</Name>
<Name>
Jim
</Name>
<Name> Jason </Name> <Name> Ignacio </Name>
<Name> Jason Ignacio </Name>
</page>
让我们运行我们的脚本并观察输出:
$ python script.py
<?xml version="1.0" encoding="utf-8"?>
<page>
<p>Jason</p>
<Name> XXXXX </Name>
<p>Jason</p>
<Name>XXX</Name>
<p>Jim</p>
<Name>XXX
</Name>
<Name>
XXX
</Name>
<Name> XXXXX </Name> <Name> Ignacio </Name>
<Name> XXXXXXXXXXXXX </Name>
</page>
请注意,<p>
标记中的名称是单独的。该代码仅更改<Name>
代码中的名称。
此外,根据设计,Jim
,Jason
和Jason Ignacio
更改为X,但其他名称保持不变。即使伊格纳西奥,如果它没有相邻的杰森,也会被单独留下。