Рекурсивно применить команду для изменения всех файлов в каталоге

Рекурсивно применить команду для изменения всех файлов в каталоге

У меня есть команда, которая считывает файл и выводит измененную версию stdout:

./convert /path/to/file

Как я могу рекурсивно применить эту команду ко всем файлам в каталоге, иперезаписать существующее содержимое каждого файла результатом команды выше?

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

решение1

Если я правильно понимаю, вы можете конвертировать один файл с помощью

./convert /path/to/file >/path/to/file.new
mv /path/to/file.new /path/to/file

Чтобы применить команду к каждому файлу в дереве каталогов, используйте командуfindутилита. Поскольку вам нужно выполнить сложную команду для каждого файла, вам нужно явно вызвать оболочку.

find /path/to/top/directory -type f -exec sh -c '
  /path/to/convert "$0" >"$0.new" &&
  mv "$0.new" "$0"
' {} \;

решение2

Вопрос, на который вы ссылаетесь, не работает рекурсивно, он работает только на один уровень в глубину. Для рекурсии используйте find:

find . -type f -exec /path/to/convert {} \;

Вы хотите убрать convertсебя с дерева, по которому идете, чтобы избежать риска, что оно попытается изменить себя.

решение3

Если я правильно понимаю, вы хотите перезаписать каждый входной файл результатом convertэтого входного файла. Если так, попробуйте это:

find . -type f | while IFS= read -r file; do
  ./convert "$file" > /tmp/foo.tmp && mv /tmp/foo.tmp "$file";
done

решение4

Заимствование из превосходного @Gillesотвечать:

find /path/to/top/directory -type f -exec sh -c '/path/to/convert "$0" | tee "$0"' {} \;

Я попробовал сделать вышеописанное sed, это сработало.

Связанный контент