4

Простая задача: учитывая каталог файлов и команду, которая принимает один файл в качестве входных данных и создает один файл в качестве выходных данных, я хочу обработать все файлы в каталоге одновременно и вывести их с соответствующими совпадающими именами (с новыми расширениями).

Так что, если команда будет обычно:

convert -input sourceFile.ext -output destFile.out

Я хочу обработать папку с

file1.ext, file2.ext, etc.

и производить в тех же каталогах файлы

file1.out, file2.out, etc.

Есть ли способ сделать это в терминале без написания скрипта bash? Я не очень хорошо знаком со сценариями, поэтому было бы полезно любое простое решение.

4 ответа4

10

Без использования basename:

for file in *.ext; do convert -input "$file" -output "${file/%ext/out}"; done

См. Http://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion

5

Посмотрите в команду find

Обязательно cd на ваш входной каталог.

cd input_directory
find . -iname "*.ext" -exec convert -input {} -output {}.out \;

Это приводит к добавлению .out к имени вашего входного файла. Получение вашего заявленного выходного файла я еще не понял.

Всегда разумно проверить, что делает find перед запуском -exec который что-то меняет.

cd input_directory    
find  .  -iname "*.ext"  -type f  -exec ls -l {} \;

будет делать что-то вроде "пробега".

  • -exec какую команду запустить
  • {} какой файл был найден; один за раз
  • \; нужно использовать это, чтобы закончить -exec

Мои ограниченные эксперименты показывают, что вам не нужно цитировать {}

$ find . -type f -exec ls -bl {} \;  
-rw-r--r--. 1 me me 0 Oct 20 19:03 ./a\ b\ c.txt  
-rw-r--r--. 1 me me 0 Oct 20 19:03 ./abc.txt  

$ ls -bl
total 0
-rw-r--r--. 1 me 0 Oct 20 19:03 a\ b\ c.txt
-rw-r--r--. 1 me 0 Oct 20 19:03 abc.txt
me ~/a $`

У меня есть текстовый файл help.txt, в котором содержатся подсказки ко всем моим трудно запоминающимся командам bash. Я привязал его к простому сценарию, чтобы распечатать файл .., ч

Вот список моих команд поиска:

# searches for all files on the system for the string you fill in between the ""
sudo find  /  -type f -exec grep -il "" {} \;
# search for all files starting with python.
find / -iname 'python*'
# search for the file type .jpeg and sort the list by date
find  ~  -iname "*.jpeg" -type f  -exec ls -l  {} \; 2>/dev/null | sort -r -k 8,8 -k 6,7M
# so I can remember the or syntax. 
find  ~  \( -iname "*.jpeg" -o -iname "*.png"  \) -type f  -exec ls -l  {} \;
4

Попробуйте это (это всего одна строка):

find /path/to/folder -maxdepth 1 -iname \*.ext -exec sh -c 'convert -input "{}" -output "/path/to/folder/$(basename "{}" .ext).out"' \;

Вот разбивка:

find /path/to/folder -maxdepth 1 -iname \*.ext

ищет все файлы, оканчивающиеся на .ext в /path/to/folder но не в подпапках. Часть -exec сообщает команде find, что делать с каждым найденным файлом. Каждый случай {} затем заменяется файлом. Шаблон

find /path/to/folder -iname \*.ext -exec echo "found this file: {}" \;

Как я уже сказал, {} расширяется до имени найденного файла. \; отмечает конец параметра -exec . В этом случае используется sh -c потому что в противном случае команда $(basename {} .ext) будет преждевременно расширена оболочкой. Поэтому мы заключаем его в одинарные кавычки, чтобы предотвратить расширение, и передаем его другому экземпляру оболочки. {} Будет расширен find , а остальная часть команды будет дословно передана sh . Команда

$(basename "filename.ext" .ext).out

удалит расширение из "filename.ext" и добавит расширение .out .

РЕДАКТИРОВАТЬ:

Я только что понял, как недоступна эта команда. Вот самая голая версия этого.

find . -name \*.ext -exec sh -c 'convert -input {} -output $(basename {} .ext).out' \;

Это почти подходит без прокрутки на этот раз. :)

2

Это зависит от того, что вы подразумеваете под «написанием сценария bash».  Ниже приведен скрипт bash, но вы можете просто ввести его в терминал, если хотите; Вам не нужно помещать это в файл:

cd directory_where_the files_are
for x in *.ext
do
        convert -input "$x" -output $(basename "$x" .ext).out
done

Это будет работать только на *.ext файлов в каталоге , который вы cd - диска.  Если вы также хотите искать в подкаталогах, find лучшее решение; например, используйте ответ Ниспио, но не -maxdepth 1 .


Редактировать: комментарий Хеннеса об ответе Ниспио применяется и здесь; ты мог бы сказать

for x in /path/to/folder/*.ext
do
        convert -input "$x" -output $(basename "$x" .ext).out
done

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .