LINUX.ORG.RU

Поиск и удаление текста

 , ,


0

1

Допустим есть текст

<?xml version='1.0' encoding='UTF-8' ?>
<account version='1.0'>
	<account>
		<protocol>PROTOCOL</protocol>
		<name>NAME</name>
		<password>PASSWORD</password>
		...
	</account>
	<account>
		<protocol>PROTOCOL2</protocol>
		<name>NAME2</name>
		<password>PASSWORD2</password>
		...
	</account>
</account>

Как мне через скрипт на bash'e, найти и удалить в тексте именно этот кусок?

<account>
	<protocol>PROTOCOL</protocol>
	<name>NAME</name>
	<password>PASSWORD</password>
	...
</account>

Взять готовый парсер.

anonymous
()

Решение в лоб: с помощью 'grep -c' ищите номер строки в файле, которая содержит «<name>NAME</name>». Так же с помощью 'grep -c' ищите номера строк, в которых содержится «account», т.е. вы ищете открывающий и закрывающий теги блока, <account> и </account>, поиск номеров этих строк может быть одной командой. Дальше разбираете вывод, с помощью sed и grep. Найдя в выводе строку «<name>NAME</name>» считываете строку выше и ниже, и из этих строк срезаете номера строк в файле с которой начинается и на которой заканчивается блок.

Для считывания диапазона строк или одной строки можно применять sed, например:

sed -n 2,4p
считает диапазон строк со 2 по 4.

Для срезки номера строки применяйте 'cut -f1 -d:'.

Ну а дальше считывайте из исходного файла диапазоны строк и выводите его в другой файл без требуемого диапазона (блока).

Для вашего примера вывод строк будет примерно следующим:

1:<?xml version='1.0' encoding='UTF-8' ?>
2:<account version='1.0'>
3:	<account>
4:		<protocol>PROTOCOL</protocol>
5:		<name>NAME</name>
6:		<password>PASSWORD</password>
7:		...
8:	</account>
9:	<account>
10:		<protocol>PROTOCOL2</protocol>
11:		<name>NAME2</name>
12:		<password>PASSWORD2</password>
13:		...
14:	</account>
15:</account>

sed -n 1,2p $FILE > new_file
sed -n 9,15p $FILE >> new_file

Вроде, если не указывать последнюю границу будет считано всё до конца.

Вот ещё одно сообщение в тему. вырезать кусок из файла (комментарий)

kostik87 ★★★★★
()

Во-первых. И не слушай тех, кто будет регулярки советовать. Они на один раз.

Вот пример, как с помощью xsltproc удалить один из однотипных элементов

ziemin ★★
()
cat tmp.xml | lua -e 'print(io.read("*all"):gsub("<account>%s-<protocol>PROTOCOL.-/account>", "", 1))'

Удаляем первый блок.

cat tmp.xml | lua -e 'print(io.read("*all"):gsub("<account>%s-<protocol>PROTOCOL2.-/account>", "", 1))'

Второй.

annulen ★★★★★
()

xml ed -P -d '//protocol[text()="PROTOCOL"]/..'

// правда пустая строка появляется, но явно подход поприличнее этих ваших седов

anonymous
()
Ответ на: комментарий от leader32

Ну скрипт всё равно писать придётся ТС, если возьмётся реализовывать предложенный вариант решения задачи. Мне было лень писать скрипт, а тот, что по ссылке не подойдёт без внесения изменений.

Ну и ТС спрашивает:

dog_roulis

Как мне через скрипт на bash'e, найти и удалить в тексте именно этот кусок?

вот пусть и реализовывает.

kostik87 ★★★★★
()
Ответ на: комментарий от annulen

Странно, в таком варианте работает

cat tmp.xml | lua -e 'print(io.read("*all"):gsub("<account>%s-<protocol>PROTOCOL2.-/account>", "", 1))'


А если искать по имени то не работает 
cat tmp.xml | lua -e 'print(io.read("*all"):gsub("<account>%s-<name>NAME2.-/account>", "", 1))'

если не ошибаюсь то дело тут в

%s-

dog_roulis
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.