Question Comment déplacer tous les fichiers du répertoire actuel vers le répertoire supérieur?


Comment déplacer tous les fichiers du répertoire actuel vers le répertoire supérieur sous Linux?

J'ai essayé quelque chose comme mv *.*, mais ça ne marche pas.


125
2017-10-28 18:54


origine


Je n'ai pas assez de rep pour repasser les questions, mais puis-je suggérer [linux] [mv] [cwd] [files], ou quelque chose de similaire? - Stephan202
J'ai repris cette question par demande de Stephan202. - eleven81
unix.stackexchange.com/a/251091/139312 - palindrom


Réponses:


La commande que vous recherchez est

mv * .[^.]* ..

ou (voir ci-dessous pour plus d'informations):

(shopt -s dotglob; mv -- * ..)

Explication: le mv commande déplace des fichiers et des répertoires. Le dernier argument pour mv est la cible (dans ce cas, le répertoire une étape "up" dans l'arbre, ..). Les arguments précédents sont les fichiers source et les répertoires. L'astérisque (*) est un caractère générique qui correspond à tous les fichiers qui ne commencent pas par un point. Les fichiers qui commencent par un point (fichiers par points) sont "cachés". Ils sont appariés en utilisant le motif .[^.]* (voir modifier ci-dessous).

Voir la page de manuel que j'ai liée pour plus d'informations sur mv.


Pourquoi .[^.]* au lieu de .* ?

Comme Chris Johnsen souligne correctement: le motif .* correspond aussi . et ... Puisque vous ne voulez pas (et ne pouvez pas) déplacer ceux-ci, il est préférable d'utiliser un modèle qui correspond à n'importe quel nom de fichier commençant par un point sauf ces deux. Le motif .[^.]* fait juste cela: il correspond à n'importe quel nom de fichier (1) commençant par un point (2) suivi d'un caractère qui est ne pas un point (3) suivi de zéro ou de plusieurs caractères arbitraires.

Comme Paggas  fait remarquer, nous devrions aussi ajouter le motif .??* afin de faire correspondre les fichiers commençant par deux points. Voir sa réponse pour une solution alternative utilisant find.

Arjan répondre mentionne shopt afin d'éviter tous ces problèmes avec les fichiers dotfiles. Mais il y a toujours le problème avec les fichiers commençant par un tiret. Et cela nécessite trois commandes. Pourtant, j'aime l'idée. Je propose de l'utiliser comme ceci:

(shopt -s dotglob; mv -- * ..)

Ceci s'exécute shopt dans un sous-shell (donc pas de second appel à shopt requis) et utilisations -- afin que les fichiers commençant par un tiret ne soient pas interprétés comme des arguments pour mv.


192
2017-10-28 19:01



En utilisant .* peut causer mv produire des avertissements / erreurs sur le fait de ne pas pouvoir bouger . et ... Vous pourriez essayer mv * .[^.]* .. au lieu. - Chris Johnsen
Réponse très complète merci
@ alain: vous êtes les bienvenus et bienvenue sur le site! (Si (et seulement si) l'un des messages ici répond suffisamment à votre question, alors vous pouvez le marquer comme tel. Cela vous donnera l'affiche 15 points de réputation supplémentaires et vous donnera également 2 rep supplémentaires.) - Stephan202
J'aime beaucoup la solution shopt fonctionnant dans un sous-shell :) - Paggas
Il n'y a pas de mal à la syntaxe de *. * - y compris .. est seulement dangereux lorsqu'il est utilisé avec chmod et chown et l'indicateur "recurse", c'est-à-dire chmod -R ou chown -R. Et dans ces cas, ne jamais déjà tapez chown. * ou chmod. * - indiquez le répertoire supérieur dans le chemin que vous recherchez et utilisez -h (ne suivez pas les liens symboliques). Mais, mv .. ne fait simplement rien, alors ne vous inquiétez pas à ce sujet. - chris


Réponse courte: utiliser

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

Longue réponse:

La commande

mv * .* ..

ne fonctionnera pas depuis .* peut correspondre . et ... Mais la commande

mv * .[^.]* ..

ne fonctionnera pas non plus, depuis .[^.]* ne correspondra pas, par exemple, ..filename! Au lieu de cela, ce que je fais est

mv * .[^.] .??* ..

qui correspondra à tout sauf . et ... * correspondra à tout ce qui ne commence pas par un ., .[^.] correspondra à tous les noms de fichiers de 2 caractères commençant par un point sauf .., et .??* correspondra à tous les noms de fichiers commençant par un point comportant au moins 3 caractères.

Mieux encore, vous pouvez utiliser

find . -mindepth 1 -maxdepth 1 -exec mv -t.. -- {} +

ce qui évite les hac mv * .[^.] .??* ..!


41
2017-10-28 20:19



Merci :) J'aurais commenté votre post, mais je n'ai pas encore assez de réputation. - Paggas
Aussi, j'ai oublié de noter l'importance de - pour que la commande fonctionne correctement avec les noms de fichiers commençant par un tiret. J'ai inclus - dans ma réponse trouver cependant. Une réponse plus complète utilisant les globs est "mv - *. [^.]. ?? * ..". - Paggas
+1: Je suis revenu pour ajouter ..?* à mon commentaire, et vous en aviez déjà pris soin. - Chris Johnsen
Que peut-il y avoir de mal à essayer de mv ..? Il ne fait tout simplement rien et ne peut rien faire. Il y a d'autres commandes où pouvez faire quelque chose (chmod et chown) mais mv et rm ne font tout simplement rien. ou .. - chris
Cela donne mv: option illégale - t - pal4life


Par souci d'exhaustivité, on peut également dire au shell Bash d'inclure des fichiers cachés, en utilisant shopt:

shopt -s dotglob
mv -- * ..
shopt -u dotglob

12
2017-10-28 20:52



+1. Beaucoup plus propre Je pense cependant qu'une légère amélioration est nécessaire. Voir la mise à jour de ma réponse. - Stephan202


Le mv n'a pas la fonctionnalité de déplacer les fichiers cachés lors de l'utilisation * - alors pourquoi ne pas utiliser la copie à la place?

cp -rf . ..

rm -rf *

Pas besoin d'entrer dans des solutions complexes de dotglobbing et d'utiliser des commandes find.


8
2017-08-02 20:46



Attention Si vous déménagez dans le même système de fichiers, dans la plus grande partie des cas, vous n'avez pas vraiment copié les fichiers mais mis à jour uniquement les entrées du répertoire sans déplacer les composants inodes ou fichiers. Voir même [1]. Avec un cp et rm Au lieu de cela, vous copiez tout. - Hastur


rsync -a --remove-source-files . ..

rsync est un outil de copie de fichiers extrêmement puissant, généralement utilisé pour effectuer des sauvegardes et des miroirs incrémentiels efficaces.

Avec la commande ci-dessus, nous disons rsync copier le contenu de . dans ..

L'interrupteur -a permet la récursivité dans . sous-répertoires et active d'autres options communes.

L'interrupteur --remove-source-files dit à rsync de supprimer les fichiers source après une copie réussie, c’est-à-dire que rsync se comporte de la même manière que mv commander.


6
2018-01-20 11:47



Un peu plus d'explication serait bien. - ChrisF
Bien sûr, j'espère que c'est plus clair maintenant. - mrucci
Notez que --remove-source-files ne supprimera pas les répertoires (synchronisés). - Dennis
Nice, solution acceptée me donne -bash: /bin/mv: Argument list too long Erreur. Celui-ci fonctionne comme le charme. - userlond


En fin de compte mv . échouera car mv ne pourra pas dissocier le répertoire dans lequel vous vous trouvez actuellement. mv * .. déplacer les fichiers dans le cwd.


2
2017-10-28 18:59



Bonjour merci a travaillé!


mv * .??* ../.

* obtient tous les fichiers non-point. .??* obtient tout. fichiers d'au moins trois octets de long, ce qui fonctionne pour tous les légitimes. Tout ce qui vous reste probablement envie de rm plutôt que mv en tous cas.

le ../. n'offre aucun avantage direct par rapport à .. mais quand vous faites un déplacement dans un répertoire, c'est une très bonne habitude à prendre, car cela échouera, comme vous le souhaitez, si quelque chose ne va pas dans le chemin. Par exemple, mv xyz bletchoù vous pense  bletch est un répertoire, peut être rendu plus sûr avec mv xyz bletch/..


2
2017-10-28 19:47



Vous pourriez ajouter .[^.] pour obtenir des fichiers de couverture comme .a. - Chris Johnsen
Il n'y a pas de différence entre ../ et ../. donc je ne prendrais pas la peine de taper le. après la barre oblique En outre, dans le cas de mv et de rm, cela ne fait pas de mal à inclure. et .. dans la liste, c’est-à-dire qu’il n’ya rien d’effrayant ou de faux avec mv *. * / path / to / file /, juste comme rm. ou même -rf. ne fait rien. - chris


Cette commande minimisée fonctionne sur la plupart des shells modernes:

\mv -- {,.{[^.],??}}* ..

Sinon mentionné est une solution portable:

\mv -- * .[^.] .??* ..

Caractéristiques:

  1. \ empêche les alias de modifier mv indésirable.

  2. - empêche que les noms de fichiers contenant des tirets en tête (-xyz) soient interprétés comme des arguments de ligne de commande.

  3. . [^.] correspond à tous les noms de fichiers de deux caractères commençant par. sauf ..

  4. . ?? * correspond à tous les autres noms de fichiers trois caractères ou plus.

Implémentations naïves:

  1. Ce qui suit ignore les noms de fichiers UNIX masqués, ceux qui commencent par. (.bashrc).

    mv * ..
    
  2. Les correspondances suivantes .. qui tentent de manière récursive de déplacer tous les répertoires par la suite jusqu'au répertoire de travail actuel ($ PWD ou pwd). Ne jamais utiliser.

    mv .* ..
    

1
2017-08-12 08:12





Il est plus correct d'utiliser le motif * .[!.] .??* que * .[^.] .??* puisque le premier fonctionnera également avec des shells plus anciens tels que ksh88:

mv -- * .[!.] .??* ..
  • -- empêche les problèmes lorsque vous avez un nom de fichier qui commence par -
  • * correspond à tous les noms de fichiers qui ne commencent pas par .
  • il n'y a pas un seul nom de fichier de caractère qui commence par un . que vous pouvez / devez déplacer
  • .[!.] correspond à tous les noms de fichiers de deux caractères qui commencent par .
  • .??* correspond aux noms de fichiers de trois caractères (ou plus) qui commencent par un .

Avec ksh88, le modèle de nom de fichier .[^.] correspondra en fait aux noms de fichiers .. (qui existe toujours) et .^ (qui n'existe probablement pas), ayant un effet opposé à ce qui est désiré.


1
2017-10-22 22:24