14

У меня есть несколько больших файлов на оптическом носителе, которые я хотел бы скопировать в несколько целей - в этом случае у меня есть два жестких диска, подключенных к одному компьютеру. Есть ли утилита, которая может функционировать как:

copy source target1 target2 ... targetN

7 ответов7

22

Для отдельных файлов вы можете использовать tee для копирования в несколько мест:

cat <inputfile> | tee <outfile1> <outfile2> > <outfile3>

или если вы предпочитаете демоггифицированную версию:

tee <outfile1> <outfile2> > <outfile3> < <inputfile>

Обратите внимание , что , как Деннис указывает на комментарии tee выходов на stdout а также перечисленных файлов, поэтому с помощью перенаправления , чтобы указать на файл 3 в приведенных выше примерах. Вы также можете перенаправить это в /dev/null как показано ниже - это имеет преимущество, заключающееся в том, что список файлов более согласован в командной строке (что может облегчить написание сценария решения для переменного числа файлов), но это немного меньше эффективный (хотя разница в эффективности невелика: примерно такая же, как разница между использованием версии cat или версии без cat):

cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null

Вероятно, вы могли бы объединить одно из вышеперечисленного с find довольно легко для работы с несколькими файлами в одном каталоге и менее легко для работы с файлами, распределенными по структуре каталога. В противном случае вам может потребоваться отключить одновременное выполнение нескольких операций копирования в качестве отдельных задач и надеяться, что кэш диска ОС будет достаточно ярким и / или достаточно большим, чтобы каждая из параллельных задач использовала кэшированное чтение данных с первого, а не вызывало головку диска. обмолота.

НАЛИЧИЕ: tee обычно доступен на стандартных установках Linux и других unix- или unix-подобных системах, обычно в составе пакета "coreutils" GNU. Если вы используете Windows (ваш вопрос не указан), вы должны найти его в различных портах Windows, таких как Cygwin.

ИНФОРМАЦИЯ О ПРОГРЕССЕ. Поскольку копирование большого файла с оптического носителя может занять некоторое время (или по медленной сети, или даже по более крупному файлу даже с локального быстрого носителя), информация о ходе может быть полезной. В командной строке я обычно использую средство просмотра каналов (доступно в большинстве дистрибутивов Linux и во многих коллекциях портов Windows и легко компилируется там, где оно недоступно напрямую) - просто замените cat на pv следующим образом:

pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
5

Для Windows:

n2ncopy сделает это:

альтернативный текст

Для Linux:

Одна только команда cp может копировать из нескольких источников, но, к сожалению, не из нескольких мест назначения. Вам нужно будет запустить его несколько раз в каком-то цикле. Вы можете использовать цикл вроде так и поместить все имена каталогов в файл:

OLDIFS=$IFS
IFS=$'\n'

for line in $(cat file.txt):
do
   cp file $line
done

IFS=$OLDIFS

или используйте Xargs:

echo dir1 dir2 dir3 | xargs -n 1 cp file1

Оба из них позволят вам скопировать целые каталоги / несколько файлов. Это также обсуждается в этой статье StackOverflow.

4

Исходя из ответа на аналогичный вопрос Другой способ - использовать GNU Parallel для одновременного запуска нескольких экземпляров cp :

parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3

Приведенная выше команда копирует file1 во все три папки назначения параллельно

2

В bash (Linux, Mac или Cygwin):

cat source | tee target1 target2 >targetN

(т. е. копирует входные данные в STDOUT, поэтому используйте перенаправление на последнюю цель).

В Windows Cygwin часто бывает излишним. Вместо этого вы можете просто добавить exe- файлы из проекта UnxUtils , которые включают cat, tee и многие другие.

1

Решение Райана Томпсона:

for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;

имеет большой смысл: если скорость записи целевых каталогов примерно одинакова, то srcfile будет считан с диска только один раз. В остальное время он будет читаться из кеша.

Я бы сделал это немного более общим, поэтому вы также получите подкаталоги:

for x in dest1 dest2 dest3; do cp -a srcdir $x &; done; wait;

Если скорость записи папок dest очень различна (например, одна находится на оперативном диске, а другая - в NFS), то вы можете увидеть, что части чтения srcdir при копировании srcdir в dest1 больше не находятся в кеше диска при записи dest2.

1

Согласно этому ответу: https://superuser.com/a/1064516/702806

Лучшее решение - использовать tar и tee . Команда более сложная, но tar кажется очень мощным для передачи, и ей нужно прочитать источник только один раз.

tar -c /source/dirA/ /source/file1 | tee >(cd /foo/destination3/; tar -x) >(cd /bar/destination2/; tar -x) >(cd /foobar/destination1/; tar -x) > /dev/null

Чтобы использовать его в скрипте, вам может потребоваться запустить скрипт с помощью bash -x script.sh

0

В Баш:

for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .