Перемещение миллионов файлов в другой каталог с конкретными именами

10

У меня есть миллионы файлов со следующей номенклатурой на компьютере с 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 различных шаблонов имен файлов. Как мне их переместить.

Абрикос
источник
1
Bash говорит сам за себя: он пытается выполнить это имя файла, так как оно является первым в строке во 2-м этапе конвейера (ваш канал 2-го этапа:: | ??????????_a1ac*.jpgbash расширяет его до нескольких имен файлов, первое из которых 1559704165_a1ac6f55fef555ee.jpg- если вы в конечном итоге , на втором этапе конвейера, пытаясь выполнить: 1559704165_a1ac6f55fef555ee.jpg next_matching_filename 3rd_matching_filename ... nth_matching_filenameЯ полагаю, вы пытались вместо этого фильтровать по этому имени файла (см. ответы ниже)
Оливье Дюлак,

Ответы:

15

Вы должны использовать:

find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' \
-exec mv -t destination "{}" +

Это maxdepth 1значит, что вы хотите искать в текущем каталоге никаких подкаталогов.

type f значит найди только файлы.

name '??????????_a1ac*.jpg' шаблон, соответствующий файлу, который вы ищете.

mv -t destination "{}" +означает переместить соответствующие файлы в место назначения. Здесь +добавляет новые сопоставленные файлы к предыдущему, например:

mv -t dest a b c d

Здесь abcd - это разные файлы.

Prvt_Yadav
источник
Спасибо за краткий ответ на этот вопрос. Вместо того, чтобы просто выбросить решение, возможно, вы могли бы объяснить, как / что / почему. Вместо того, чтобы быть полезным для одного человека, один раз, это может быть полезно для всех, все время. Один и тот же вопрос задавался и отвечал бесчисленное количество раз за последние 40-50 лет. Проблема в том, что это никогда не объясняется хорошо. Научите человека ловить рыбу .. Тем временем: gnu.org/software/findutils/manual/html_node/find_html/… и, как это часто бывает, Википедия полезнее официальных документов: en.wikipedia.org/wiki/Find_ ( Unix)
голоса
Смотрите обновленный ответ.
Prvt_Yadav
Обратите внимание, что -tэто расширение GNU, поэтому оно может быть недоступно для других типов производных UNIX.
Кевин
Когда вы говорите: «Двойные кавычки предотвращают разбиение слов». Я предполагаю, что вы имеете в виду "{}", и в этом случае я хочу указать, что {}оболочка не раскрывается и не нуждается в кавычках. Оболочка проходит, {}чтобы найти, и находит, видит {}и заменяет его путями. Find exec не использует синтаксический анализатор оболочки и не разбивает слова самостоятельно. Цитирование не приносит никакого вреда, просто приведенное обоснование немного неточно.
jw013
@ jw013 спасибо.
Prvt_Yadav
11

Ваша команда,

find . -maxdepth 1 -type f | ??????????_a1ac*.jpg |xargs mv -t "/home/ubuntu/ntest"

Трубы список всех файлов ко всем файлам!

find . -maxdepth 1 -type f -name `*_a1ac*.jpg` -print0 |\
xargs  -0 -r mv -t "/home/ubuntu/ntest"

сделает свое дело.

waltinator
источник
1
большое спасибо ... ваше решение тоже сработало ... спасибо, что сообщили мне, где я ошибся
Абрикос
8

Ты очень близко. Вы должны использовать -nameопцию для find. И не забудьте процитировать шаблон.

Так

find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' |xargs mv -t "/home/ubuntu/ntest"
Стивен Харрис
источник
Большое спасибо ... ваше решение тоже сработало ... дополнительное спасибо, что сообщили мне, что я близок к решению .... это мотиватор для новичка, как я
Абрикос
1
Вы должны добавить в -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-подобной
Оливье Дюлак
2

Не так «хорошо», как findрешения, но другое правильное решение - сделать mvкоманды более детализированными.

Это делает 4096 перемещений, с меньшим количеством файлов, перемещаемых за mvоперацию.

FILEPAT=a1ac
for i in $(seq $((0x000)) $((0xfff))); 
do 
   H=$(printf '%x\n' $i)
   mv 1559704165_${FILEPAT}${H}*.jpg /home/ubuntu/ntest
done
RonJohn
источник
Это умный взлом для тех, кто без find(по любой причине).
лес
-1

Если вы хотите переместить файлы на той же хост-системе, что, как я полагаю, вы делаете с вашей mv, rsyncможет быть более быстрым вариантом:

rsync -av --inplace -W /source/??????????_a1ac*.jpg /home/ubuntu/ntest/

--inplaceи -Wнастроены на ускорение процесса.

Если это приведет к слишком длинной ошибке в другом списке аргументов, вы можете передать спискиrsync

Составьте список с помощью find, например

find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txt

и дать это rsync

rsync -av --inplace -W --files-from=/tmp/my_image_list.txt /path/to/files /home/ubuntu/ntest/

Источник здесь /path/to/files, потому что rsyncбудет относиться к списку, который вы даете, относительно вашего источника.


Дело в том, что: rsyncбыстрее, чем mvесли файлы не находятся в одной файловой системе .

Роберт Ридл
источник
Это, вероятно, приведет к той же самой ошибке «список аргументов слишком длинный», о которой упоминал OP
Grump
@Grump, чтобы избежать этого, OP может написать список файлов для копирования в файл, то есть, find . -maxdepth 1 -type f -name '??????????_a1ac*.jpg' > /tmp/my_image_list.txtа затем передать его в rsync с помощью --files-from=/tmp/my_image_list.txt. Дело в том, что rsyncэто быстрее. Если файлы не находятся в одной файловой системе, которую OP не указал.
Роберт Ридл
@RobertRiedl: вы должны отредактировать свой ответ и добавить эту информацию. Комментарии могут быть непостоянными.
19
@NickD, я обновил свой ответ.
Роберт Ридл