#pipe #exec #xargs
#канал #exec #xargs
Вопрос:
Как следует из названия, я пытаюсь отсортировать изображения по папкам в зависимости от того, какая камера использовалась для их съемки. Я усердно работал над тем, чтобы научиться использовать каналы и xargs, и я думаю, что я почти у цели. Единственная проблема заключается в том, что последние xargs, похоже, выполняются только после того, как awk прошел через всю папку, а не для каждого файла. Если я сделаю:
find temp/sorted/jpg_over_300px/ -type f -exec identify -quiet -format '%[EXIF:model] %i n' '{}' ; | gawk '$2=="SE" {print $3}'
Я получаю хорошие чистые результаты, новые строки по мере нахождения файлов, а модель камеры exif соответствует «SE» для iPhone SE. Но если я добавлю xargs -I % mv % [new_folder]
команду для перемещения файлов в другую папку, mv будет выполнен только после полного сканирования всей папки (я знаю, потому что я пробовал с папкой, содержащей только один файл).).
find temp/sorted/jpg_over_300px/ -type f -exec identify -quiet -format '%[EXIF:model] %i n' '{}' ; | gawk '$2=="SE"{print $3}' | xargs -I % mv % temp/sorted/jpg_iphone_se/
Я хочу избежать этого, поскольку в моей папке МНОГО файлов, и я хочу избежать ситуации «слишком много аргументов». Я попытался добавить -print0 для поиска и -0 для xargs, но безуспешно.
Спасибо за ваше время
Ответ №1:
Отсортировано, благодаря [этому вопросу] [https://unix.stackexchange.com/questions/336184/use-output-from-awk-as-input-for-mv ]
Я также выполнил некоторую очистку и перенаправление stderr, чтобы отправлять только действительные запросы в awk.
find temp/sorted/jpg_over_300px/ -type f -exec identify -format '%[EXIF:model] %in' '{}' ; 2> /dev/null | awk '/iPhone 5S/ {system("cp "$3" temp/sorted/jpg_iphone_5s")}'
Для людей, которые учатся, как я, вот это шаг за шагом:
find temp/sorted/jpg_over_300px/ -type f -exec identify -format '%[EXIF:model] %in' '{}' ;
Используйте команду find
, просматривайте папку temp/sorted/jpg_over_300px/
только для файлов -type f
и каждый раз, когда они найдены, выполняйте команду identify -exec identify
для извлечения данных exif, касающихся модели камеры -format '%[EXIF:model]'
и имени файла ‘%i’ плюс символ n
новой строки, чтобы отправить результаты в правильном формате в остальную часть канала. Прежде чем перейти к остальной части канала, мы избавляемся от сообщений об ошибках, перенаправляя stderr в черную дыру 2>/dev/null
, затем мы подключаемся к awk | awk
, который будет искать iPhone SE в данных, передаваемых по каналу '/iPhone 5S/
, и выполняет системную команду cp для копирования файлов в новую папку {system("cp "$3" temp/sorted/jpg_iphone_5s")}'