использование sed для замены строки в файлах, которые находятся в разных папках

У меня есть файл, который находится в разных папках (с расширением .mvw). Я хочу написать скрипт, который идет в каждую папку и заменить строку (в файле * .mvw) “D3PLOT_1DForce” на имя папки

Структура папок как ниже

  • XYZ_DV_L02_P01
  • XYZ_DV_L02_P02
  • XYZ_DV_L02_P03

Я написал следующий сценарий

#!/bin/sh for ii in XYZ_DV_L02* ; do (cd "$ii") find . -iname "*.mvw" -type f -exec sed -i "s/D3PLOT_1DForce_EffPlStrainMax_VonMisesMax/"${ii}"/g" "{}" \; done 

Он работает и заменяет строку именем папки, но заменяет имя 1-й папки во всех файлах. Я думаю, что sed не собирается в петле.

Как я могу поместить sed для работы в цикле, чтобы соответствующие имена папок использовались для замены строки в файле?

3 Solutions collect form web for “использование sed для замены строки в файлах, которые находятся в разных папках”

Команда cd выполняется в вложенной оболочке и поэтому фактически ничего не делает. Таким образом, ваша команда find выполняется из родительского каталога, по одному разу для каждого из имен XYZ_DV_L02* в XYZ_DV_L02* . Первый вызов sed изменяет строку во всех файлах, следующие вызовы sed не находят строку, но выполняются в любом случае.

Попробуй это:

 #!/bin/sh for ii in XYZ_DV_L02* ; do find "$ii" -iname "*.mvw" -type f -exec sed -i " s/D3PLOT_1DForce_EffPlStrainMax_VonMisesMax/${ii}/g" "{}" + done 

Спасибо за редактирование от Стефана Шазеля

Хотя я только что скопировал команду find из вопроса, только исправляя путь, стоит объяснить изменения:

  • ${ii} был заключен в кавычки, теперь он является частью кавычек, которые содержат весь аргумент sed .
  • Использование + вместо \; заставит find выполнить одну команду sed для нескольких файлов, а не одну для каждого файла.

редактировать

По запросу из комментария это заменит каждую последовательность набора [-_a-zA-Z0-9] за которой следует .h3d с текстом замены, который представляет собой имя файла, включая расширение .mvw , как я понимаю комментарий, но это не кажется полезным. Если вы хотите получить доступ к тексту в шаблоне, вы можете использовать \1 . Возможно, вам придется адаптировать набор для ваших конкретных потребностей.

 #!/bin/sh for ii in XYZ_DV_L02* ; do find "$ii" -iname "*.mvw" -type f -exec sed -i -r " s/([-_a-zA-Z0-9]+)\.h3d/${ii}.h3d/g" "{}" + done 

Попробуй это,

 #!/bin/sh for ii in XYZ_DV_L02* ; do cd "$ii" find . -iname "*.mvw" -type f -exec sed -i "s/D3PLOT_1DForce/"${ii}"/g" "{}" \; cd .. done 

Можно изменить каталог на первую входную папку для цикла for и поиска файла. Но мы должны вернуться в родительский каталог перед запуском следующего цикла.

Если у вас есть структура каталогов только с несколькими подкаталогами, у каждого из которых есть этот файл .mvw который вы хотите изменить, тогда вам не нужно использовать find потому что вы уже точно знаете, где находятся ваши файлы.

 for pathname in XYZ_DV_L02*/*.mvw; do sed -i "s/D3PLOT_1DForce/${pathname%%/*}/g" "$pathname" done 

Это перебирает все файлы .mvw в указанных подкаталогах и заменяет строку именем каталога. Расширение параметра ${pathname%%/*} удаляет все после первой строки / в строке в $pathname .

Тестирование:

 $ tree . |-- XYZ_DV_L02_P01 | `-- somefile.mvw |-- XYZ_DV_L02_P02 | `-- somefile.mvw `-- XYZ_DV_L02_P03 `-- somefile.mvw 3 directories, 3 files $ cat XYZ_DV_L02_P0*/*.mvw Hello D3PLOT_1DForce_EffPlStrainMax_VonMisesMax! Hello D3PLOT_1DForce_EffPlStrainMax_VonMisesMax! Hello D3PLOT_1DForce_EffPlStrainMax_VonMisesMax! 

(здесь работает цикл)

 $ cat XYZ_DV_L02_P0*/*.mvw Hello XYZ_DV_L02_P01_EffPlStrainMax_VonMisesMax! Hello XYZ_DV_L02_P02_EffPlStrainMax_VonMisesMax! Hello XYZ_DV_L02_P03_EffPlStrainMax_VonMisesMax! 

Очевидно, что если у вас есть глубокая иерархия, то вам, возможно, придется использовать find любом случае, но вы можете выполнять цикл изнутри find а не снаружи find :

 find XYZ_DV_L02*/ -type f -name '*.mvw' -exec sh -c ' for pathname do sed -i "s/D3PLOT_1DForce/${pathname%%/*}/g" "$pathname" done' sh {} + 

Здесь мы находим все файлы .mvw под любым из каталогов, соответствующих шаблону XYZ_DV_L02*/ . Для этих найденных файлов мы запускаем цикл, который делает то же самое, что и цикл в начале этого ответа. Это заменит строку D3PLOT_1DForce во всех файлах .mvw любом месте под любым из каталогов соответствующим XYZ_DV_L02* каталога XYZ_DV_L02* .

Связанные с:

  • Понимание опции -exec `find`

В этом ответе предполагается GNU sed или другая реализация sed которая выполняет редактирование на месте с -i без аргумента-опции.

  • Поиск файлов с конкретным контентом, пользователем и разрешениями
  • Xargs для извлечения имени файла
  • найти путь аргумента командной строки
  • Использование диска всеми файлами в каталоге
  • Использование цикла bash для запуска программы, которая использует одинарные кавычки в командной строке, где одинарные кавычки сводят на нет намерения сценария bash
  • Сохранение вывода команды поиска в переменную
  • Изменение расширения нескольких файлов с помощью однострочной команды
  • Команда locate находит файлы, которых там нет
  • Найти самые большие файлы в каталоге в определенный диапазон дат
  • С помощью gnu найдите, в чем разница между -print0 и -printf «% p \ 0»
  • Поиск файлов старше x дней в системе с урезанным занятым ящиком
  • Interesting Posts

    Как запустить скрипт, когда SSSD создает домашний каталог для нового пользователя

    Как отключить udevd в systemd?

    Как использовать Google DNS с ppp

    Ключ к букве «p» не работает повсюду, Ubuntu Linux

    Различные флаги USE для двоичного пакета сервера и хоста

    Утилита командной строки для получения пароля, у которого нет отклика эха

    Можно ли обнаружить, когда файл был загружен?

    Стандартный рабочий процесс для оцифровки журналов или книг с использованием OCR при минимизации размера файла?

    Переназначить кнопку «shutdown» на ноутбуке ASUS

    Как псевдоним команды, содержащей как апострофы, так и кавычки?

    / usr / bin /, который возвращает загадочную ошибку ", которая: no ls in ((null))"

    Что означает это сообщение из ядра?

    Почему следующие два способа отображения переменных среды текущей оболочки отличаются?

    Мне нужно очень небольшое количество Linux Utils. Как мне выбрать Distro?

    проблема загрузки в Linux

    Linux и Unix - лучшая ОС в мире.