Использование синтаксического анализатора XML — действительно хорошая идея, но если вы не можете его использовать по какой-либо причине, (файл неправильно -сформирован, у вас не установлены какие-либо синтаксические анализаторы и т. д. )], вы можете использовать для этого PERL:
$ perl -ne 'if(/<h2>(.*?)<\/h2><p>(.*?)<\/p>/){print "$1\t$2\n"}' filename.ext
Hello World
Bells Walls
Jelly Minus
Я предпочитаю использовать ленивые совпадения, чтобы не получить непредвиденных результатов:
test.txt
<h1>Nothing</h1>
<h2>Hello</h2><p>World</p><h2>Goodbye</h2><p>Earth</p>
<h2>Bells</h2><p>Walls</p>
<h2>Jelly</h2><p>Minus</p>
<h3>Zip</h3>
$ perl -ne 'if(/<h2>(.*?)<\/h2><p>(.*?)<\/p>/){print "$1\t$2\n"}' test.txt
Hello World
Bells Walls
Jelly Minus
$ perl -ne 'if(/<h2>(.*)<\/h2><p>(.*)<\/p>/){print "$1\t$2\n"}' test.txt
Hello</h2><p>World</p><h2>Goodbye Earth
Bells Walls
Jelly Minus
Как вы можете видеть, только использование регулярного выражения не позволит получить все случаи, которые можно получить с помощью инструмента, специфичного для предметной области -. Если вы согласны с этим, то все в порядке; просто имейте в виду, что вы можете получить неточные результаты, если ввод не соответствует точно вашему шаблону!
Технически любое выражение может отображаться как индекс. Проблема заключается в том, чтобы парсер поместил то, что вы хотите, в индекс. Некоторые символы, в том числе пробелы, никогда не появляются. Только символы, составляющие слово, могут быть частью нижнего индекса, потому что нижний индекс является частью слова.
mc% echo $arr[ 1]
zsh: invalid subscript
mc% echo $arr[1 ]
zsh: invalid subscript
mc% echo $arr[$#arr - 1]
zsh: invalid subscript
mc% echo $arr[$#arr-1]
d
Синтаксический анализатор нижнего индекса останавливается на первом недопустимом символе, и ошибка «недопустимый нижний индекс» возникает еще до того, как zsh проверит завершающую закрывающую скобку.
mc% echo $arr[ 1
zsh: invalid subscript
В echo $arr[ 1]
часть после пробела фактически считается отдельным словом.:echo
получит два аргумента, являющихся результатом расширения $arr[
и 1]
, за исключением того, что zsh не начинает выполнение какой-либо команды из-за к сбою разбора.Есть несколько случаев, когда вы можете сказать, что то, что вы можете представить как часть арифметического выражения, на самом деле не анализируется как таковое, например:
mc% echo $arr[1<<2]
heredoc> << is a heredoc operator, not part of the subscript.
heredoc> 2]
zsh: invalid subscript
Символы, не составляющие -слова -, могут, конечно, проникать как часть вложенного расширения, такого как арифметическое выражение или подстановка команды.
mc% echo $arr[$[1&3]]
a
mc% echo $arr[`echo "1 + 2"`]
c
Если расширение параметра заключено в двойные кавычки, любой символ (, кроме сбалансированной закрывающей скобки или концевой кавычки ), проходит через индекс и становится частью нижнего индекса. Это потому, что внутри двойных кавычек любой символ фактически является символом, составляющим слово. Аналогичным образом, если расширение параметра использует фигурные скобки, zsh ищет закрывающую фигурную скобку }
для раскрытия параметра, прежде чем искать закрывающую скобку ]
для нижнего индекса, и поэтому символы, не составляющие -слова -, делают его в нижний индекс.
mc% echo "$arr[$#arr - 1]"
d
mc% echo ${arr[$#arr - 1]}
d
Если вы хотите углубиться в мельчайшие -детали, соответствующая функцияparse_subscript
вызывается изgetindex
.