Как я ищу, файл для строки затем используют его в качестве переменной?

с Perl :

perl -0ne 'END {print $.}'

или:

perl -nle 'print scalar split "\0"'

или:

perl -nle 'print scalar unpack "(Z*)*", $_'
0
16.12.2018, 00:10
3 ответа

Обработка XML в качестве текста, как правило, не является надежным решением, но если вы настаиваете на том, что вы, возможно, можете воспользоваться пространством удержания SED E.G.

sed -e '/<id>[0-9]*<\/id>/h' -e '/<root>/{x;p;x;}' file.xml
4
28.01.2020, 02:17

Решение с использованием awk будет

awk '/<id>/{id=$0}/<root>/{print id}1' file.xml

Если вы не хотите печатать , вы можете пропустить Линия, добавив Далее .

awk '/<id>/{id=$0;next}/<root>/{print id}1' file.xml
0
28.01.2020, 02:17
sed -e :b -e '$!{N;\|<id>.*\n<root>|!bb
};do what ever you want to do with all of those lines now....'

Я согласен со стилдрайвером, что h oldspace, вероятно, лучший вариант, но есть и другие варианты. Иногда мы не можем побеспокоиться об управлении обоими буферами - или, как часто бывает в моей проблеме, мы уже управляем обоими буферами. Вышеуказанные фрагменты стекают линии в пространстве паттернов. Пока между тегами всегда происходит , он всегда рекурсивно заполняет пространство паттерна нужным блоком данных перед переходом на 2-ю строку - , т.е. будет делать это до тех пор, пока буферы не взорвутся - но это довольно сложно сделать сейчас.

Также, возвращаясь к hстарой вещи пространства, exизменение действительно делает swap hстарой и шаблонной вещи. Используя его один раз, буфер шаблонов становится старым буфером h и наоборот. Этот эффект выдерживает линейные циклы. Часто то, что я делаю, читаю в файле, пока не доберусь до стартовой строки, выполняю предварительные правки, затем своп и продолжаю ставить H до тех пор, пока не получу другую. Когда мой скрипт поменяет местами обратно, он наматывает блок сзади - на последнем маркере, который я включил, плюс все Hстарые за это время. Это простой способ буферизации только столько, сколько необходимо, когда вы должны.

И так, другой способ реализации цикла, как вы хотите:

sed -e '/<id>/h;//!H;/<root>/!{$!d' -e '};x...'

С этой точки на пространстве шаблона находится Hстарое пространство и наоборот. h old will overwrite hold space with current pattern space whenever it used - так что приведенный выше пример каждый раз начинает свежий буфер со строкой . !H добавляет все промежуточные строки к Hстарому пространству, каждая из которых следует за символом \newline. $!dподнимает пробел в каждой строке, которая является ! не последний раз $, когда текущая строка благополучно Hстарше и начинает следующий цикл строк, и поэтому exизменение происходит только на совпадениях <корень>, к которому весь блок ждет вас.

Просто имейте в виду, что на вашем самом последнем блоке , ваш маркер, вероятно, последняя строка, в случае, если она отличается от совпадений .

Но...

Согласно вашему редактированию, я не вижу причин, по которым вам не удалось уйти:

sed '/<id>/h;//d;\|</root>|G
' <<\INPUT
unimportant 1
<id> number 1 </id>
<root> sub text
more text
 more text
</root>
<root> sub text as well
and more text
and more text
</root>
unimportant 2
<id> number 2 </id>
<root> sub text
more text
more text
</root>
<root> sub text
and more text
and more text
</root>
INPUT

Там строки - это hстарые (опять же: перезапись hстарого места), а затем dвозведенные из вывода. Когда происходит совпадение , sed Gets старое пространство hдобавленное к пространству шаблонов перед автоматической печатью результатов в конце линейного цикла, который выглядит так:

unimportant 1
<root> sub text 
more text
 more text
</root>
<id> number 1 </id>
<root> sub text as well
and more text
and more text
</root>
<id> number 1 </id>
unimportant 2
<root> sub text
more text
more text
</root>
<id> number 2 </id>
<root> sub text
and more text
and more text
</root>
<id> number 2 </id>
1
28.01.2020, 02:17

Теги

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