web-dev-qa-db-fra.com

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 de linux?

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

131
asksuperuser

La commande que vous recherchez est

mv * .[^.]* ..

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

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

Explication: la commande mv déplace les fichiers et les répertoires. Le dernier argument de mv est la cible (dans ce cas, le répertoire un pas "en haut" dans l'arborescence, ..). 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 commençant par un point (fichiers de points) sont "cachés". Ils sont appariés en utilisant le modèle .[^.]* (voir édition 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 correctement souligné: le modèle .* correspond également à . et ... Puisque vous ne voulez pas (et ne pouvez pas) les déplacer, il est préférable d’utiliser un modèle qui correspond à tout nom de fichier commençant par un point à l’exception de ces deux . Le modèle .[^.]* fait justement cela: il correspond à tout nom de fichier (1) commençant par un point (2) suivi d'un caractère qui est not un point (3) suivi de zéro ou de plusieurs caractères arbitraires.

Comme Paggasfait remarquer , il faudrait également 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's réponse mentionne shopt afin d'éviter tous ces problèmes avec les fichiers de points. Mais il reste le problème des 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 exécute shopt dans un sous-shell (donc pas de deuxième appel à shopt requis) et utilise -- afin que les fichiers commençant par un tiret ne soient pas interprétés en tant qu'arguments de mv.

199
Stephan202

Réponse courte: utiliser

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

Longue réponse:

La commande

mv * .* ..

ne fonctionnera pas car .* peut correspondre à . et ... Mais la commande

mv * .[^.]* ..

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

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

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

Mieux encore, vous pouvez utiliser

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

ce qui évite les hacks globaux laids dans mv * .[^.] .??* ..!

42
Paggas

Juste pour être complet, on peut aussi dire au Bash Shell d'inclure des fichiers cachés, en utilisant shopt :

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

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

cp -rf . ..

rm -rf *

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

8
Micky Martin
rsync -a --remove-source-files . ..

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

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

Le commutateur -a permet la récursion dans les sous-répertoires . et active certaines autres options courantes.

Le commutateur --remove-source-files indique à rsync de supprimer les fichiers source après une copie réussie, c’est-à-dire qu’il fait se comporter de la même manière que la commande mv.

6
mrucci

Il est plus correct d'utiliser le modèle * .[!.] .??* que * .[^.] .??* car le premier fonctionnera également avec les anciens shells tels que ksh88:

mv -- * .[!.] .??* ..
  • -- évite 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 de noms de fichier de caractère commençant par un . que vous pouvez/devez déplacer
  • .[!.] correspond à tous les noms de fichier de deux caractères qui commencent par un .
  • .??* correspond aux noms de fichier de trois caractères (ou plus) commençant par .

Avec ksh88, le modèle de nom de fichier .[^.] correspond en fait aux noms de fichier .. (qui existe toujours) et .^ (qui n'existe probablement pas), ce qui a un effet opposé à celui souhaité.

2
jrw32982

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

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

Sinon mentionné est une solution portable:

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

Caractéristiques:

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

  2. - empêche les noms de fichiers contenant des traits d'union (-xyz) d'être interprétés comme des arguments de ligne de commande.

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

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

Naive Implementations:

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

    mv * ..
    
  2. Les correspondances suivantes .. qui tentent de façon récursive de déplacer tous les répertoires éventuellement jusqu’à/dans .. du répertoire de travail en cours ($ PWD ou pwd). Ne jamais utiliser.

    mv .* ..
    
2
dhchdhd

En fin de compte, essayer mv . échouera car mv ne pourra pas dissocier le répertoire dans lequel vous vous trouvez. Vous pouvez mv * .. pour déplacer les fichiers dans le dossier de cwd.

2
DaveParillo
mv * .??* ../.

* récupère tous les fichiers sans points. .??* obtient tout. fichiers au moins trois octets de long, ce qui fonctionne pour tous les légitimes. Quoi qu'il en soit, vous voudrez probablement rm plutôt que mv de toute façon.

Le ../. n'offre aucun avantage direct par rapport au .., mais lors du déplacement dans un répertoire, c'est une très bonne habitude à adopter, car il échouera, comme vous le souhaitez, si quelque chose ne va pas dans le chemin. Par exemple, mv xyz bletch, où pensez bletch est un répertoire, peut être rendu plus certain avec mv xyz bletch/..

2
DigitalRoss

Trouve et travaille aussi. Ce type de structure peut être utile si vous souhaitez sélectionner des fichiers sur des critères plus complexes en modifiant find et egrep.

find -maxdepth 1 | egrep '^./.'         # Returns all files

mv `find -maxdepth 1 | egrep '^./.'` .. # mv <all files> ..
0
user3192145

Je pense que la solution la plus simple pour déplacer tous les fichiers dans son répertoire parent. serait

mv "`ls`" ../

ou, s'il y a des fichiers/répertoires cachés

utilisation:

mv "`ls -a`" ../ 2>/dev/null

En outre, supposons que vous souhaitiez déplacer le contenu d’un dossier dans l’un de ses dossiers internes (par exemple)

utilisation:

mv "`ls -a`" /tony 2>/dev/null

Remarque:

"`ls -a`" 

Pour déplacer les fichiers contenant des espaces.

2>/dev/null

Permet de supprimer l'avertissement/l'erreur, car ls -a imprime également les dossiers . et .. et que vous ne pouvez pas les déplacer ou les copier. Donc, pour ces dossiers, une erreur s’affichera (si nous n’utilisons pas 2>/dev/null), il ne pourra pas les déplacer et le reste sera déplacé assez facilement.

Il est préférable d'éviter ls -a s'il n'y a pas de fichiers cachés et utilisez simplement ls.

0