У меня есть текстовый файл (file.txt
), в котором указаны пути ко всем файлам, для которых должны выполняться команды. Как перебрать цикл for
и выполнить команды для файла в каждом пути текстового файла? Я пробовал это:
#!/bin/sh
LOC=pathto the file
for f in $LOC;
do
sed -i '1i\10004' $f;
done
Вам не нужен цикл оболочки, потому что даже с -i
, команда sed
принимает несколько аргументов имени файла и работает с каждым именованным файлом отдельно . Однако, если все файлы уже полностью не зарезервированы, я рекомендую вам использовать -i.bak
- с любым суффиксом, который вы предпочитаете, это не обязательно должно быть .bak
. Использование sed -i
без создания файла резервной копии часто приводит к случайной потере данных. (Эта рекомендация будет применяться в равной степени, если вы запускаете sed
один раз для каждого файла в цикле.)
Поскольку sed
принимает несколько аргументов имени файла, и поскольку вы можете использовать xargs
вместо цикла для создания списка имен файлов и передачи их в sed
, вы можете сделать все за одну короткую команду. В зависимости от ваших потребностей, вы можете просто запустить эту команду вместо написания скрипта. Или ваш сценарий может состоять только из этой одной команды, кроме хеш-бэнга #!/bin/sh
вверху. Вам не нужно использовать ни переменные оболочки, ни циклы, ни другие управляющие структуры в оболочке. (Обработка текста, такого как список имен файлов, с использованием цикла в сценарии оболочки, часто не лучший подход .)
Я предполагаю, что входной файл содержит одно имя файла на строку, даже если разделение имен файлов нулевыми символами, а не символами новой строки было бы лучше (в том смысле, что оно работало бы правильно, даже если некоторые имена файлов содержали символы новой строки). Предполагая, что это так, вот команда, которую вы можете использовать:
xargs -d'\n' -a files sed -i.bak '1i\10004'
-d'\n'
сообщает xargs
, что имена файлов, которые он читает, разделены символами новой строки, то есть они появляются по одному на строку во входном файле. -a files
говорит xargs
прочитать входные данные из файла с именем files
. (Вы можете использовать перенаправление и написать <files
вместо -a files
, как это часто делается.) Замените files
фактическим именем файла, из которого вы хотите прочитать имена файлов. -i.bak
выполняет модификации на месте (-i
), как вы знаете. Включение .bak
без пробела в этот же аргумент командной строки указывает sed
сохранять файлы резервных копий с суффиксом .bak
. Если вам нужен другой суффикс, используйте его вместо .bak
. Если вы действительно хотите сделать это без создания файлов резервных копий, то вы можете просто опустить суффикс и написать просто -i
. '1i\10004'
передает 1i\10004
в sed
для использования в качестве команды для обработки строк файла. (Другие читатели захотят заменить это любой командой sed
, которую они используют.)