Відповіді:
Для одиночних файлів можна 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-подібних системах, як правило, як частина пакету GNU "coreutils". Якщо ви використовуєте Windows (у вашому питанні не вказано), ви повинні знайти її в різних портах Windows, таких як Cygwin.
ІНФОРМАЦІЯ ПРО ПРОГРЕС: Оскільки копіювання великого файлу з оптичного носія може зайняти деякий час (або через повільну мережу, або ще більший файл з навіть локальних швидких медіа), інформація про прогрес може бути корисною. У командному рядку я вважаю за краще використовувати глядач труби (доступний в більшості Linux дистрибутивів і багатьох колекціях портів для Windows і легко скомпілювати себе , де не доступні безпосередньо) для цього - просто замінити cat
з pv
наступним чином:
pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
tee
також буде виводитися у stdout, тому ви, можливо, захочете це зробити, tee outputfile1 outputfile2 < inputfile > /dev/null
оскільки виведення бінарного файлу в термінал може бути галасливим і безладним з його налаштуваннями.
tar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
Для 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.
Виходячи з відповіді, наданої на аналогічне запитання Ще одним способом є використання GNU Parallel для запуску декількох cp
примірників одночасно:
parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3
Вищевказана команда буде копіювати файл1 у всі три цільові папки паралельно
В bash (Linux, Mac або Cygwin):
cat source | tee target1 target2 >targetN
(трійник копіює вхід до STDOUT, тому використовуйте перенаправлення на останню ціль).
У Windows Cygwin часто надмірний. Натомість ви можете просто додати exe з проекту UnxUtils , до якого входять кішки, трійники та багато інших.
Рішення Райана Томпсона:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
має багато сенсу: Якщо швидкість запису в цілях призначення dirs приблизно однакова, то srcfile буде прочитаний лише один раз з диска. Решту часу він буде читатися з кеша.
Я б зробив це трохи більш загальним, тому ви також отримаєте підкаталоги:
for x in dest1 dest2 dest3; do cp -a srcdir $x &; done; wait;
Якщо швидкість запису dest dirs сильно відрізняється (наприклад, одна знаходиться на операційному диску, а інша на NFS), то ви можете побачити, що частини srcdir, прочитані під час копіювання srcdir в dest1, більше не зберігаються в кеш-диску диска під час запису dest2.
Відповідно до цієї відповіді: 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
tar
є те, що він автоматично копіює (зберігає) атрибути файлу (наприклад, дата / час модифікації, режим (захист) та потенційно ACL, власник / група (якщо привілейовано), SELinux контекст (якщо застосовується), розширені атрибути (якщо застосовується) тощо)……………… PS Навіщо користувачеві потрібно використовувати bash -x
?
#!/bin/sh
на початку свого сценарію, але синтаксис команди не приймається. Ви можете використовувати bash -x
або #!/bin/bash
на початку свого файлу. Я не знаю, чому є різниця між sh
та bash
інтерпретаціями.
В bash:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;