Bash выводится два результата рядом друг с другом

В заменяемой части всего 4 специальных символа: \ , & , новая строка и разделитель ( ref )

$ VAR='abc/def&ghi\foo
next line'

$ repl=$(sed -e 's/[&\\/]/\\&/g; s/$/\\/' -e '$s/\\$//' <<<"$VAR")

$ echo "$repl"
abc\/def\&ghi\\foo\
next line

$ echo ZYX | sed "s/Y/$repl/g"
Zabc/def&ghi\foo
next lineX

1
22.10.2018, 13:51
3 ответа
[your command] | paste -d '' - -

соединит последовательные строки.

1
27.01.2020, 23:42

Как только вы начнете использовать grepXML, вы будете делать предположения о входных данных, и (почти наверняка )у вас больше не будет корректного вывода XML, так что иногда это не лучший путь вперед.

Тем не менее, путь наименьшего сопротивления часто включает в себя grep, поэтому в зависимости от вашего XML (будет полезен хорошо -сформированный минимальный пример ), вы сможете использовать xmllintс--xpath(xmllint>= 2.7.7 для --xpathподдержка )вот так:

xmllint --xpath "//reference|//sourcefile"  input.xml |
  pcregrep -o "(<reference>.*?</sourcefile>)"

где xmllintизвлекает элементы, используя выражениеXPath , которое соответствует либо(|как логическому «или» )интересующих вас элементов,(//для выбора всех совпадающих элементов в любом месте ввод ). (не -не поддерживающий XML)pcregrep(вместоegrep)сопоставляет каждую пару элементов с группировкой и выводит каждую совпадающую группу по одной на -строку. Здесь следует отметить регулярное выражение .*?, которое является PCRE не -жадным соответствием , поэтому оно соответствует минимальному объему текста между указанными тегами, а не всей строке. за один раз(xmllint --xpath...выгружает все в одну строку ).

Использование grep немного "мошенничает", мы делаем предположения о входных данных, но xmllintвыполняет большую часть тяжелой работы. Такой подход может привести к проблемам с анализом в будущем, поскольку XML не является "обычным" , а регулярные выражения — не лучший инструмент для этой работы.

Аккуратный способ сделать это с помощью XMLStarlet:

xml select -t -m '//*' \
  --if 'local-name()="reference"' -c. \
  --elif 'local-name()="sourcefile"' -c. -o $'\n' input.xml

Это ищет все элементы (//*), при совпадении <reference>этот узел копируется в вывод (-c.), иначе при совпадении <sourcefile>этот узел копируется в вывод с дополнительной новой строкой вывода(-o $'\n').

0
27.01.2020, 23:42

Просто передайте данные наperl -pe 'chop if /^<reference>/'

0
27.01.2020, 23:42

Теги

Похожие вопросы