Как назвать имена каталогов после передачи их всех в xargs?

0

Я использую find для передачи всех каталогов в xargs, и команда для каждого каталога в xargs должна создать для каждого новый каталог, похожий на dirname_a, так как это можно сделать?

т.е.

find . -type d -print0 | xargs -0 mkdir ${DIR}_a && mogrify -path ${DIR}_a -resize '1200x1200>' -quality 95 ${DIR}/*{.jpg|.JPG} {} \;

$ {DIR} не работает, так как это должно быть неправильно

я могу использовать

for D in ./* ; do mkdir ${D}_a && mogrify -path ${D}_a -resize '1200x1200>' -quality 95 ${D}/*{.jpg|.JPG}; done

но это не будет работать ни для каталогов, ни для файлов с пробелами в именах, поэтому я искал find с xargs.

mozerella
источник
Как правило, вы получите лучшие ответы, если действительно объясните, что вы пытаетесь сделать. Не все знакомы с инструментами imagemagick и shell, чтобы понять, что вы пытаетесь сделать. Даже для тех из нас, кто не является, нелегко расшифровать то, что вы опубликовали.
Terdon

Ответы:

1

Вот хороший трюк xargs с комбинацией параметров -Iи -n1.

find . -mindepth 1 -type d | xargs -n1 -I {} bash -c 'mkdir "{}_a" && mogrify -path "{}_a" -resize 1200x1200\> -quality 95 "{}/"*.{jpg,JPG}'

-I {}говорит xargs сделать замену, когда находит {}строку в команде. -n1говорит xargs обрабатывать результаты поиска одна строка за одной.

Вы хотите создать несколько экземпляров mogrify, вы можете добавить -P5параметр в xargs.

Это приведет к 5 процессам за раз и значительно сократит время обработки, особенно если у вас есть много изображений для конвертации.

Тони
источник
теперь это впечатляет. а ты использовал xargs, о чем и был мой вопрос. хорошая работа.
mozerella
1

Не используйте xargs. Вместо этого попробуйте цикл:

find . -mindepth 1 -type d | 
 while IFS= read -r dir; do mkdir "$dir"_a && 
  mogrify -path "$dir"_a -resize '1200x1200>' -quality 95 "$dir/"*.{jpg,JPG}; \
 done
terdon
источник
1

Если строка, хранящаяся в переменной, может содержать пробелы, вы должны поместить двойные кавычки вокруг переменной, то есть

for D in ./* ; do mkdir "$D"_a && .... ; done
Uwe
источник
Это тоже хорошо работает сейчас, с цитатами, спасибо Uwe
mozerella