Я пытаюсь запустить команду, похожую на приведенную ниже, в скрипте bash. Он должен искать во всех подпапках $sourcedir
и копировать все файлы определенного типа на корневой уровень $targetdir
.
#!/bin/bash
# These are set as arguments to the script, not hard-coded
sourcedir="/path/to/sourcedir"
targetdir="/path/to/targetdir"
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2/`basename "$1"`"' "{}" "$targetdir" \;
Это, кажется, довольно близко, за исключением того, что {}
не передается в $2
отношении-exec sh -c ...
Я хотел бы сделать это как можно ближе к «правильному пути», с допуском для специальных символов в именах файлов (особенно символы одинарных кавычек).
Изменить: я вижу людей, предлагающих использовать xargs
или цепочки аргументов. У меня сложилось впечатление, что это нормально только для ограниченного числа аргументов. Если у меня есть, например, тысячи файлов .jpg, которые я пытаюсь скопировать из нескольких каталогов галерей в гигантский каталог слайд-шоу, будут ли работать решения, объединяющие аргументы?
Изменить 2: Моя проблема заключалась в том, что я пропустил _
перед моей первой опцией sh в -exec
команде. Для тех, кому интересно, как заставить команду find работать, добавьте _
и все будет хорошо:
find "$sourcedir" -type f -name "*.type" -exec sh -c 'cp "$1" "$2"' _ "{}" "$targetdir" \;
Я принял ответ ниже, потому что он выполняет ту же задачу, но более эффективен и элегантен.
xargs
был создан, чтобы автоматически обрабатывать огромное количество аргументов в обычных командах, имеющих ограничения. Также следует учитывать, что большинство пределов максимального аргумента были значительно улучшены для стандартных утилит GNU. Вы также увидите выигрыш в производительности, избегая всех тех разветвлений процессов, которые важны для тысяч файлов.