Existe-t-il une ligne de commande one-liner pour déplacer tout le contenu de tous les sous-dossiers directs d’un dossier dans le dossier lui-même et supprimer les sous-dossiers (qui sont maintenant vides)? C'est-à-dire, éliminer un niveau dans la hiérarchie des dossiers?
Pour être absolument clair, la structure plus profonde du sous-dossier doit être préservée.
Je me suis heurté à cela à quelques reprises maintenant, et j'ai été un peu déçu que cela ne semble pas être une fonctionnalité de Dolphin, ni quelque chose avec lequel d'autres personnes se débattent.
Je suppose que cela devra peut-être être divisé en deux, en déplaçant le contenu des sous-dossiers et en supprimant ceux-ci. Toutefois, cela peut avoir pour effet indésirable de supprimer des sous-dossiers vides de second niveau.
En fait, pas un vrai one-liner:
find . -mindepth 2 -maxdepth 2 -print -exec mv --backup=numbered -t . '{}' + \
&& find . -mindepth 1 -maxdepth 1 -type d -empty -delete
Recherchez tout d'abord dans le sous-dossier avec la profondeur exacte 2 et déplacez-le vers .
. Ensuite, recherchez et supprimez tous les dossiers vides du répertoire actuel.
original_filename.~n~
(n signifiant 1, 2, 3 ...).Mise à jour:
Je ne suis pas content de la solution ci-dessus. Trop de mises en garde et de problèmes. Par exemple, lorsque --backup = numbered renomme le dossier parent de votre dossier que vous souhaitez déplacer ...
mkdir -p test/test
mv test/test . --backup=numbered
mv: cannot move 'test/test' to './test': No such file or directory
Mieux vaut utiliser un répertoire temporaire pour éviter les problèmes. Le répertoire temporaire doit se trouver sur le même système de fichiers pour éviter de copier les fichiers.
tmpdir=$(mktemp -d)
find . -mindepth 2 -maxdepth 2 -print -exec mv -b -t $tmpdir '{}' +
find . -mindepth 1 -maxdepth 1 -type d -empty -delete
mv -b $tmpdir/* .
rm $tmpdir
Pour vous protéger contre la suppression de sous-répertoires vides, le moyen le plus simple d’IMO consiste à accéder à un répertoire temporaire, puis à le renommer. Disons que le répertoire en question est foo
et que vous voulez que foo/*/*
devienne foo/*
. Faites quelque chose comme:
tar c --remove-files foo | tar xv --strip-components=2 --backup=t --one-top-level=temp
mv temp foo
--remove-files
, le premier tar
supprimera les fichiers au fur et à mesure de son traitement, supprimant finalement foo
lui-même.--strip-components=2
, le second tar
coupera le foo/*/
des chemins extraits, de sorte que foo/a/b
deviendra b
.--backup=t
est identique à cp
ou mv
- crée des copies de sauvegarde numérotées. Cependant, mv
crée des copies des répertoires s'ils portent le même nom, mais tar
fusionnera les répertoires et effectuera des sauvegardes de fichiers.--one-top-level=temp
indique à tar
de créer un répertoire nommé temp
et d'extraire des fichiers à cet emplacement.Par exemple:
$ tree bar
bar
├── a
│ ├── c
│ │ └── bar
│ ├── d
│ │ └── bar
│ ├── e
│ │ └── bar
│ └── f
│ └── bar
├── b
│ ├── c
│ │ └── bar
│ ├── d
│ │ └── bar
│ ├── e
│ │ └── bar
│ └── f
│ └── bar
└── c
├── c
│ └── bar
├── d
│ └── bar
├── e
│ └── bar
└── f
└── bar
Et après avoir exécuté les commandes tar
:
$ tar c --remove-files bar | tar xv --strip-components=2 --backup=t --one-top-level=temp
bar/a/e/
bar/a/e/bar
bar/a/f/
bar/a/f/bar
bar/a/c/
bar/a/c/bar
bar/a/d/
bar/a/d/bar
bar/b/e/
bar/b/e/bar
Renaming ‘temp/e/bar’ to ‘temp/e/bar.~1~’
bar/b/f/
bar/b/f/bar
Renaming ‘temp/f/bar’ to ‘temp/f/bar.~1~’
bar/b/c/
bar/b/c/bar
Renaming ‘temp/c/bar’ to ‘temp/c/bar.~1~’
bar/b/d/
bar/b/d/bar
Renaming ‘temp/d/bar’ to ‘temp/d/bar.~1~’
bar/c/e/
bar/c/e/bar
Renaming ‘temp/e/bar’ to ‘temp/e/bar.~2~’
bar/c/f/
bar/c/f/bar
Renaming ‘temp/f/bar’ to ‘temp/f/bar.~2~’
bar/c/c/
bar/c/c/bar
Renaming ‘temp/c/bar’ to ‘temp/c/bar.~2~’
bar/c/d/
bar/c/d/bar
Renaming ‘temp/d/bar’ to ‘temp/d/bar.~2~’
$ tree temp
temp
├── c
│ ├── bar
│ ├── bar.~1~
│ └── bar.~2~
├── d
│ ├── bar
│ ├── bar.~1~
│ └── bar.~2~
├── e
│ ├── bar
│ ├── bar.~1~
│ └── bar.~2~
└── f
├── bar
├── bar.~1~
└── bar.~2~
4 directories, 12 files
Avec la sortie tar
, vous pouvez voir quand tar
renommer des fichiers à sauvegarder, ce qui vous permet de savoir quels fichiers sont devenus quelles sauvegardes.
Je suis légèrement surpris que cela fonctionne, mais vous pouvez en fait donner le même nom de répertoire pour --one-top-level
et éviter ainsi de devoir le renommer. Juste ce pipeline est suffisant:
tar c --remove-files bar | tar xv --strip-components=2 --backup=t --one-top-level=bar