Copiez uniquement les fichiers standard d'un répertoire vers un autre

12

Je voudrais copier un contenu du répertoire 1 dans le répertoire 2. Cependant, je voudrais seulement copier les fichiers (et non les répertoires) de mon répertoire 1. Comment faire?

cp dir1/* dir2/*

alors j'ai toujours le problème des répertoires.

De plus, tous mes fichiers n'ont pas d'extension, donc . ne fera pas l'affaire

user1058398
la source
1
Je ne sais pas ce que les extensions ont à voir avec ça.
ctrl-alt-delor
1
cp dir1/* dir2oucp -t dir2 dir1/*
ctrl-alt-delor
@richard Il y a une habitude assez courante venant du monde DOS de ne pas utiliser d'extensions pour les répertoires, qui survit encore dans une certaine mesure, ce qui conduit certaines personnes à supposer que s'il y a un point, ce n'est pas un répertoire et vice versa.
Gilles 'SO- arrête d'être méchant'
ok mais toujours pas pertinent.
ctrl-alt-delor

Réponses:

18
cp dir1/* dir2

cpne copiera pas les répertoires sauf indication explicite de le faire (avec --recursivepar exemple, voir man cp).

Remarque 1: cp quittera très probablement avec un état différent de zéro, mais les fichiers auront quand même été copiés. Cela peut être un problème lorsque enchaînant les commandes basées sur les codes de sortie: &&, ||, if cp -r dir1/* dir2; then ..., etc. (Merci à contrebis pour leurs commentaires sur cette question )

Remarque 2 : cpattend que le dernier paramètre soit un nom de fichier ou un répertoire unique. Il ne devrait vraiment pas y *avoir de caractère générique après le nom du répertoire cible. dir2\*sera développé par le shell comme dir1\*. Des choses inattendues se produiront:

  • Si dir2est vide et dépend de votre shell et de vos paramètres:
    • vous pouvez simplement recevoir un message d'erreur, ce qui est le meilleur des cas.
    • dir2/*sera pris littéralement (à la recherche d'un fichier / répertoire nommé *), ce qui entraînera probablement aussi une erreur, sauf s'il *existe réellement.
    • dir2/*il sera tout simplement supprimé de la commande, laissant cp dir1/*. Ce qui, selon l'expansion de dir1/*, peut même détruire des données:
      • Si dir1/*correspond à un seul fichier ou répertoire, vous obtiendrez une erreur de cp.
      • Si dir1/*correspond exactement à deux fichiers, l'un sera écrasé par l'autre ( Mauvais ).
      • Si dir/*correspond à plusieurs fichiers et que la dernière correspondance est un, vous obtiendrez un message d'erreur.
      • Si la dernière correspondance de dir/*est un répertoire, toutes les autres correspondances y seront déplacées.
  • Si dir2n'est pas vide, cela dépend encore:
    • Si la dernière correspondance de dir2/*est un répertoire dir1/*et que les autres correspondances de dir2/*seront déplacées dans.
    • Si la dernière correspondance de dir2/*est un fichier, vous obtiendrez probablement un message d'erreur, sauf s'il ne dir1/* correspond qu'à un seul fichier.
Adaephon
la source
$ cp dir1/* dir2-> cp: dir1/isadir is a directory (not copied).sort avec le statut 1 pour moi.
contrebis
1
Oui, il sort aussi avec le statut 1 pour moi. Mais même ainsi, cpne copie les fichiers correspondant dir1/*sur tous les systèmes que j'ai vérifié: Arch Linux, Ubuntu 14.04, OpenBSD 3.9 et 5.5, SuSE Linux 8.1, FreeBSD 6.2, Solaris 8, 9 et 10 (où cpeffectivement les sorties avec le code 2). Ce comportement n'est donc pas nouveau (SuSE 8.1 date de 2002) ni limité à Linux. cpquitte avec un code de sortie différent de zéro car il ne pouvait pas faire tout ce qu'on lui avait demandé de faire. Cela ne veut pas dire que cela ne fait rien .
Adaephon
3
Bien sûr, je pensais que cela valait la peine d'être noté, car si vous enchaînez des commandes avec &&cela, cela peut causer un problème. J'essayais quelque chose comme ça bien que je ne me souvienne plus du contexte maintenant.
contrebis
Cela ne copie pas les fichiers cachés.
felwithe
@felwithe L'ajout de *fichiers cachés ou la manière d'inclure des fichiers cachés dépend du shell. Si le *ne comprend pas de fichiers cachés, vous pouvez les faire correspondre avec .*. Notez que cela inclura .et ..sur bashet dashmais pas sur zsh. Dans le cadre de cette réponse que vous pouvez vous en sortir avec cp dir1/* dir1/.* dir2parce que .et ..sont des répertoires et ne seront pas copiés. zshpeut également être fait pour inclure des fichiers cachés avec *(D).
Adaephon du
7

C'est le shell qui étend les caractères génériques, pas les commandes. Développe donc d' cp dir1/* dir2/*abord les deux caractères génériques, puis appelle cple résultat. Ce n'est pas du tout ce à quoi vous vous attendez apparemment: en fonction du nombre de fichiers qu'il contient déjà dir2, il dir2/*peut s'agir d'un ou de plusieurs arguments. La commande cpne sait pas lequel de ses arguments provenait de l'expansion du premier motif et lesquels provenaient de l'expansion du deuxième motif. Il s'attend à ce que son dernier argument soit le nom du répertoire de destination. Ainsi, pour copier tous les fichiers du répertoire dir1dans le répertoire dir2, le dernier argument doit être le répertoire dir2:

cp dir1/* dir2

Depuis *correspond à tous les fichiers, cptente de copier tous les fichiers. Cela inclut les répertoires: les répertoires sont aussi des fichiers. Il ignore les répertoires, mais signale une erreur. Il copie le contenu de fichiers spéciaux tels que les canaux nommés (quelque chose vaut mieux y écrire, ou cpva les bloquer), etc.

Pour copier uniquement les fichiers normaux , vous devez restreindre la correspondance. Dans zsh, vous pouvez utiliser le qualificatif glob . pour cela:

cp dir1/*(.) dir2

D'autres obus n'en ont pas. Vous pouvez utiliser la findcommande pour filtrer les types de fichiers. En supposant que vous exécutez Linux ou Cygwin non intégré:

find dir1 -maxdepth 1 -type f -exec cp -t dir2 {} +

Sous Linux, FreeBSD et OSX:

find dir1 -maxdepth 1 -type f | xargs -I {} cp {} dir2
Gilles 'SO- arrête d'être méchant'
la source
Y a-t-il une raison à préciser -maxdepth 1. De même, existe-t-il un moyen de copier récursivement et de conserver la hiérarchie de répertoires d'origine dans le répertoire de destination?
Abdull
@Abdull Sans -maxdepth 1, la findcommande serait récursive dans des sous-répertoires, ce qui n'était pas souhaité ici. Si vous voulez copier l'arborescence des répertoires , y compris l' ensemble des sous - répertoires, il est une question tout à fait différente, et la réponse est beaucoup plus simple: cp -a dir1 dir2.
Gilles 'SO- arrête d'être méchant'
0

Vous trouverez ci-dessous la commande pour copier le fichier du répertoire source vers le répertoire de destination.

  1. Allez dans le dossier source puis écrivez la commande ci-dessous:

    $ cp fileName destination directory path

Exemple:

cp publichOT.sh  /data/home/useradmin
Tapan Dubey
la source