Здравствуйте старожилы, очень сильно нуждаюсь в Bash скрипте. Данный скрипт должен найти определённую строку во всех .txt файлах, всех каталогов и подкаталогов (то есть полностью во всех папках). И заменить ее на мной указанную.[u]В моем случае поиск будет происходить по пути:[/u] /volume1/test
[u]Заменить нужно[/u] 192.168.1.56 на 192.168.178.111Применение данного скрипта помогло частично:
#!/bin/sh
for i in `find "/volume1/test" -depth -name "*.txt" -exec grep -H "192.168.1.56" {} \; | awk -F ":" '{print $1}' | xargs`;
do sed -i 's/192.168.1.56/192.168.178.111/g' $i;
doneвозможно в силу специфики аппарата для которого пишется данный скрипт.
[u]Аппарат:[/u] Synology DS1813+
Не происходит полный поиск и замена во всех подкаталогах и во всех txt файлах. Хотя скрипт запускается от root.Для того чтобы видеть картину целяком прикрепляю результаты теста скрипта написанного выше:
Сформировал подробный отчет в виде изображения ниже:
http://s018.radikal.ru/i515/1401/a2/09ed91afdfd6.jpg
Прикрепляю архив в котором находятся файлы, которые мной использовались для тестирования (6,19 МБ):
В данном архиве находится каталог для которого в конечном итоге данный скрипт должен быть задействован (483 МБ):
В случае тестирования распакуйте любой из архивов в корень папки.
Вроде как объяснил более чем доступно, спасибо всем откликнувшимся. Прошу помощи так как сам не располагаю достаточным количеством знаний в написании Bash скриптов. И только приобретаю опыт.
> Применение данного скрипта помогло частично:
> #!/bin/sh
> for i in `find "/volume1/test" -depth -name "*.txt" -exec grep -H "192.168.1.56"
> {} \; | awk -F ":" '{print $1}' | xargs`;
> do sed -i 's/192.168.1.56/192.168.178.111/g' $i;
> done
> Не происходит полный поиск и замена во всех подкаталогах и во всех
> txt файлах. Хотя скрипт запускается от root.Нет, это в силу того, как работает конструкция <<for i in `bla-bla-bla`; do>>.
Замени на <<bla-bla-bla |while read i; do>> или [в коде выше не нужно, вроде, и требует #!/bin/bash] на << while read i; do ...; done < <(bla-bla-bla) >>.
Ваш скрипт не учитывает пробелы в именах файлов, как и написал предыдущий оратор.
Должно быть так:#!/bin/sh
find /volume1/test -name '*.txt' -exec grep -H '192\.168\.1\.56' {} \; | awk -F":" '{ print $1 }' | while read i ; do
sed -i 's/192\.168\.1\.56/192\.168\.178\.111/g' "$i"
doneВ команде sed "$i" двойные кавычки - обязательно
>[оверквотинг удален]
> оратор.
> Должно быть так:
> #!/bin/sh
> find /volume1/test -name '*.txt' -exec grep -H '192\.168\.1\.56' {} \; |
> awk -F":" '{ print $1 }' | while read i ;
> do
> sed -i 's/192\.168\.1\.56/192\.168\.178\.111/g' "$i"
> done
> В команде sed "$i" двойные кавычки
> - обязательноОгромное спасибо за быстрые ответы.
Мою задачку решил данный скрипт:
#!/bin/sh
find /volume1/test -type f -name "*.txt" -exec sed -i 's/192\.168\.1\.56/192\.168\.178\.111/g' "{}" \;Скрипт полноценно работает. После работы скрипта, скрупулёзно проверил 1681 txt файл (через notepad++), нужные изменения были внесены должным образом в каждый файлик. Еще раз всем спасибо. Тему можно закрывать.
>#!/bin/sh
> find /volume1/test -type f -name "*.txt" -exec sed -i 's/192\.168\.1\.56/192\.168\.178\.111/g'
> "{}" \;Что только не придумают, чтобы man sed и man find не читать.
find /volume1/test -type f -name "*.txt" -print0 | xargs -0 sed -i 's/192\.168\.1\.56/192\.168\.178\.111/g'> Скрипт полноценно работает. После работы скрипта, скрупулёзно проверил 1681 txt файл
Иногда усердие превозмогает разум.
find /volume1/test -type f -name "*.txt" -print0 | xargs -0 grep '192\.168\.1\.56'Тебе повезло, что не попалось ни одного пробела в именах файлов/каталогов.
>[оверквотинг удален]
> find /volume1/test -type f -name "*.txt" -print0 | xargs -0 sed
> -i 's/192\.168\.1\.56/192\.168\.178\.111/g'
>
Странно но в именах каталогов пробелов уйма. Но поиск и замена произошли идеально.
ПС."Иногда усердие превозмогает разум."-Цитата дня, спасибо.)
>[оверквотинг удален]
> find /volume1/test -type f -name "*.txt" -print0 | xargs -0 sed
> -i 's/192\.168\.1\.56/192\.168\.178\.111/g'
>
>> Скрипт полноценно работает. После работы скрипта, скрупулёзно проверил 1681 txt файл
> Иногда усердие превозмогает разум.
>
> find /volume1/test -type f -name "*.txt" -print0 | xargs -0 grep
> '192\.168\.1\.56'
>
> Тебе повезло, что не попалось ни одного пробела в именах файлов/каталогов.Странно но в именах каталогов пробелов уйма. Но поиск и замена произошли идеально.
ПС."Иногда усердие превозмогает разум."-Цитата дня, спасибо.)
> Что только не придумают, чтобы man sed и man find не читать.
> Иногда усердие превозмогает разум.
> Тебе повезло, что не попалось ни одного пробела в именах файлов/каталогов.Вы, несомненно, умный. Очень умный. И очень быстрый. Только не внимательный. _СОВСЕМ_ невнимательный.
Если присмотреться, то в варианте топик-стартёра
... sed -i 's/192\.168\.1\.56/192\.168\.178\.111/g' "{}" \;
> Вы, несомненно, умный. Очень умный. И очень быстрый. Только не внимательный. _СОВСЕМ_
> невнимательный.
> Если присмотреться, то в варианте топик-стартёра
>
> ... sed -i 's/192\.168\.1\.56/192\.168\.178\.111/g' "{}" \;
>Угу, с кавычками прошло. Правда запустило 1600+ процессов. Полагаешь, это вообще стоило рассматривать, как вариант?
> Угу, с кавычками прошло. Правда запустило 1600+ процессов. Полагаешь, это вообще стоило
> рассматривать, как вариант?Имхо, для _одноразового_ решения подойдёт любой костыль.
Это не тот случай, когда лучше "два часа потренироваться и потом за пять минут долететь"
Здравствуйте!
Есть вопрос по аналогичной задаче:
Имеется скриптIPADDR=$(ip -o -f inet addr show eth0 | sed -n 's/^.\+inet \(.\+\)\/.\+$/\1/gp')
if [ "x${IPADDR}" != "x" ]; then
for F in `grep -r -l 'IP\.ADDRESS\.TO\.CHANGE' /file.txt`; do
sed -i 's/IP\.ADDRESS\.TO\.CHANGE/'${IPADDR}'/g' $F;
done
fiСкрипт вполне себе рабочий и свою функцию выполняет, но появилась необходимость вставлять ip в виде 192-168-1-1 (т.е. не через точки, а тире, а в переменную $IPADDR попадает в виде 192.168.1.1).
Подайте идею, как это сделать.
IPADDR=$(ip -o -f inet addr show eth0 | sed -n 's/^.\+inet \(.\+\)\/.\+$/\1/gp' | tr "." "-" )
> IPADDR=$(ip -o -f inet addr show eth0 | sed -n 's/^.\+inet \(.\+\)\/.\+$/\1/gp'
> | tr "." "-" )Спасибо, но это решение не совсем подходит.
Текстовый файл в итоге должен иметь вид вроде следующего:ip=192.168.1.1
mask=255.255.255.0
domain=192-168-1-1-mydomain.netА при таком решении "-" подставится во всех случаях
> Текстовый файл в итоге должен иметь вид вроде следующегоНу - вам надо, вы и думайте, как этого добиться.
А то сначала спрашиваете как в IP-адресе заменить точки на тире, а потом недовольны, потому что у вас целая структура файла, видите ли, требует генерации.
>> Текстовый файл в итоге должен иметь вид вроде следующего
> Ну - вам надо, вы и думайте, как этого добиться.
> А то сначала спрашиваете как в IP-адресе заменить точки на тире, а
> потом недовольны, потому что у вас целая структура файла, видите ли,
> требует генерации.В любом случае, спасибо за помощь!