У меня есть миллионы файлов со следующей номенклатурой на компьютере с Linux:
1559704165_a1ac6f55fef555ee.jpg
Первые 10 цифр являются метками времени, а те, за которыми _
следует символ a, являются конкретными идентификаторами. Я хочу переместить все файлы, соответствующие конкретным идентификаторам имен файлов, в другую папку.
Я попробовал это в каталоге с файлами
find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"
Однако я получаю сообщение об ошибке:
bash 1559704165_a1ac6f55fef555ee.jpg: command not found
Когда я пытался, mv ??????????_a1ac*.jpg
я получаю список аргументов слишком длинная ошибка. У меня есть как минимум 15 различных шаблонов имен файлов. Как мне их переместить.
| ??????????_a1ac*.jpg
bash расширяет его до нескольких имен файлов, первое из которых1559704165_a1ac6f55fef555ee.jpg
- если вы в конечном итоге , на втором этапе конвейера, пытаясь выполнить:1559704165_a1ac6f55fef555ee.jpg next_matching_filename 3rd_matching_filename ... nth_matching_filename
Я полагаю, вы пытались вместо этого фильтровать по этому имени файла (см. ответы ниже)Ответы:
Вы должны использовать:
Это
maxdepth 1
значит, что вы хотите искать в текущем каталоге никаких подкаталогов.type f
значит найди только файлы.name '??????????_a1ac*.jpg'
шаблон, соответствующий файлу, который вы ищете.mv -t destination "{}" +
означает переместить соответствующие файлы в место назначения. Здесь+
добавляет новые сопоставленные файлы к предыдущему, например:Здесь abcd - это разные файлы.
источник
-t
это расширение GNU, поэтому оно может быть недоступно для других типов производных UNIX."{}"
, и в этом случае я хочу указать, что{}
оболочка не раскрывается и не нуждается в кавычках. Оболочка проходит,{}
чтобы найти, и находит, видит{}
и заменяет его путями. Find exec не использует синтаксический анализатор оболочки и не разбивает слова самостоятельно. Цитирование не приносит никакого вреда, просто приведенное обоснование немного неточно.Ваша команда,
Трубы список всех файлов ко всем файлам!
сделает свое дело.
источник
Ты очень близко. Вы должны использовать
-name
опцию дляfind
. И не забудьте процитировать шаблон.Так
источник
-print0
качестве последнего аргумента для поиска (вместо значения по умолчанию: -print) и добавить в-0
качестве первого параметра в xargs (то есть:)xargs -0 mv -t "/home/ubuntu/ntest"
. таким образом, все виды странных имен файлов (с пробелами в нем, с "новой строкой" и т. д.) могут быть обработаны.find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' -print0 |xargs -0 mv -t "/home/ubuntu/ntest"
(работает только с GNU-подобнойНе так «хорошо», как
find
решения, но другое правильное решение - сделатьmv
команды более детализированными.Это делает 4096 перемещений, с меньшим количеством файлов, перемещаемых за
mv
операцию.источник
find
(по любой причине).Если вы хотите переместить файлы на той же хост-системе, что, как я полагаю, вы делаете с вашей
mv
,rsync
может быть более быстрым вариантом:--inplace
и-W
настроены на ускорение процесса.Если это приведет к слишком длинной ошибке в другом списке аргументов, вы можете передать списки
rsync
Составьте список с помощью find, например
и дать это
rsync
Источник здесь
/path/to/files
, потому чтоrsync
будет относиться к списку, который вы даете, относительно вашего источника.Дело в том, что:
rsync
быстрее, чемmv
если файлы не находятся в одной файловой системе .источник
find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txt
а затем передать его в rsync с помощью--files-from=/tmp/my_image_list.txt
. Дело в том, чтоrsync
это быстрее. Если файлы не находятся в одной файловой системе, которую OP не указал.