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