J'essaie d'écrire un script Bash qui écrasera un répertoire existant. J'ai un répertoire foo/
et j'essaie d'écraser bar/
avec ce dernier. Mais quand je fais ça:
cp -Rf foo/ bar/
un nouveau répertoire bar/foo/
est créé. Je ne veux pas ça. Il y a deux fichiers dans foo/
; a
et b
. Il existe également des fichiers portant le même nom dans bar/
. Je souhaite que foo/a
et foo/b
remplacent bar/a
et bar/b
.
Vous pouvez le faire en utilisant l’option -T
dans cp
.
Voir la page Man pour cp
.
-T, --no-target-directory
treat DEST as a normal file
Ainsi, selon votre exemple, voici la structure du fichier.
$ tree test
test
|-- bar
| |-- a
| `-- b
`-- foo
|-- a
`-- b
2 directories, 4 files
Vous pouvez voir la différence évidente lorsque vous utilisez -v
pour Verbose.
Lorsque vous utilisez uniquement l'option -R
.
$ cp -Rv foo/ bar/
`foo/' -> `bar/foo'
`foo/b' -> `bar/foo/b'
`foo/a' -> `bar/foo/a'
$ tree
|-- bar
| |-- a
| |-- b
| `-- foo
| |-- a
| `-- b
`-- foo
|-- a
`-- b
3 directories, 6 files
Lorsque vous utilisez l'option -T
, il écrase le contenu, traitant la destination comme un fichier normal et non un répertoire.
$ cp -TRv foo/ bar/
`foo/b' -> `bar/b'
`foo/a' -> `bar/a'
$ tree
|-- bar
| |-- a
| `-- b
`-- foo
|-- a
`-- b
2 directories, 4 files
Cela devrait résoudre votre problème.
Faites-le en deux étapes.
rm -r bar/
cp -r foo/ bar/
Si vous voulez vous assurer que bar/
finit par être identique à foo/
, utilisez rsync
à la place:
rsync -a --delete foo/ bar/
Si seules quelques modifications ont été apportées, l'exécution sera beaucoup plus rapide que la suppression et la recopie de tout le répertoire.
-a
est le "mode archive", qui copie fidèlement les fichiers de foo/
dans bar/
--delete
supprime également les fichiers supplémentaires qui ne figurent pas dans foo/
de bar/
, en s'assurant que bar/
finit par être identique.-vh
pour les commentaires détaillés et lisibles par l’homme.foo
est obligatoire, sinon rsync
copiera foo/
dans bar/foo/
plutôt que de remplacer bar/
lui-même. foo/
sur le contenu de bar/
, nous utilisons une barre oblique sur les deux. C'est déroutant, car cela ne fonctionnera pas comme prévu avec une barre oblique. on ni, cependant; rsync interprète sournoisement le chemin de destination comme s'il comportait une barre oblique, même s'il respecte l'absence de barre oblique sur le chemin source. Nous avons donc besoin d'une barre oblique sur le chemin source pour faites-la correspondre à la barre oblique ajoutée automatiquement sur le chemin de destination, si nous voulons copier le conten de foo/
dans bar/
, plutôt que le répertoire foo/
lui-même atterrissage dans bar/
en tant que bar/foo
.)rsync
est très puissant et utile, si vous êtes curieux, cherchez ce qu'il peut faire d'autre (comme copier sur ssh).
Utilisez cette commande cp
:
cp -Rf foo/* bar/
La commande suivante vérifie que les fichiers dotfiles (fichiers cachés) sont inclus dans la copie:
$ cp -Rf foo/. bar
Très similaire à @ Jonathan Wheeler:
Si vous ne voulez pas vous souvenir, mais ne réécrivez pas bar
:
rm -r bar/
cp -r foo/ !$
!$
affiche le dernier argument de votre commande précédente.
Essayez d'utiliser cette commande composée de deux étapes:
rm -rf bar && cp -r foo bar
L'opération que vous avez définie est une "fusion" et vous ne pouvez pas le faire avec cp
. Cependant, si vous ne recherchez pas la fusion et que vous voulez bien perdre le dossier bar
, vous pouvez simplement rm -rf bar
supprimer le dossier, puis mv foo bar
pour le renommer. Cela ne prendra pas beaucoup de temps car les deux opérations sont effectuées par des pointeurs de fichiers et non par le contenu du fichier.