Назад | Перейти на главную страницу

Linux (mv или cp) конкретные файлы из текстового списка файлов?

У меня есть каталог с множеством файлов, что-то вроде 50 000 PDF-файлов и других файлов на сервере. Мне нужно переместить определенные в другой каталог. Я могу создать список файлов, которые нужно переместить, в формате csv или в любом другом текстовом формате.

Что мне нужно сделать, так это запустить сценарий bash и переместить или скопировать файлы, перечисленные в текстовом файле, в другой каталог.

Есть ли простой способ сделать это? Мы будем очень благодарны за любые предложения или ресурсы.

Во избежание бесполезного использования cat (и если вы не используете rsync):

xargs -a file_list.txt mv -t /path/to/dest

Это будет обрабатывать любое допустимое имя файла, если оно не содержит новую строку, если файлы перечислены по одному на строку.

rsync имеет несколько параметров, которые могут принимать список файлов для обработки (--files-from, --include-from, и т.д.).

Например, это поможет:

rsync -a /source/directory --files-from=/full/path/to/listfile /destination/directory
for file in `cat listoffiles`; do mv "$file" /path/of/destination ; done

предполагая bash, плюс listoffiles по одному файлу в строке. Мое единственное возражение против маршрута rsync состоит в том, что OP запрашивает метод перемещения файлов, а не их копирование. У rsync больше флагов, чем на королевской свадьбе, поэтому я уверен, что для этого можно доработать его, но иногда чем проще, тем лучше!

rsync --files-from=file_list.txt /path/to/source/ /path/to/dest/

Rsync имеет дополнительное преимущество перед cp или mv команд, потому что он автоматически создает папки, если они не существуют.

Это зависит от формата имеющегося у вас текстового файла. Например, если у вас есть список файлов, записанный таким образом, что каждый файл находится в новой строке. Вы можете использовать xargs, например:

$ cat your_text_file | xargs cp -t /path/to/destination

Также вы можете использовать find команда с -exec вариант. для копирования / перемещения файлов.

Я думаю, что ответ rsync лучше, но только для другого варианта:

tar -cf - -T FILE_OF_FILENAMES_TO_MOVE.txt |(cd /path/to/new/dir && tar -xvf -)

Если (и только если) у вас нет каких-либо неприятных символов в именах файлов (пробелы, символы новой строки, которые могут запутать xargs в том, как разбить вещи на отдельные аргументы), и вы создаете список файлов, разделенных символами новой строки (один файл на строку), вы можете сделать что-то вроде.

cat filenames.txt | xargs mv -t /path/to/move/files/to

(В общем, см. Человек xargs, это круто)

Если ваш конкретный mv не имеет опции -t, вы также можете проделать некоторые уловки, например

( cat filenames.txt; echo; echo /path/to/move/files/to ) | xargs mv

Примечание - ни один из них не будет работать должным образом, если в них есть имена файлов с символами новой строки.

Я случайно скопировал все содержимое каталога в целевой каталог вместо того, чтобы перемещать весь каталог. Это привело к тому, что вместо исходного каталога был добавлен в каталог загроможденный целевой каталог.

Чтобы исправить это, я сделал следующее:

ls -rt /path/to/cluttered/destination/directory/ > /opt/dircheck/filestomove Приведенная выше команда создает файл filestomove, который будет списком всего содержимого каталога назначения, отсортированного в обратном порядке по времени, то есть от самого старого к самому новому.

Затем я создал подкаталог теперь загроможденного целевого каталога, чтобы переместить в него материал.

mkdir /path/to/cluttered/destination/directory/newsubdirectory

Затем я повторил список каталогов, за исключением вывода на экран и отображения более подробной информации.

ls -lrht /path/to/cluttered/destination/directory/ В этой строке перечислены каталоги, отсортированные по дате по возрастанию (обратная сортировка по времени), и отображается дополнительная информация, включая отметку даты / времени каждого файла в теперь загроможденном целевом каталоге. Я обращаюсь к этому, начиная сверху, чтобы показать, какие каталоги и файлы я хочу сохранить на месте. В метке даты / времени файлов, где начинаются все новые файлы, будет пробел, которого там быть не должно.

Затем я отредактировал файл filestomove, созданный на первом шаге выше (который отсортирован по дате), и удалил несколько из списка, которые были там ранее, которые я хочу оставить из исходного каталога.

vim /opt/dircheck/filestomove Удалите сверху все файлы, которые не хотите перемещать.

Затем я использовал команду, указанную ранее в этом посте, чтобы переместить файлы из моего списка в новый созданный мной каталог.

sudo xargs -a /opt/dircheck/filestomove mv -t /path/to/cluttered/destination/directory/newsubdirectory

Это переместило все файлы за доли секунды. (Примечание: вам может не понадобиться sudo в начале, это вопрос прав доступа к файлам).

Теперь мой исходный целевой каталог красив и чист и содержит новый каталог со всеми файлами и каталогами, которые его загромождали.

Попробуйте что-нибудь вроде:

cat list.txt | while read line; do mv "$line" /images; done

Следующее сработало для меня, когда мне нужно было скопировать все файлы PNG с определенного пути (и все подкаталоги) в новое место с сохранением структуры каталогов:

rsync -av --prune-empty-dirs --include='*/' --include='*.png' --exclude='*' source/ destination/

Поскольку RSYNC сначала создает зеркало структуры каталогов, а затем синхронизирует файлы, вы можете получить лишние папки, которые будут пустыми. Я использовал флаг --prune-empty-dirs, чтобы удалить эти пустые каталоги.

Я не имею отношения к организации, но счел правильным отдать должное источнику, который вдохновил это решение: http://techblog.zabuchy.net/2011/transfer-only-selected-file-types-with-rsync/