URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 9825
[ Назад ]

Исходное сообщение
"Поиск и замена текста во всех txt, всего каталога."

Отправлено dydaevskiy , 03-Фев-14 09:44 
Здравствуйте старожилы, очень сильно нуждаюсь в 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 МБ):

http://clck.ru/94dRm

В данном архиве находится каталог для которого в конечном итоге данный скрипт должен быть задействован (483 МБ):

http://clck.ru/94dRu

В случае тестирования распакуйте любой из архивов в корень папки.

Вроде как объяснил более чем доступно, спасибо всем откликнувшимся. Прошу помощи так как сам не располагаю достаточным количеством знаний в написании Bash скриптов. И только приобретаю опыт.


Содержание

Сообщения в этом обсуждении
"Поиск и замена текста во всех txt, всего каталога."
Отправлено Andrey Mitrofanov , 03-Фев-14 10:29 
> Применение данного скрипта помогло частично:
> #!/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) >>.


"Поиск и замена текста во всех txt, всего каталога."
Отправлено Ager , 03-Фев-14 11:11 
Ваш скрипт не учитывает пробелы в именах файлов, как и написал предыдущий оратор.
Должно быть так:

#!/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"   двойные кавычки - обязательно


"Поиск и замена текста во всех txt, всего каталога."
Отправлено dydaevskiy , 03-Фев-14 11:27 
>[оверквотинг удален]
> оратор.
> Должно быть так:
>  #!/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++), нужные изменения были внесены должным образом в каждый файлик. Еще раз всем спасибо. Тему можно закрывать.


"Поиск и замена текста во всех txt, всего каталога."
Отправлено ACCA , 03-Фев-14 23:44 
>
#!/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'

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


"Поиск и замена текста во всех txt, всего каталога."
Отправлено dydaevskiy , 04-Фев-14 09:07 
>[оверквотинг удален]
> 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'
>

> Тебе повезло, что не попалось ни одного пробела в именах файлов/каталогов.

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

ПС."Иногда усердие превозмогает разум."-Цитата дня, спасибо.)



"Поиск и замена текста во всех txt, всего каталога."
Отправлено dydaevskiy , 04-Фев-14 09:08 
>[оверквотинг удален]
> 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'
>

> Тебе повезло, что не попалось ни одного пробела в именах файлов/каталогов.

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

ПС."Иногда усердие превозмогает разум."-Цитата дня, спасибо.)


"Поиск и замена текста во всех txt, всего каталога."
Отправлено Ager , 04-Фев-14 12:32 
> Что только не придумают, чтобы man sed и man find не читать.
> Иногда усердие превозмогает разум.
> Тебе повезло, что не попалось ни одного пробела в именах файлов/каталогов.

Вы, несомненно, умный. Очень умный. И очень быстрый. Только не внимательный. _СОВСЕМ_ невнимательный.
Если присмотреться, то в варианте топик-стартёра


...   sed -i 's/192\.168\.1\.56/192\.168\.178\.111/g' "{}" \;


"Поиск и замена текста во всех txt, всего каталога."
Отправлено ACCA , 05-Фев-14 01:18 
> Вы, несомненно, умный. Очень умный. И очень быстрый. Только не внимательный. _СОВСЕМ_
> невнимательный.
> Если присмотреться, то в варианте топик-стартёра
>
 
>  ...   sed -i 's/192\.168\.1\.56/192\.168\.178\.111/g' "{}" \;
>

Угу, с кавычками прошло. Правда запустило 1600+ процессов. Полагаешь, это вообще стоило рассматривать, как вариант?


"Поиск и замена текста во всех txt, всего каталога."
Отправлено Ager , 05-Фев-14 13:14 
> Угу, с кавычками прошло. Правда запустило 1600+ процессов. Полагаешь, это вообще стоило
> рассматривать, как вариант?

Имхо, для _одноразового_ решения подойдёт любой костыль.
Это не тот случай, когда лучше "два часа потренироваться и потом за пять минут долететь"


"Поиск и замена текста во всех txt, всего каталога."
Отправлено xaleks , 13-Янв-15 18:06 
Здравствуйте!
Есть вопрос по аналогичной задаче:
Имеется скрипт

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).
Подайте идею, как это сделать.


"Поиск и замена текста во всех txt, всего каталога."
Отправлено DeadLoco , 14-Янв-15 11:30 
IPADDR=$(ip -o -f inet addr show eth0 | sed -n 's/^.\+inet \(.\+\)\/.\+$/\1/gp' | tr "." "-" )

"Поиск и замена текста во всех txt, всего каталога."
Отправлено xaleks , 14-Янв-15 11:48 
> 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

А при таком решении "-" подставится во всех случаях


"Поиск и замена текста во всех txt, всего каталога."
Отправлено DeadLoco , 14-Янв-15 12:45 
> Текстовый файл в итоге должен иметь вид вроде следующего

Ну - вам надо, вы и думайте, как этого добиться.

А то сначала спрашиваете как в IP-адресе заменить точки на тире, а потом недовольны, потому что у вас целая структура файла, видите ли, требует генерации.


"Поиск и замена текста во всех txt, всего каталога."
Отправлено xaleks , 14-Янв-15 12:48 
>> Текстовый файл в итоге должен иметь вид вроде следующего
> Ну - вам надо, вы и думайте, как этого добиться.
> А то сначала спрашиваете как в IP-адресе заменить точки на тире, а
> потом недовольны, потому что у вас целая структура файла, видите ли,
> требует генерации.

В любом случае, спасибо за помощь!