Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Найти и заменить  (Прочитано 2071 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн typus

  • Автор темы
  • Любитель
  • *
  • Сообщений: 78
    • Просмотр профиля
    • Virtual Reality Panoramafotografie für interaktive Darstellung auf Webseiten.
Найти и заменить
« : 08 Января 2011, 16:36:35 »
Всем привет,
Помогите довести до ума скрипт, который бы искал в исходной папке рекурсивно по всем подпакам строки с одним текстом и заменял этот текст на другой...
Вроде бы, в просто, find и sed все делают. Осталось только до ума довести.
Например, команда вида
find "корневая_папка_для_поиска" -name "*.xml" -print0 | xargs -0 sed -i -e "s/текст_для_поиска/заменяем_на/g"все делает, но при этом копирует все исходные файлы - до вснесения в них изменений и кладет их рядом с добавлением -е в конец имени файла. А мне не нужны двойные файлы, зачем они?
Если же опцию е не применять, то не срабатывает, выходит ошибка типа
sed: 1: "/home/wins/skin/me ...": undefined label 'im/skin/media/xml/media.xml'И еще, хотелось бы иметь лог, желательно такой: после того, как find нашел данные вхождения, записался бы лог где, в каких файлах что было найдено, после замены - соответственно что стало. Вроде как grep тут нужен, но чет я не соображу, как правильно и красиво все оформить.
Если у кого есть мысли, помогайте, плз.

Оффлайн Vitsliputsli

  • Старожил
  • *
  • Сообщений: 1293
    • Просмотр профиля
Re: Найти и заменить
« Ответ #1 : 08 Января 2011, 17:21:41 »
Цитировать
все делает, но при этом копирует все исходные файлы - до вснесения в них изменений и кладет их рядом с добавлением -е в конец имени файла
И с -e пробовал и без, никаких фалов "с добавлением -е" не видел.

find -name "*.xml" > my.log && xargs -a my.log sed -i "s/текст_для_поиска/заменяем_на/g"будет создан файл с перечислением обработанных файлов.
"в каких файлах что было найдено, после замены - соответственно что стало" найдено то, что искали; заменили на то, на что заменяли... или я что-то не понял?

Оффлайн typus

  • Автор темы
  • Любитель
  • *
  • Сообщений: 78
    • Просмотр профиля
    • Virtual Reality Panoramafotografie für interaktive Darstellung auf Webseiten.
Re: Найти и заменить
« Ответ #2 : 08 Января 2011, 23:27:13 »
Цитировать
все делает, но при этом копирует все исходные файлы - до вснесения в них изменений и кладет их рядом с добавлением -е в конец имени файла
И с -e пробовал и без, никаких фалов "с добавлением -е" не видел.

в общем, у меня на одной системе  - на Ubuntu  - все ок, на другой такое (freeBSD). Создается копия исходного файла с именем например file.xml-e. Ну и там же не работает без -е, ошибка как я выше написал.
Впрочем, наверное, тут это немного офф, и надо на форуме по фре спрашивать. Я честно говоря думал, что эти команды с одинаковыми опциями одинаково на разных unix-осях отрабатывают.

find -name "*.xml" > my.log && xargs -a my.log sed -i "s/текст_для_поиска/заменяем_на/g"будет создан файл с перечислением обработанных файлов.
"в каких файлах что было найдено, после замены - соответственно что стало" найдено то, что искали; заменили на то, на что заменяли... или я что-то не понял?

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

Оффлайн Vitsliputsli

  • Старожил
  • *
  • Сообщений: 1293
    • Просмотр профиля
Re: Найти и заменить
« Ответ #3 : 09 Января 2011, 00:26:12 »
Цитировать
все делает, но при этом копирует все исходные файлы - до вснесения в них изменений и кладет их рядом с добавлением -е в конец имени файла
Он воспринимает -e как аргумент параметра -i.
Те в варианте
sed -i -e "s/текст_для_поиска/заменяем_на/g"он создает файл с суффиксом -e  обработав его по правилу "s/текст_для_поиска/заменяем_на/g"
а в варианте
sed -i "s/текст_для_поиска/заменяем_на/g"он пытается создать файл с суффиксом "s/текст_для_поиска/заменяем_на/g" - что невозможно.
Вероятно как-то так...

В linux аргумент для -i должен идти без пробела - потому проблемы нет.
Попробуйте так:
sed -i "" -e "s/текст_для_поиска/заменяем_на/g"

Оффлайн typus

  • Автор темы
  • Любитель
  • *
  • Сообщений: 78
    • Просмотр профиля
    • Virtual Reality Panoramafotografie für interaktive Darstellung auf Webseiten.
Re: Найти и заменить
« Ответ #4 : 09 Января 2011, 02:54:40 »
да, так работет, спасибо.


Оффлайн Vitsliputsli

  • Старожил
  • *
  • Сообщений: 1293
    • Просмотр профиля
Re: Найти и заменить
« Ответ #5 : 09 Января 2011, 17:25:49 »
Если еще актуально, чтобы логи писались можно сделать так:
for a in $( find -name "*.xml" ); do
sed -i "/текст_для_поиска/ s//заменяем_на/gwsed.log" $a
c=`wc -l < sed.log`
if [ $c != 0 ]; then
echo "$a - $c замен(ы)"
fi
done
rm sed.log
Конечно, не красиво. sed Постоянно пишет в файл sed.log, но как по-другому его заставить писать что делает, и при этом не повторять одно и то же, так и не понял...

Кстати, конструкция в sed немного отличается от стандартной - вроде как это должно работать быстрее...

Оффлайн typus

  • Автор темы
  • Любитель
  • *
  • Сообщений: 78
    • Просмотр профиля
    • Virtual Reality Panoramafotografie für interaktive Darstellung auf Webseiten.
Re: Найти и заменить
« Ответ #6 : 09 Января 2011, 22:56:16 »
Если еще актуально, чтобы логи писались можно сделать так:
for a in $( find -name "*.xml" ); do
sed -i "/текст_для_поиска/ s//заменяем_на/gwsed.log" $a
c=`wc -l < sed.log`
if [ $c != 0 ]; then
echo "$a - $c замен(ы)"
fi
done
rm sed.log
Конечно, не красиво. sed Постоянно пишет в файл sed.log, но как по-другому его заставить писать что делает, и при этом не повторять одно и то же, так и не понял...

Кстати, конструкция в sed немного отличается от стандартной - вроде как это должно работать быстрее...
Актуально, спасибо, попробую, отпишусь.
Т.е. в такой конструкции в конце sed.log будет удален, а все должно записаться в gwsed.log, если я правильно понял?

Оффлайн Vitsliputsli

  • Старожил
  • *
  • Сообщений: 1293
    • Просмотр профиля
Re: Найти и заменить
« Ответ #7 : 10 Января 2011, 01:18:53 »
Цитировать
gwsed.log
g - это часть правила "/текст_для_поиска/ s//заменяем_на/g"
w - это команда писать сделанные изменения в файл
sed.log - собственно этот файл, те параметр для w

Во время выполнения sed, если что-то заменено, то "заменяем_на" будет записано в файл sed.log каждый раз когда происходит замена. В итоге, после обработки каждого xml-файла, в sed.log будет столько строк, сколько было произведено замен. Эти строки считаем и присваиваем переменной $c.
 :( ничего лучше не нашел. Вероятно плохо искал...

Оффлайн typus

  • Автор темы
  • Любитель
  • *
  • Сообщений: 78
    • Просмотр профиля
    • Virtual Reality Panoramafotografie für interaktive Darstellung auf Webseiten.
Re: Найти и заменить
« Ответ #8 : 10 Января 2011, 12:46:57 »
Цитировать
gwsed.log
g - это часть правила "/текст_для_поиска/ s//заменяем_на/g"
w - это команда писать сделанные изменения в файл
sed.log - собственно этот файл, те параметр для w

Во время выполнения sed, если что-то заменено, то "заменяем_на" будет записано в файл sed.log каждый раз когда происходит замена. В итоге, после обработки каждого xml-файла, в sed.log будет столько строк, сколько было произведено замен. Эти строки считаем и присваиваем переменной $c.
 :( ничего лучше не нашел. Вероятно плохо искал...
я понял, проверил сегодня, отрабатывает нормально, но лог в конце цикла удаляется, а если его не удалять, то он находится в исходной папке нулевого размера - пустой...
В принципе, меня бы устроила запись вывода "echo" в файл - но что то у меня echo выводит в файл только одну строку,  в данном случае, только то, что было найдено  и изменено в первом файле.
Если же таких файлов больше, то изменения происходят, но не записываются.
Вроде все правильно, но не срабатывает.
#!/bin/bash
LOGFILE=/home/alex/sed1.log
cd /home/alex/media
for a in $( find -name "*.xml" ); do
sed -i "/текст_для_поиска/ s//заменяем_на/gwsed.log" $a
c=`wc -l < sed.log`
if [ $c != 0 ]; then
echo "Найдено и изменено в $a - $c значений"  1>$LOGFILE

fi

done
rm sed.log

Оффлайн Vitsliputsli

  • Старожил
  • *
  • Сообщений: 1293
    • Просмотр профиля
Re: Найти и заменить
« Ответ #9 : 10 Января 2011, 17:17:43 »
а так:
echo "Найдено и изменено в $a - $c значений"  >> $LOGFILE

Оффлайн typus

  • Автор темы
  • Любитель
  • *
  • Сообщений: 78
    • Просмотр профиля
    • Virtual Reality Panoramafotografie für interaktive Darstellung auf Webseiten.
Re: Найти и заменить
« Ответ #10 : 11 Января 2011, 14:30:15 »
а так:
echo "Найдено и изменено в $a - $c значений"  >> $LOGFILE
Ну да, спасибо, так получается. В принципе, на этом можно и закончить.

 

Страница сгенерирована за 0.053 секунд. Запросов: 23.