#regex #awk #sed #grep
#регулярное выражение #awk #sed #grep
Вопрос:
Я пытаюсь извлечь текст из большого файла, однако меня интересует только текст между двумя шаблонами.
Пример текста выглядит следующим образом:
<account>0409</account><name>Charles</name><type>R</type><accountStatus>active</accountStatus>
Моим желаемым результатом должен быть только текст в теге name, ничего до и ничего после. В примере:
Вывод: Чарльз
В этом случае начальным шаблоном является <name>
, а конечным шаблоном </name>
Как я могу добиться этого с помощью grep / sed / awk?
Комментарии:
1.
sed -n 's/^ *<name>(.*)</name> *$/1/p'
2. Я получаю следующий ответ: sed: -e выражение # 1, символ 46: Непревзойденный (или (
3. Второй вариант не экранирован.
4.
sed -n 's/^.*<name>(.*)</name>.*$/1/p'
Ответ №1:
Использование GNU awk для RS с несколькими символами:
$ awk -v RS='</?name>' '!(NR%2)' file
Charles
Вышеуказанное будет работать независимо от того, есть ли где-либо во входном файле новые строки или нет, и независимо от того, сколько раз <name>...</name>
появляется в одной строке или разбивается на строки, требуется только, чтобы <name>
и </name>
всегда отображались как пары во входном файле:
$ cat file
<name>Charles</name><name>William</name>
<name>Edward
</name>
<name> John Boy Walton </name>
$ awk -v RS='</?name>' '!(NR%2)' file
Charles
William
Edward
John Boy Walton
и если вы хотите удалить из имен все начальные / конечные пробелы, это простая настройка:
$ awk -v RS='[[:space:]]*</?name>[[:space:]]*' '!(NR%2)' file
Charles
William
Edward
John Boy Walton
Ответ №2:
С помощью awk
awk -F"<|>" '/name/ {print $3}' file
Charles
Если все данные находятся в одной строке, выполните:
awk -v RS="<" -F> '/name/{print $2;exit}' file
Charles
Комментарии:
1. Весь текст состоит из одной строки, он не разделен символами новой строки. Как вы думаете, это изменит поведение вашего решения? Я ничего не получаю обратно, используя эту команду
2. @user3120518 смотрите мой обновленный пост. Я также отредактировал ваш оригинальный пост.