Ну, с одной стороны, -i
переключатель не рекомендуется:
-i[replace-str]
This option is a synonym for -Ireplace-str if replace-str is specified.
If the replace-str argument is missing, the effect is the same as -I{}.
This option is deprecated; use -I instead.
Поэтому, когда я изменил вашу команду на это, это сработало:
$ find /foo/bar -name '*.mp4' -print0 | xargs -I{} -0 mv -t /some/path {}
пример
$ find . -print0 | xargs -I{} -0 echo {}
.
./.sshmenu
./The GIT version control system.html
./.vim_SO
./.vim_SO/README.txt
./.vim_SO/.git
./.vim_SO/.git/objects
./.vim_SO/.git/objects/pack
./.vim_SO/.git/objects/pack/pack-42dbf7fe4a9b431a51da817ebf58cf69f5b7117b.idx
./.vim_SO/.git/objects/pack/pack-42dbf7fe4a9b431a51da817ebf58cf69f5b7117b.pack
./.vim_SO/.git/objects/info
./.vim_SO/.git/refs
./.vim_SO/.git/refs/tags
...
Использование -I{}
Этот подход не должен использоваться после запуска этой команды:
$ find -print0 ... | xargs -I{} -0 ...
неявно включает эти переключатели в xargs
, -x
и -L 1
. В -L 1
конфигурирует xargs
так , что он звонит команды , которые вы хотите запустить файлы через в одной моде.
Таким образом, это лишает смысла использование xargs
здесь, поскольку, если вы дадите ему 1000 файлов, он будет запускать mv
команду 1000 раз.
Так какой подход я должен использовать тогда?
Вы можете сделать это, используя xargs вот так:
$ find /foot/bar/ -name '*.mp4' -print0 | xargs -0 mv -t /some/path
Или просто найти сделать все это:
$ find /foot/bar/ -name '*.mp4' -exec mv -t /some/path {} +
"This approach shouldn't be used"
какой подход следует использовать вместо этого? Было"find /foot/bar/ -name '*.csv' -print0 | xargs -0 mv -t some_dir'"
бы лучшим решением? Если да, то как жеxargs
знать в этом случае , когда вmv
команде кормиться аргументов он получает из трубы? (это всегда ставит их в последний раз?)find ... -exec ...
лучшим путем , или если вы хотите использовать это тоже хорошо. Да, это всегда ставит их в последнюю очередь. Вот почему этот метод нуждается в .xargs
find ... | xargs ... mv -t ...
-t
Опция
-i
принимает необязательный аргумент. Поскольку вы ставите пробел после-i
, у-i
опции не было аргумента, и поэтому последующий-0
был не опцией,xargs
а вторым из 6 операндов{} -0 mv -t /some/path {}
.При наличии только этой опции
-i
xargs ожидал разделенный символом новой строки список имен файлов. Поскольку во входных данных, вероятно, не было новой строки, xargs получил то, что выглядело как огромное имя файла (со встроенными нулевыми байтами, но xargs этого не проверял). Эта единственная строка, содержащая весь вывод,find
была длиннее максимальной длины командной строки, поэтому возникла ошибка «слишком длинная командная строка».Ваша команда работала бы
-i{}
вместо-i {}
. В качестве альтернативы вы могли бы использовать-I {}
:-I
аналогично-i
, но принимает обязательный аргумент, поэтому следующий аргумент, переданный в,xargs
используется в качестве аргумента-I
опции. Затем аргумент после этого-0
интерпретируется как опция и так далее.Тем не менее, вы не должны использовать
-I {}
вообще. Использование-I
имеет три эффекта:-I
отключает обработку цитаты, которая-0
уже делает.-I
изменяет строку для замены, но{}
является значением по умолчанию.-I
заставляет команду выполняться отдельно для каждой входной записи, что здесь бесполезно, поскольку ваша команда (mv -t
) специально предназначена для работы с несколькими файлами за вызов.Либо капля
-I
и-i
вообщеили бросьте xargs и используйте
-exec
:источник
Попробуйте использовать цикл для bash:
или если вы хотите посмотреть, что происходит:
источник
Если вы видите это при использовании раковины рыбы .
Это относится к тому, как рыба расширяет замещающую нить
{}
Если вы используете рыбу, вам нужно избежать замены строки
\{\}
или используйте другую строку замены
источник