
У меня есть команда, которая считывает файл и выводит измененную версию 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
, это сработало.