Удаление новой строки между тегами xml в сценарии оболочки Unix - PullRequest
1 голос
/ 11 июня 2019
<mstr>
  <srt>Payment towards File# 1234</srt>
  <msg>info for treat sxc
  Pay to shankar  A/C#999999
  bank of ooty</msg>
  <ins>info for party BB
   Pay to kumar A/C#999999
   state bank</ins>
</mstr>

приведенный выше XML-код, который я хотел бы преобразовать, как показано ниже, то есть данные, заключенные в следующую строку между начальным и конечным тегами.следует в одной строке, как показано ниже.

 <mstr>
  <srt>Payment towards File# 1234</srt>
  <msg>info for treat sxc Pay to shankar  A/C#999999 bank of chen</msg>
  <ins>info for party BB Pay to kumar A/C#999999 state bank</ins>
</mstr>

Я попробовал следующий способ, ссылаясь на веб-ответ.Хотите понять, что ниже команда awk также ищет любую другую альтернативу, чтобы исправить мою проблему?

 awk '{printf /^</&&!/^<\//?RS $0:$0}'

Ответы [ 5 ]

2 голосов
/ 11 июня 2019

Я бы предложил, хотя есть и лучшие альтернативы, использовать awk для файла PYX . Формат PYX - это линейно-ориентированное представление документов XML, производное от формата SGML ESIS. (см. спецификацию информационного набора ESIS - ISO 8879 «Элементная структура», ISO / IEC JTC1 / SC18 / WG8 N931 (ESIS)).

Формат PYX чрезвычайно прост для описания и понимания. Первый символ в каждой строке идентифицирует тип содержимого строки. Контент не охватывает непосредственно строки, хотя последовательные строки могут содержать один и тот же тип контента. В случае атрибутов тега имя и значение атрибута просто разделяются пробелом, без использования дополнительных кавычек. Префиксные символы:

( start-tag
) end-tag
A attribute
- character data (content)
? processing instruction

Итак, мы можем попросить xmlstarlet преобразовать XML в PYX, использовать awk для удаления строк и преобразовать его обратно в файл XML:

$ xmlstarlet pyx file.xml | sed -E '/^-\\n/b;/^-/s/\\n +/ /g' | xmlstarlet p2x -
1 голос
/ 11 июня 2019

Вот объяснение сценария awk.

awk '{printf /^</&&!/^<\//?RS $0:$0}'

Надеюсь, изображение на экране четкое.

enter image description here

0 голосов
/ 11 июня 2019

Я бы использовал язык сценариев с модулем синтаксического анализа XML. Например, с ruby:

ruby -r'rexml/document' -e '
    file = ARGV.shift
    doc = REXML::Document.new(File.new(file))
    doc.elements.each("/mstr/*") {|child| child.text = child.text.gsub(/\n\s*/, " ")}
    File.open(file, "w") {|f| f.puts(doc.to_s)}
' file.xml

Результаты в файле

<mstr>
  <srt>Payment towards File# 1234</srt>
  <msg>info for treat sxc Pay to shankar  A/C#999999 bank of ooty</msg>
  <ins>info for party BB Pay to kumar A/C#999999 state bank</ins>
</mstr>
0 голосов
/ 11 июня 2019

Что вы хотите сделать - удаление пробелов в начале и конце текста и свертывание любой последовательности пробелов и символов новой строки в один пробел внутри текста - это известно как нормализация пробелов в XML, и могут быть сделаны многими инструментами обработки XML из коробки без необходимости специального сценария оболочки. Например, вы можете использовать tidy (доступно в http://tidy.sourceforge.net/ и может быть уже установлено на вашем компьютере или может быть установлено через sudo apt-get install tidy в Debian / Ubuntu) следующим образом, чтобы нормализовать пробелы в вводе (предполагается, что он сохранен). в test.xml):

tidy -xml -w 80 test.xml

Ваша строка в awk печатает любую строку ввода ($0), пропускает символы новой строки (используя printf() вместо print()) и добавляет RS (разделитель записей, символ табуляции по умолчанию) перед выходная строка, если строка начинается с тега начального элемента (/</), но не похожа на тег конечного элемента (!/^<\//). Два теста регулярного выражения объединяются с логическим и оператором && и являются частью условного выражения, в котором все перед символом ? соответствует условию теста, а часть, следующая за ?, представляет "if" и "else" Ветвь, соответственно, взять в зависимости от условного, разделенного :. Для вашего ввода программа awk будет выводить все в одной строке (без завершающего символа новой строки), и перед каждым тегом начального элемента будет добавлен символ табуляции. Он не сможет разделить последовательные текстовые строки пробелом и неправильно передаст всю входную строку в качестве первого аргумента printf(), так что процентный символ во входном тексте, интерпретируемый как плашечник в строках формата printf, будет сломать ваш вывод.

Сделайте себе одолжение и используйте настоящие инструменты XML или SGML для обработки разметки.

0 голосов
/ 11 июня 2019

Использование XML-инструмента для обработки XML, использование sed или awk может легко сломать данные.

Например, в xsh , инструменте, который мне приходится обслуживать, который на самом деле является оберткой вокруг XML :: LibXML , вы можете сделать:

open file.xml ;
for /mstr/* set . normalize-space(.) ;
save :b ;

Вывод почти ожидаемый - он просто сохраняет "ooty" вместо "chen", но это легко исправить, добавив

set /mstr/msg xsh:subst(/mstr/msg, 'ooty', 'chen') ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...