LINUX.ORG.RU

Поиск и удаление текста между определенными словами

 , ,


1

3

Здравствуйте, подскажите, как на centos7 возможно (и возможно ли?) найти во всех файлах сервера текст на 20-25 строк, расположенный между опред.словами, например «//text1 .... //text2» и удалить только этот текст вместе с тегами из каждого файла? Т.е. сам файл выглядит так:

...
//text1
somecode_line1
somecode_line2
somecode_line3
...
somecode_line35
//text2
...

Необходимо удалить весь этот мусор (причем текст может быть разным, в то время как text1 и text2 - везде одинаковы) между //text1 и //text2 включая и сами //text1 //text2 по-возможности.

Знаю как заменить одну строку, а вот с такой конструкцией что-то не получается ничего.

sed -i 's/text1*text2//g' filename

Но лучше сначала поэкспериментируй на чем-то ненужном, а то мало ли

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

Благодарю, а если я не знаю имени файла? Если мне необходимо сперва найти файлы с этим текстом, а только потом заменить? Там файлов штук 30-40 в итоге выйдет, не править же каждый вручную...

iAlexandre ()
Ответ на: комментарий от gnunixon

Благодарю за ответы, но смотрите какая проблема:

sed -i 's/text1*text2//g' /var/www/html/* 

и сразу же получил ошибку:

sed: couldn't edit /var/www/html/testfolder: not a regular file

Т.е. таким образом нужно только работать с файлами в папке, если в ней будет еще папка - не сработает ничего.

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

Вот у меня есть troff. И aptitude. И nethack. И много еще чего. Вот только нахрена оно все в контексте поставленной задачи, о анонимус со специфическим юмором?

anonymous ()

Испытуемый файл:

$ cat filename
somecode_line1
somecode_line2
//text1
somecode_line3
somecode_line4
//text2
somecode_line5
somecode_line6
somecode_line7
//text1
somecode_line8
somecode_line9
somecode_line10
//text2
somecode_line11

Решение в лоб:

$ perl -ne '$d=1 if /text1/; print unless $d; $d=0 if /text2/' filename

Решение через няшный флип-флоп оператор:

$ perl -ne 'print unless /text1/ ... /text2/' filename

Результат:

somecode_line1
somecode_line2
somecode_line5
somecode_line6
somecode_line7
somecode_line11
evbogdanov ()
Ответ на: комментарий от evbogdanov

Ну, можно и на авке, и на пыхе еще, да хоть на ассемблере с сисколлами. Правда, твои однострочники для одного файла. Имхо, проще чем find ... -exec sed ... уже некуда.

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

Ты прав. Я невнимательно распарсил задачу.

Для папок лучше использовать find ... -exec ...

Но если руки чешутся поперлокодить:

$ perl -i -lnE 'say unless /text1/ .. /text2/' $(ls /var/www/html/ | perl -lnE 'say if -T')
evbogdanov ()
Ответ на: комментарий от Deleted

Благодарю:) Но почему-то не удаляется текст между этими словами. Создал 3 одинаковых файла в папке test с таким содержанием:

testtext1
asdlkjladhkajshjkslfkjsahfksjhfskjfjsdfasdf
testtext2

testtext1 sdlhfsakjhfjkashfjkdsafhskajfhjksaf testtext2

Запустил

find /var/www/html/test -type f -exec sed -i 's/testtext1*testtext2//g' {} \;

Ииии.. Ничего, воз и ныне там, текст никуда из файлов не пропал.

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

Ну да. Вместо /testtext1*testtext2/ должно быть /testtext1.*testtext2/. Но есть еще один существенный косяк. sed, оказывается, не умеет многострочную замену без очень черной магии. Однострочники на перле, как мне показалось, тоже ведут себя по-свински, удаляя нужный текст в конце файла. Видимо, придется писать что-то чуть хитрее.

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

Вот такую жуть набыдлокодил. Самому стыдно :)

find /var/www/html/test -type f -exec perl -e '$/="";open $f,"<$ARGV[0]";$_=<$f>;close $f;s/testtext1.*?testtext2//gs;open $f, ">$ARGV[0]"; print $f $_;' {} \;

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

А это действительно работает, огромная благодарность! :) Черная магия в действии. :)

iAlexandre ()
Ответ на: комментарий от JaneDoe

Что-то как-то странно работает: на тестовых файлах отработало хорошо, а на боевых - удалило содержимое всего файла :)

iAlexandre ()
find /dir -type f -exec perl -0ipe 's%\n//text1.*//text2\n%\n%s' {} \+
ArcFi ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.