Копирование файлов из ряда каталогов на основе списка в текстовом файле - PullRequest
1 голос
/ 28 мая 2019

Я пытаюсь использовать rsync или cp в цикле for для копирования файлов, соответствующих списку из 200 имен, сохраненных в новых строках в файле .txt, которые соответствуют именам файлов с .pdbqt расширение, которое находится в серии подкаталогов с одной родительской папкой. Файл .txt выглядит следующим образом:

file01
file02
file08
file75
file45
...

Я попытался использовать rsync со следующей командой:

rsync -a /home/ubuntu/Project/files/pdbqt/*/*.pdbqt \
--files-from=/home/ubuntu/Project/working/output.txt \
/home/ubuntu/Project/files/top/

Когда я запускаю команду rsync, я получаю:

rsync error: syntax or usage error (code 1) at options.c(2346) [client=3.1.2]

Я написал скрипт bash следующим образом, пытаясь заставить его работать:

#!/bin/bash
for i in "$(cat /home/ubuntu/Project/working/output.txt | tr '\n' '')"; do
    cp /home/ubuntu/Project/files/pdbqt/*/"$i".pdbqt /home/ubuntu/Project/files/top/;
done

Я понимаю, cat не очень хорошая команда для использования, но я не мог найти альтернативное решение, так как я все еще плохо знаком с использованием bash. При запуске я получаю следующую ошибку:

tr: when not truncating set1, string2 must be non-empty
cp: cannot stat '/home/ubuntu/Project/files/pdbqt/*/.pdbqt': No such file or directory

Я предполагаю, что ошибка cp выдается в результате ошибки tr, но я не уверен, как еще избавиться от \n, считываемого из списка, разделенного новой строкой.

Ожидаемые результаты состоят в том, что из подкаталогов в /pdbqt/ с файлами 12000 .pdbqt 200 файлов из списка output.txt будут скопированы из этих подкаталогов в каталог /top/.

Ответы [ 3 ]

0 голосов
/ 28 мая 2019

Есть ли у директорий в Project/files/pdbqt/* или файлах *.pdbqt тире (-) в имени?

Ошибка показывает строку в исходном коде rsync options.c"Your options have been rejected by the server.\n"

, что заставляет меня думать, что это интерпретирует inode (файлы / dirs) в вашем глобусе как параметры rsync.

for i in $( < /home/ubuntu/Project/working/output.txt LC_CTYPE=C tr '\n' ' ' )
do
  cp /home/ubuntu/Project/files/pdbqt/*/"${i}.pdbqt" /home/ubuntu/Project/files/top/
done

Я думаю, что ваш кот пропустил пробел

cat /home/ubuntu/Project/working/output.txt | tr '\n' ' '

John1024 использует while и read лучше, чем у меня.

0 голосов
/ 28 мая 2019

Вы думаете правильно думать rsync. rsync предоставляет опцию --files-from="yourfile", которая будет rsync всех файлов в вашем textfile (относительно базового каталога, который вы укажете далее) до места назначения (либо host:/dest/path, либо локально только с /dest/path)

Вы захотите указать --no-R, чтобы указать rsync не использовать относительные имена файлов, поскольку --files-from= принимает базовый путь в качестве следующего аргумента. Например, чтобы перенести все файлы в вашем текстовом файле на некоторый удаленный хост, где расположение указанных файлов находится в текущем каталоге, вы можете использовать:

rsync -uai --no-R --files-from="textfile" ./ host:/dest/path

Где команда по существу указывает, что вы читаете имена для передачи из textfile, где файлы будут найдены в ./ (текущий каталог), и вы будете передавать файлы в host:/dest/path в указанном host , Вы можете увидеть man 1 rsync для получения полной информации.

0 голосов
/ 28 мая 2019

for циклы хороши, когда ваши данные уже находятся в переменных оболочки.При чтении данных из файла циклы while ... read работают лучше.В вашем случае попробуйте:

while IFS= read -r file; do  cp -i -- /home/ubuntu/Project/files/pdbqt/*/"$file".pdbqt  /home/ubuntu/Project/files/top/; done </home/ubuntu/Project/working/output.txt

или, если вы находите многострочную версию более читабельной:

while IFS= read -r file
do
    cp -i -- /home/ubuntu/Project/files/pdbqt/*/"$file".pdbqt /home/ubuntu/Project/files/top/
done </home/ubuntu/Project/working/output.txt

Как это работает

  • while IFS= read -r file; do

    Запускает цикл while, считывающий по одной строке за раз.IFS= говорит bash не обрезать пустое пространство от линии, а -r говорит read не искажать обратную косую черту.Строка сохраняется в переменной оболочки с именем file.

  • cp -i -- /home/ubuntu/Project/files/pdbqt/*/"$file".pdbqt /home/ubuntu/Project/files/top/

    . Копирует файл.-i говорит cp спросить перед перезаписью существующего файла.

  • done </home/ubuntu/Project/working/output.txt

    Это отмечает конец цикла while и говорит оболочке получить вход для цикла из /home/ubuntu/Project/working/output.txt

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