2010-01-20 175 views
2

我有格式的文件:Linux文本文件操作

<a href="http://www.wowhead.com/?search=Superior Mana Oil"> 
<a href="http://www.wowhead.com/?search=Tabard of Brute Force"> 
<a href="http://www.wowhead.com/?search=Tabard of the Wyrmrest Accord"> 
<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack"> 

我需要选择=之后,但在“,并在该行的末尾打印此之前的文本,将因此成为例如:

<a href="http://www.wowhead.com/?search=Superior Mana Oil">Superior Mana Oil</a> 
<a href="http://www.wowhead.com/?search=Tabard of Brute Force">Tabard of Brute Force</a> 
<a href="http://www.wowhead.com/?search=Tabard of the Wyrmrest Accord">Tabard of the Wyrmrest Accord</a> 
<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack">Tattered Hexcloth Sack</a> 

我不知道的通过Linux命令行来做到这一点(我猜大概SED/AWK但不与他们良好)的最佳方式,在理想情况下就像一个剧本,我可以只给文件名例如./fixlink.sh brokenlinks.txt

+3

尝试编写脚本并运行它。何时/如果您遇到错误,请将其发布到此处并提供帮助。 “请为我写脚本”类型的问题在这里不是很受鼓励。 – 2010-01-20 11:41:24

回答

3

假设你可以有各地的=标志之一或AFER <a更多的空间,以及零个或更多的空间,下面应该工作:

$ cat in.txt 
<a href="http://www.wowhead.com/?search=Superior Mana Oil"> 
<a href="http://www.wowhead.com/?search=Tabard of Brute Force"> 
<a href="http://www.wowhead.com/?search=Tabard of the Wyrmrest Accord"> 
<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack"> 
# 
# The command to do the substitution 
# 
$ sed -e 's#<a[ \t][ \t]*href[ \t]*=[ \t]*".*search[ \t]*=[ \t]*\([^"]*\)">#&\1</a>#' in.txt 
<a href="http://www.wowhead.com/?search=Superior Mana Oil">Superior Mana Oil</a> 
<a href="http://www.wowhead.com/?search=Tabard of Brute Force">Tabard of Brute Force</a> 
<a href="http://www.wowhead.com/?search=Tabard of the Wyrmrest Accord">Tabard of the Wyrmrest Accord</a> 
<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack">Tattered Hexcloth Sack</a> 

如果你确定你没有多余的空格中,图案被简化为:

s#<a href=".*search=\([^"]*\)">#&\1</a># 

seds后跟任意字符(#在这种情况下)开始替换。被替换的模式是直到第二次出现相同的字符。因此,在我们的第二个示例中,要替换的模式是:<a href=".*search=\([^"]*\)">。我使用\([^"]*\)来表示任何非"字符的序列,并将其保存在反向引用\1\(\)对表示反向引用)。最后,由#分隔的下一个令牌是替换。 &sed代表“无论匹配”,在这种情况下是整条线,而\1只是与链接文本相匹配。

这里再次模式:

's#<a[ \t][ \t]*href[ \t]*=[ \t]*".*search[ \t]*=[ \t]*\([^"]*\)">#&\1</a>#' 

及其说明:

如果你真的确保总是会有search=其次是你想要的,你可以在文本做:

$ sed -e 's#.*search=\(.*\)">#&\1</a>#' 

希望h ELPS。

+2

因为英勇的努力没有倒下,但是当一行代码需要14行解释时,下一个人可能会很聪明地维护它。 – 2010-01-20 12:05:06

+0

LOL @Adam:我假定OP不知道正则表达式。再加上做出“稳健”的模式,导致了长时间的解释。哦,我试过了。希望他能学到一些东西*(如果他没有厌倦我的帖子的三分之一,那就是!)。 :-) – 2010-01-20 12:08:52

+0

当我试图在这个详细程度上解释一些技术时,我通常会发现我自己学习了一些东西 - 所以这绝不是浪费精力。 – 2010-01-20 12:14:14

2
awk 'BEGIN{ FS="=" } 
{ 
    o=$NF 
    gsub(/\042>/,"",o) 
    print $0, o"</a>" 

}' file 

输出

$ ./shell.sh 
<a href="http://www.wowhead.com/?search=Superior Mana Oil"> Superior Mana Oil</a> 
<a href="http://www.wowhead.com/?search=Tabard of Brute Force"> Tabard of Brute Force</a> 
<a href="http://www.wowhead.com/?search=Tabard of the Wyrmrest Accord"> Tabard of the Wyrmrest Accord</a> 
<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack"> Tattered Hexcloth Sack</a> 

,如果你不擅长的东西,阅读了文档。这始终是解决方案的开始。要了解awk/gawk,请转至doc

0

然后让我们在sed中做。

replace.sh

#!/bin/bash 
#<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack"> 
# => 
#<a href="http://www.wowhead.com/?search=Tattered Hexcloth Sack">Tattered Hexcloth Sack</a> 
sed -r -e 's|(<a href=".*search=(.*))">|\1">\2</a>|' $1 

./replace.sh输入。TXT

0

用sed:

sed 's/\(.*search=\)\(.*\)\(".*\)/\1\2\3\2<\/a>/' brokenlinks.txt 
2

尼斯AWK!但

sed -n 's|=\([^"].*\)">|&\1</a>|p'

更短,会自动删除不匹配的行。

+0

+1使用'&'。 – 2010-01-20 12:17:28