Копирование типа файла в указанных каталогах c в другой каталог - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть файл .txt, который содержит список каталогов. Я хочу сделать сценарий, который проходит через этот файл .txt, копирует что-либо в каталоге, который указан для определенного типа файла, в другой каталог.

Я никогда не делал этого с каталогами, только с файлами.

Как мне отредактировать этот простой скрипт для чтения списка каталогов, поиска файла .csv и копирования его в другой каталог?

cat filenames.list | \
while read FILENAME
do
  find . -name "$FILENAME" -exec cp '{}' new_dir\;
done

Ответы [ 4 ]

1 голос
/ 12 февраля 2020
for DIRNAME in $(dirname.list); do find $DIRNAME -type f -name "*.csv" -exec cp \{} dest \; ; done;

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

for DIRNAME in $(dirname.list); do cp $DIRNAME/*.csv dest ; done
0 голосов
/ 12 февраля 2020

Учитывая find возможность обрабатывать несколько папок и предполагая, что цель состоит в том, чтобы "свести" все CSV-файлы в одно место назначения, учтите следующее.

Обратите внимание, что предполагается, что имена папок не имеют специальных символов (включая пробелы, символы табуляции, новые строки и т. д. c).

Дополнительным преимуществом является уменьшение количества вызовов cp, что делает процесс эффективным для большого количества файлов / папок.

find $(<filename.list) -name '*.csv' | xargs cp -t DESTINATION/

В более сложном случае, когда имена папок / имена файлов могут быть любыми (включая пробел, '*' и т. Д. c.), Рассмотрите возможность использования разделителя NUL (-print0 и -0).

xargs -I{} -t find '{}' -name '*.csv' <dd -print0 | xargs -0 -I{} -t cp -t new/ '{}'

, который будет разветвляться кратно find и кратно cp.

0 голосов
/ 12 февраля 2020

Использование поиска внутри некоторое время l oop работает, но поиск будет выполняться в каждой строке файла, другой альтернативой является сохранение списка в массиве, так что find может искать каталоги в списке в одном поиске.

Если у вас есть bash4 +, вы можете использовать mapfile.

mapfile -t directories < filenames.list

Если вы застряли в bash3.

directories=()
while IFS= read -r line; do
  directories+=("$lines")
done < filenames.list

Теперь, если вы только после одного файла введите похожие файлы, заканчивающиеся на *.csv.

find "${directories[@]}" -type f -name '*.csv' -exec sh -c 'cp -v -- "$@" /newdirectory' _ {} +

Если у вас есть несколько типов файлов для сопоставления и несколько каталогов для копирования файлов.

while IFS= read -r -d '' file; do
  case $file in
    *.csv) cp -v -- "$file" /foodirectory;;  ##: csv file copy to foodirectory
    *.mp3) cp -v -- "$file" /bardirectory;;  ##: mp3 file copy to bardirectory
    *.avi) cp -v -- "$file" /bazdirectory;;  ##: avi file copy to bazdirectory
  esac
done < <(find "${directories[@]}" -type f -print0)

find print0 будет работать с прочитайте -d '' при работе с файлами с пробелами и переводами строки. см. Как мне найти и обработать имена файлов, содержащие переводы строк, пробелы или оба?

-- есть, так что если у вас есть проблемное c имя файла, которое начинается с da sh - cp не будет интерпретировать его как option.

0 голосов
/ 12 февраля 2020

Несмотря на имя файла списка filenames.list, позвольте мне предположить, что файл содержит список имен каталогов, а не имен файлов. Затем попробуйте:

while IFS= read -r dir; do
    find "$dir" -type f -name "*.mp3" -exec cp -p -- {} new_dir \;
done < filenames.list

Команда find ищет в "$ dir" файлы с расширением .mp3, затем копирует их в new_dir.
Сценарий выше не волнует дублирование имен файлов. Если вы хотите сохранить исходное дерево каталогов и / или вам нужна контрмера для дублирования имен файлов, пожалуйста, дайте мне знать.

...