Управление текстовыми файлами в Linux - PullRequest
2 голосов
/ 20 января 2010

У меня есть файл формата:

<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

Ответы [ 5 ]

3 голосов
/ 20 января 2010

Предполагая, что вы можете иметь один или несколько пробелов после <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>#

В sed, s, за которым следует любой символ (в данном случае #), начинается замена. Подставляемый шаблон - до второго появления того же персонажа. Итак, во втором примере, шаблон для замены: <a href=".*search=\([^"]*\)">. Я использовал \([^"]*\) для обозначения любой последовательности, отличной от " символов, и сохранил ее в обратной ссылке \1 (пара \(\) обозначает обратную ссылку). Наконец, следующий токен, ограниченный #, является заменой. & в sed означает «что соответствует», в данном случае это целая строка, а \1 соответствует тексту ссылки.

Вот снова образец:

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

и его объяснение:

'                       quote so as to avoid shell interpreting the characters
s                       substitute
#                       delimiter
<a[ \t][ \t]*           <a followed by one or more whitespace
href[ \t][ \t]*=[ \t]*  href followed by optional space, = followed by optional space
".*search[ \t]*=[ \t]*  " followed by as many characters as needed, followed by
                        search, optional space, =, followed by optional space
\([^"]*\)               a sequence of non-" characters, saved in \1
">                      followed by ">
#                       delimiter, replacement pattern starts
&\1                     the matched pattern, followed by backreference \1.
</a>                    end the </a> tag
#                       end delimiter
'                       end quote

Если вы действительно уверены, что всегда будет search=, за которым следует текст, который вы хотите, вы можете сделать:

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

Надеюсь, это поможет.

2 голосов
/ 20 января 2010

Хороший awk!Но

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

короче и удаляет несоответствующие строки.

2 голосов
/ 20 января 2010
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 голосов
/ 20 января 2010

Используйте sed:

sed 's/\(.*search=\)\(.*\)\(".*\)/\1\2\3\2<\/a>/' brokenlinks.txt
0 голосов
/ 20 января 2010

тогда давайте сделаем это в седе.

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 input.txt

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...