Используйте xargs для преобразования каталога из результатов поиска в другой каталог
У меня есть следующая команда:
find . -type d -mtime 0 -exec mv {} /path/to/target-dir ;
Это приведет к перемещению каталога, основанного в другой каталог. Как я могу использовать xargs
вместо exec
, чтобы сделать то же самое.
5 ответов:
Если у вас есть GNU
mv
(иfind
иxargs
), Вы можете использовать опцию-t
дляmv
(и-print0
дляfind
и-0
дляxargs
):find . -type d -mtime -0 -print0 | xargs -0 mv -t /path/to/target-dir
Обратите внимание, что современные версииfind
(совместимые с POSIX 2008) поддерживают+
вместо;
и ведут себя примерно так же, какxargs
без использованияxargs
:find . -type d -mtime -0 -exec mv -t /path/to/target-dir {} +
Это позволяет
find
группировать удобные номера имен файлов (каталогов) в один вызов программы. У вас нет такого уровня контроля по количеству аргументов, переданных вmv
, которые предоставляетxargs
, но это редко действительно нужно. Это все еще зависит от опции-t
для GNUmv
.
С BSD xargs (Для OS X и FreeBSD), вы можете использовать
-J
, который был построен для этого:find . -name some_pattern -print0 | xargs -0 -J % mv % target_location
, который переместит все, что соответствует
some_pattern
в.
вtarget_location
С GNU xargs (Для Linux и Cygwin), используйте
-I
вместо:find . -name some_pattern -print0 | xargs -0 -I % mv % target_location
Устаревший вариант
-i
GNU xargs подразумевает-I{}
и может использоваться следующим образом:Обратите внимание, что BSD xargs также имеет опциюfind . -name some_pattern -print0 | xargs -0 -i mv {} target_location
-I
, но это делает что-то еще.
find ./ -maxdepth 1 -name "some-dir" -type d -print0 | xargs -0r mv -t x/
Найти : при выборе опции
-print0
вывод закончится на '\0';Xargs : с опцией
-0
, он разделит args на '\0', но пробел,-r
означает no-run-if-empty, так что вы не получите никаких ошибок, еслиfind
не получил никакого вывода. (-r
Является расширением GNU.)Я обычно использую это в сценариях, когда я не уверен, существуют ли целевые файлы или нет.
find
это не очень хороший инструмент для этого. Я полагаю, вы хотите переместить все подкаталоги в другой каталог.find
выведет такие вещи, как./a ./a/b ./a/b/c ./a/b/c/d
После того, как
./a
будет перемещен первым, вы просто получите ошибки о "нет такого файла или каталога" все поддиры.Вы должны просто использовать
mv */ /another/place
- конечная косая черта на подстановочном знаке ограничивает расширение только dirs.
Если вы не используете GNU mv, вы можете использовать эту команду:
find . -depth -type d -mtime 0 -exec bash -c 'declare -a array;j=1;for i; do array[$j]="$i"; j=$((j+1));done; mv "${array[*]}" /path/to/target-dir' arg0 {} +
В противном случае, вот более простое решение, которое не требует xargs:
find . -depth -type d -mtime 0 -exec mv -t /path/to/target-dir {} +
Обратите внимание, что я добавил-глубина в противном случае вы будете иметь ошибки, когда и каталог и один из его подкаталогов должен быть обработан.