На этот вопрос уже есть ответ здесь:
mkdir dregsfolder
find /home/tony/Desktop/unsorted_files/ -maxdepth 1 -not \( -type d -or -iname "*.jpg" -or -iname "*.gif" -or -iname "*.docx" \)xargs -0 --no-run-if-empty mv /home/tony/Desktop/dregsfolder
Когда я запускаю этот код; Мне сообщили
find: paths must precede expression: )xargs
, что я смущен, так как я думал, что путь уже был указан с помощью / home / tony / Desktop / unsorted_files
.
Я запутался еще больше, потому что в этом вопросе на Unix & Linux Stack Exchange у нас есть пример xargs
копирования файлов в каталог с именем play
:
find /tmp/ -ctime -1 -name "x*" | xargs -I '{}' mv '{}' ~/play/
И здесь, похоже, целевой каталог, т.е. play; был указан ПОСЛЕ xargs
...
Мне нужны пояснения относительно точных механизмов, связанных с xargs
, и связанных с ними нюансов, для анализа ТОЛЬКО файл из каталога (как определено в предыдущем вопросе), но, кроме того, его более широкое использование в мире unix в отношении параметров.
xargs
попытки создать список аргументов из его stdin (стандартный вход). Часто, stdin xargs
вывод некоторой команды, которая была передана по каналу к xargs
. Для создания бесполезного примера мы можем потратить впустую много символов, перечисляющих файлы в нашем корневом каталоге вместо просто ввода ls -A ~
как это:
echo ~ | xargs ls -A
Оператор канала |
берет stdout (стандартный вывод) команды слева от него и передает его как stdin команды направо от него. Важно помнить, что stdout является просто потоком текста, который может вызвать проблемы при передаче второй команде xargs
если это содержит пробелы или специальные символы. Когда мы используем find
, чей вывод является именами файлов, с xargs
, для предотвращения ошибок, вызванных специальными символами, мы традиционно используем
find -print 0 | xargs -0
Это вызывает find
добавлять нулевой символ к каждому имени файла и xargs
интерпретировать список, как разграничено пустым указателем вместо разграниченного пространством. Нулевой символ не может появиться в именах файлов, таким образом, нет никакого шанса, что имя файла будет интерпретироваться как два имен файлов, если мы разграничим с нулевым символом.
Так как Вы пропустили символ вертикальной черты |
это разделяет и соединяет две команды find
и xargs
, find
мысль это )xargs
был один из его аргументов, и так как он не начался -
или следуйте за допустимым тестовым началом -
, это решило это )xargs
должен быть путь, который Вы хотите искать, но paths must precede expression
, синтаксис find
требует, чтобы путь искал, чтобы быть данным перед другими аргументами.
Многие люди предпочитают использовать -exec
с find
вместо того, чтобы передать по каналу к xargs
(см. то, Что различие между находкой с - должностное лицо и xargs?), например:
find /path -tests ... -exec some_command {} +
Это может более подойти в Вашем случае, особенно начиная с mv
команда ожидает, что ее последним аргументом будет место назначения. Вы могли использовать xargs -I {} mv {} /path/to/destination
но это было бы более читаемым и возможно более эффективным указать место назначения с -t
find /home/tony/Desktop/unsorted_files/ -maxdepth 1 -not \( -type d -or -iname "*.jpg" -or -iname "*.gif" -or -iname "*.docx" \) -exec mv -t /home/tony/Desktop/dregsfolder -- {} +
"find: paths must precede expression: )xargs
" find
способ сказать Вам, что, поскольку это обрабатывало свои параметры, он видел что-то, что похоже на начальную точку (на самом деле, это НЕ было похоже на выражение) ПОСЛЕ ТОГО, КАК это думало, что было сделано, анализируя пути к поиску, и это видело проблему вокруг")xargs
". man find
говорит find [-H] [-L] [-P] [-D debugopts] [-Olevel] [starting-point...] [expression]
Вы опустили канал (|
) символ для соединения find
вывод к xargs
вход.
Другая точка - Используя"-0
"опция к xargs
требует, чтобы Вы для сообщения нашли для разделения имен файлов с NUL
s, с -print0
- Вы не делаете.
Вы читали мой ответ на Движущиеся файлы определенного типа / расширение от одного каталога до другого??