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

Если вы хотите запустить команду в фоновом режиме и иметь файловый дескриптор для отправки данных через канал.

С помощью zshили bashвы можете использовать перенаправление на подстановку процесса.

exec 3> >(cmd)

А затем отправить вывод с помощью:

echo something >&3

И укажите конец -файла -с помощью exec 3>&-.

Порог с помощью zshи bash, также можно сделать:

{ coproc cmd >&3 3>&-; } >&3

Это запуск cmdкак со-процесс, который запускает процесс с двумя каналами, один для ввода, один для вывода, но здесь, поскольку нам нужен только один для ввода, мы восстанавливаем cmd' s stdout на остальную часть оболочки.

Для отправки вывода:

echo something >&p # with zsh
echo something >&"${COPROC[1]}" # with bash

С помощью yashвы можете использовать перенаправление процесса:

exec 3>(cmd)

С любой борновской -оболочкой всегда можно сделать:

{ {
  echo something >&3
  echo whatever
 ...
} 3>&1 >&4 4>&- | cmd; } 4>&1

Это не совсем то же самое, что запускать cmdв фоновом режиме и запускать команды, которые отправляют свои выходные данные в cmd, поскольку эти команды выполняются в подоболочке, а для интерактивных оболочек cmdтакже находится на переднем плане (. ] на него влияет, например, Ctrl+C ), но кроме этого, он в основном функционально эквивалентен.

10
06.07.2019, 16:56
5 ответов

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

Так

find. -maxdepth 1 -type f -name '??????????_a1ac*.jpg' |xargs mv -t "/home/ubuntu/ntest"
8
27.01.2020, 19:59

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

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"

поможет.

11
27.01.2020, 19:59

Не так «хорошо», как решения 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
2
27.01.2020, 19:59

Если вы хотите переместить файлы в той же хост-системе, что, как я полагаю, вы делаете со своим 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, если файлы не находятся в одной и той же файловой системе .

-2
27.01.2020, 19:59

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

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

Здесь a b c d — разные файлы.

15
27.01.2020, 19:59

Теги

Похожие вопросы