Переміщення мільйонів файлів в інший каталог із специфічними шаблонами імен


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
Баш говорить все це: він намагається виконати це ім'я файлу, оскільки воно є першим у рядку на 2-й стадії труби (ваша труба 2-го ступеня | ??????????_a1ac*.jpg:: bash розширює його до кількох імен файлів, перше - 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 - це різні файли.


Дякуємо, що стисло відповіли на це питання. Замість того, щоб просто демпінгувати рішення, можливо, ви могли б пояснити, як / що / чому. Замість того, щоб бути корисним одній людині, один раз, вона може бути корисною всім, весь час. За одне і те ж питання було задано і відповіли незліченна кількість разів протягом останніх 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"

зробить трюк.


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

Це розумний злом для тих, хто без find(з будь-якої причини).
ліс

-1

Якщо ви хочете переміщувати файли в одній хост-системі, що, напевно, ви робите зі своєю mv, rsyncможе бути швидшим варіантом:

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

--inplaceі -Wналаштовані на пришвидшення процесу.

Якщо це призведе до занадто довгої помилки у списку аргументів, ви можете подавати списки доrsync

Складіть список, наприклад, з пошуку

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якщо файли не в одній файловій системі .


Це, ймовірно, вдарило до тієї самої "аргументації задовго" помилки згаданої ОП
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: ви повинні відредагувати свою відповідь та додати цю інформацію. Коментарі можуть бути постійними.
NickD

@NickD, я оновив свою відповідь.
Роберт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.