Réponses:
Pour les fichiers uniques, vous pouvez utiliser tee
pour copier à plusieurs endroits:
cat <inputfile> | tee <outfile1> <outfile2> > <outfile3>
ou si vous préférez la version démoggifiée:
tee <outfile1> <outfile2> > <outfile3> < <inputfile>
Notez que, comme Dennis le fait remarquer dans les commentaires, tee
renvoie aux stdout
fichiers répertoriés, d'où l'utilisation de la redirection pour pointer vers le fichier 3 dans les exemples ci-dessus. Vous pouvez également rediriger cela vers /dev/null
comme ci-dessous - cela a l'avantage de garder la liste des fichiers plus cohérente sur la ligne de commande (ce qui peut faciliter le scriptage d'une solution pour un nombre variable de fichiers) mais est un peu moins efficace (bien que le la différence d'efficacité est faible: à peu près la même que la différence entre l'utilisation de la cat
version ou la version sans cat
):
cat <inputfile> | tee <outfile1> <outfile2> <outfile3> > /dev/null
Vous pouvez probablement combiner l'un des éléments ci-dessus avec find
assez facilement pour opérer sur plusieurs fichiers dans un répertoire et moins facilement pour opérer sur des fichiers répartis sur une structure de répertoire. Sinon, vous devrez peut-être simplement désactiver les opérations de copie multiples en parallèle en tant que tâches distinctes et espérer que le cache du disque du système d'exploitation est lumineux et / ou suffisamment grand pour que chacune des tâches parallèles utilise des données de lecture mises en cache à partir de la première au lieu de provoquer une tête de lecteur raclée.
DISPONIBILITÉ: tee
est couramment disponible sur les configurations Linux standard et autres systèmes unix ou similaires, généralement dans le cadre du package GNU "coreutils". Si vous utilisez Windows (votre question ne le précise pas), vous devriez le trouver dans les différents ports Windows tels que Cygwin.
INFORMATIONS SUR LA PROGRESSION: Comme la copie d'un fichier volumineux sur un support optique peut prendre un certain temps (ou sur un réseau lent, ou un fichier encore plus volumineux, même sur un support rapide local), les informations de progression peuvent être utiles. Sur la ligne de commande, j'ai tendance à utiliser le visualiseur de tuyaux (disponible dans la plupart des distributions Linux et de nombreuses collections de ports Windows et facile à compiler vous-même lorsqu'il n'est pas disponible directement) pour cela - il suffit de le remplacer cat
par pv
ceci:
pv <inputfile> | tee <outfile1> <outfile2> > <outfile3>
tee
sortira également sur stdout, donc vous voudrez peut-être le faire tee outputfile1 outputfile2 < inputfile > /dev/null
car la sortie d'un fichier binaire sur le terminal peut être bruyante et gâcher ses paramètres.
tar cf - file1 file2 | tee >(tar xf - -C ouput1) | tar xf - -C output2
Pour les fenêtres:
n2ncopy fera ceci:
Pour Linux:
La cp
commande seule peut copier à partir de plusieurs sources mais malheureusement pas de plusieurs destinations. Vous devrez l'exécuter plusieurs fois dans une boucle quelconque. Vous pouvez utiliser une boucle comme celle-ci et placer tous les noms de répertoire dans un fichier:
OLDIFS=$IFS
IFS=$'\n'
for line in $(cat file.txt):
do
cp file $line
done
IFS=$OLDIFS
ou utilisez xargs:
echo dir1 dir2 dir3 | xargs -n 1 cp file1
Les deux vous permettront de copier des répertoires entiers / plusieurs fichiers. Ceci est également abordé dans cet article StackOverflow.
Basé sur la réponse donnée pour une question similaire Une autre façon est d'utiliser GNU Parallel pour exécuter plusieurs cp
instances à la fois:
parallel -j 0 -N 1 cp file1 ::: Destination1 Destination2 Destination3
La commande ci-dessus copiera file1 dans les trois dossiers de destination en parallèle
En bash (Linux, Mac ou Cygwin):
cat source | tee target1 target2 >targetN
(tee copie son entrée dans STDOUT, donc utilisez la redirection sur la dernière cible).
Sous Windows, Cygwin est souvent excessif. Au lieu de cela, vous pouvez simplement ajouter les exes du projet UnxUtils , qui incluent chat, tee et bien d'autres.
La solution de Ryan Thompson:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
a beaucoup de sens: si la vitesse d'écriture des répertoires de destination est approximativement la même, alors srcfile ne sera lu qu'une seule fois sur le disque. Le reste du temps, il sera lu dans le cache.
Je le rendrais un peu plus général, donc vous obtenez également des sous-répertoires:
for x in dest1 dest2 dest3; do cp -a srcdir $x &; done; wait;
Si la vitesse d'écriture des répertoires de destination est très différente (par exemple, l'une se trouve sur un disque RAM et l'autre sur NFS), vous pouvez voir que les parties de srcdir lues lors de la copie de srcdir vers dest1 ne sont plus dans le cache disque lors de l'écriture dest2.
Selon cette réponse: /superuser//a/1064516/702806
Une meilleure solution consiste à utiliser tar
et tee
. La commande est plus compliquée mais tar
semble être très puissante pour le transfert ET elle n'a besoin de lire la source qu'une seule fois.
tar -c /source/dirA/ /source/file1 | tee >(cd /foo/destination3/; tar -x) >(cd /bar/destination2/; tar -x) >(cd /foobar/destination1/; tar -x) > /dev/null
Pour l'utiliser dans un script, vous devrez peut-être lancer votre script avec bash -x script.sh
tar
est qu'il copiera (conservera) automatiquement les attributs de fichier (par exemple, la date / heure de modification, le mode (protection) et potentiellement les ACL, le propriétaire / groupe (si privilégié), SELinux contexte (le cas échéant), attributs étendus (le cas échéant), etc.)……………… PS Pourquoi l'utilisateur aurait-il besoin d'utiliser bash -x
?
#!/bin/sh
au début de mon script mais la syntaxe de la commande n'est pas acceptée. Vous pouvez utiliser bash -x
ou #!/bin/bash
au début de votre fichier. Je ne sais pas pourquoi il y a une différence entre sh
et les bash
interprétations.
En bash:
for x in dest1 dest2 dest3; do cp srcfile $x &>/dev/null &; done; wait;
Si vous souhaitez le faire dans Windows à partir de PowerShell, ce n'est pas possible par défaut, car contrairement à l' -Path
argument, le -Destination
ne prend pas plusieurs arguments. Cependant, vous pouvez utiliser -Passthrough
et chaîner les commandes. (Mais ce n'est pas amusant.)
La meilleure solution est de créer la vôtre, comme indiqué ici .