Extrait de Bash pour déplacer tous les fichiers d'un répertoire dans ce répertoire


14

J'ai un répertoire contenant beaucoup de fichiers et de répertoires. Afin de le ranger, je vais mettre tous ces fichiers dans un répertoire, donc j'allais faire quelque chose comme ceci:

$ ls | wc -l
123
$ mkdir new_directory
$ mv * ./new_directory

Cependant que de toute évidence ne fonctionnera pas car il va essayer de se déplacer new_directorydans new_directory. Existe-t-il un moyen simple de faire ce que je veux sur une seule ligne sans avoir à copier et coller tous les fichiers et répertoires de ce répertoire?


3
cela fonctionne, il affiche simplement un message d'erreur indiquant qu'il est incapable de déplacer new_directory en lui-même.
cas

Réponses:


18

Votre

mv * ./new_directory
la commande fonctionnera réellement; il affichera simplement un avertissement indiquant qu'il ne peut pas déplacer ce répertoire en lui-même.


Le «seul» problème avec cela est que si l'expansion totale de la commande devient trop longue (c'est-à-dire trop de fichiers, trop de noms) cela ne fonctionnera plus.
Niels Basjes

En remarque, si vous allez faire cela avec un, git mvvous devez utiliser le -kdrapeau, car git échouera par défaut, pas seulement cracher un avertissement. Vous devrez donc faire git mv -k * ./new_dir.
Yuval A

11

Un oneliner rapide et sale.

mv `ls -A | grep -v new_directory` ./new_directory

1
Ne fonctionnera pas: un ls simple n'affichera pas les fichiers dot.
wzzrd le

Très bon point. Correction de cela avec un -a.

2
Donc, au lieu d'essayer de mv new_directory pour lui-même (question d'origine), vous essayez maintenant de déplacer. et .. dans new_directory.
Niels Basjes

2
Merci pour la rétroaction Niels. Fixé avec un supérieur qui supprime le. et le .. de la liste des répertoires.

8

Si vous recherchez simplement les fichiers (c'est-à-dire pas les répertoires), alors

find . -type f -maxdepth 1 -exec mv {} ./new_directory/ \;

est la solution la plus portable. Pour la vitesse, vous devez déplacer find et xargs, avec -print0 et -0, mais uniquement si vous avez GNU find et xargs.


3
En utilisant une recherche GNU assez récente, vous pouvez également utiliser \ + au lieu de \; pour diminuer le nombre de mv que nous faisons.
wzzrd le

Si vous avez GNU find, vous pouvez également utiliser xargs, qui fera de même, et vous permettra d'exécuter plusieurs mvs en même temps avec le drapeau -p.
Cian

utilisation sympa de find- bien que j'aie été sur des systèmes qui n'en ont pas, malheureusement :(
warren

Vraiment? find est (afaik) spécifié dans SUS, donc tout devrait l'avoir. Le seul problème est de savoir si c'est GNU find (qui a beaucoup de belles options intéressantes) ou la recherche régulière.
Cian


6

Les fois où j'ai eu ce problème, j'ai fait l'une des choses suivantes:

$ mkdir ../new-directory
$ mv * ../new-directory/
$ mv ../new-directory .

ou

$ mkdir .new-directory
$ mv * .new-directory/
$ mv .new-directory new-directory

La deuxième forme tire parti des noms de fichiers ignorés par des caractères génériques qui commencent par "."


J'ai oublié les fichiers pointillés sautés par caractères génériques; Merci pour le rappel ! :)
aemonge

2

qu'en est-il de:

cd ..
mv old_dir new_directory
mkdir old_dir
mv new_directory old_dir

IOW, ne déplacez pas le contenu dans un nouveau répertoire, mais placez ce répertoire dans un nouveau.


1

De la même manière que la réponse de @ Rembrane (mais pas une ligne):

for FN in *
do
    if [ "<new_dir>" != $FN ] then
        mv $FN <new_dir>
done

Cela devrait être 100% portable - même s'il findest malheureusement absent de votre système.


find est requis dans la seule spécification unix. En tant que tel, il ne devrait jamais être absent (pas que vous ne puissiez pas construire quelque chose sans cela. Mais j'imagine que cela nécessiterait un effort horrible, et aucun système de fournisseur n'en manquerait)
Cian

peut-être que c'est un sysadmin hyperparanoïde yoinking findutils ou son équivalent? pas sûr, mais je sais que j'ai rencontré des boxen qui ne l'ont pas :(
warren

1

Mes suggestions: comme l’ont dit d’autres

mv * ./new_directory

fonctionnera trouver IFF l'expansion totale est assez courte.

Sinon, vous pouvez essayer celui-ci qui s'adapte à un nombre beaucoup plus grand de fichiers:

find . -type f -maxdepth 1 | xargs -s100000 echo | xargs -iXXX mv XXX new_directory

Explication

  1. Liste tous les fichiers.
  2. Regroupez tous les noms de fichiers en blocs de 100 000 caractères max.
  3. Construisez une seule commande mv par bloc.

se casse si vous avez des espaces dans vos noms de fichiers
Cian

Tu as raison. Donc je suppose que cela devrait être augmenté avec des drapeaux -print0 et -0 pour corriger.
Niels Basjes

Je l' ai essayé avec -print0et -0et il encore des pauses.
Cristian Ciupitu le

find: avertissement: vous avez spécifié l'option -maxdepth après un argument non-option -type, mais les options ne sont pas positionnelles (-maxdepth affecte les tests spécifiés avant lui ainsi que ceux spécifiés après). Veuillez spécifier les options avant les autres arguments.
Cristian Ciupitu le

1

Utilisation:

find -mindepth 1 -maxdepth 1 \! -name new_directory -print0 | \
    xargs -0 -P 100 -I'{}' mv '{}' new_directory

Depuis la xargspage de manuel:

-P max-procs

  Run up to max-procs processes at a time;

-1

Pour éviter le message d'erreur et rester simple:

mv *.* ./new_Folder

fera la même chose mais éviter le message d'erreur (sauf si vous avez des points dans les noms de vos dossiers, je suppose).

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.