W przypadku pojedynczych plików możesz użyć tee
do skopiowania do wielu miejsc:
cat <inputfile> | tee <outfile1> <outfile2> > <outfile3>
lub jeśli wolisz wersję demoggified:
tee <outfile1> <outfile2> > <outfile3> < <inputfile>
Zauważ, że jak Dennis wskazuje w tee
wynikach komentarzy, stdout
a także na wymienione pliki, dlatego też w powyższych przykładach użyj przekierowania, aby wskazać plik 3. Możesz również przekierować to do /dev/null
poniższego - ma to tę zaletę, że lista plików jest bardziej spójna w wierszu poleceń (co może ułatwić skrypty rozwiązanie dla zmiennej liczby plików), ale jest nieco mniej wydajna (chociaż różnica wydajności jest niewielka: mniej więcej taka sama jak różnica między używaniem cat
wersji lub wersji bez cat
):
cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null
Prawdopodobnie można połączyć jeden z powyższych z find
dość łatwo operować na wielu plikach w jednym katalogu, a mniej łatwo na plikach rozproszonych w strukturze katalogów. W przeciwnym razie możesz po prostu ustawić równolegle wiele operacji kopiowania jako osobne zadania i mieć nadzieję, że pamięć podręczna dysku systemu operacyjnego jest jasna i / lub wystarczająco duża, że każde z równoległych zadań używało buforowanych danych odczytu od pierwszego zamiast powodowania napędu lanie.
DOSTĘPNOŚĆ: tee
jest powszechnie dostępna w standardowych konfiguracjach Linuksa i innych systemach uniksowych lub podobnych, zazwyczaj jako część pakietu „coreutils” GNU. Jeśli używasz systemu Windows (twoje pytanie nie określa), powinieneś go znaleźć w różnych portach systemu Windows, takich jak Cygwin.
INFORMACJE O POSTĘPIE: Ponieważ kopiowanie dużego pliku z nośnika optycznego może zająć trochę czasu (lub w wolnej sieci lub nawet większy plik z nawet lokalnego szybkiego nośnika), informacje o postępie mogą być przydatne. W wierszu polecenia I mają tendencję do używania widza pipe (dostępny w większości dystrybucji Linuksa i wielu kolekcjach portowych Windows i łatwo samemu skompilować gdzie nie bezpośrednio) do tego - po prostu wymienić cat
się pv
tak:
pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
tee
będzie również wyprowadzany na standardowe wyjście, więc możesz to zrobić,tee outputfile1 outputfile2 < inputfile > /dev/null
ponieważ wysyłanie pliku binarnego do terminala może być hałaśliwe i powodować problemy z jego ustawieniami.tar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
Dla Windowsa:
n2ncopy zrobi to:
W systemie Linux:
Samo
cp
polecenie może kopiować z wielu źródeł, ale niestety nie z wielu miejsc docelowych. Będziesz musiał uruchomić go wiele razy w jakiejś pętli. Możesz użyć takiej pętli i umieścić wszystkie nazwy katalogów w pliku:lub użyj xargs:
Oba z nich pozwolą ci skopiować całe katalogi / wiele plików. Jest to również omówione w tym artykule StackOverflow.
źródło
Na podstawie odpowiedzi udzielonej na podobne pytanie Innym sposobem jest użycie GNU Parallel do uruchamiania wielu
cp
instancji jednocześnie:Powyższe polecenie skopiuje plik 1 do wszystkich trzech folderów docelowych równolegle
źródło
W bash (Linux, Mac lub Cygwin):
(tee kopiuje dane wejściowe do STDOUT, więc użyj przekierowania na ostatnim celu).
W systemie Windows Cygwin jest często przesadzony. Zamiast tego możesz po prostu dodać pliki exe z projektu UnxUtils , które obejmują cat, tee i wiele innych.
źródło
Rozwiązanie Ryana Thompsona:
ma sens: jeśli szybkość zapisu katalogów docelowych jest w przybliżeniu taka sama, plik src zostanie odczytany tylko raz z dysku. Pozostały czas będzie czytany z pamięci podręcznej.
Uczyniłbym to trochę bardziej ogólnym, więc otrzymujesz także podkatalogi:
Jeśli prędkość zapisu katalogów docelowych jest bardzo różna (np. Jeden znajduje się na dysku RAM, a drugi w systemie plików NFS), możesz zauważyć, że części srcdir czytają podczas kopiowania srcdir do dest1 podczas zapisywania dest2.
źródło
Zgodnie z tą odpowiedzią: /superuser//a/1064516/702806
Lepszym rozwiązaniem jest użycie
tar
itee
. Polecenie jest bardziej skomplikowane, aletar
wydaje się, że jest bardzo potężne do przesyłania ORAZ musi odczytać źródło tylko raz.tar -c /source/dirA/ /source/file1 | tee >(cd /foo/destination3/; tar -x) >(cd /bar/destination2/; tar -x) >(cd /foobar/destination1/; tar -x) > /dev/null
Aby użyć go w skrypcie, może być konieczne uruchomienie skryptu za pomocą
bash -x script.sh
źródło
tar
jest to, że automatycznie kopiuje (zachowuje) atrybuty pliku (np. Datę / godzinę modyfikacji, tryb (ochrony) i potencjalnie listy ACL, właściciela / grupę (jeśli jest uprzywilejowana), SELinux kontekst (jeśli dotyczy), rozszerzone atrybuty (jeśli dotyczy) itp.)……………… PS Dlaczego użytkownik powinien korzystaćbash -x
?#!/bin/sh
na początku skryptu, ale składnia polecenia nie jest akceptowana. Możesz użyćbash -x
lub#!/bin/bash
na początku swojego pliku. Nie wiem, dlaczego istnieje różnica międzysh
ibash
interpretacje.W bash:
źródło
Jeśli chcesz to zrobić w systemie Windows z poziomu programu PowerShell, domyślnie nie jest to możliwe, ponieważ w przeciwieństwie do
-Path
argumentu,-Destination
nie przyjmuje wielu argumentów. Można jednak używać-Passthrough
i łączyć szeregowo polecenia. (Ale to nie jest fajne.)Najlepszym rozwiązaniem jest zrobienie własnego, jak pokazano tutaj .
źródło