Je veux créer un script pour "afficher" tous les fichiers et répertoires d’un répertoire donné en une fois, par exemple. ./unhide test
.
test/
├── sub1
│ └── .hiddenfile1
└── sub2
└── .hiddendir
├── .hiddendirsub
├── .hiddenfile2
└── not.hidden
Résultat souhaité:
test/
├── sub1
│ └── hiddenfile1
└── sub2
└── hiddendir
├── hiddendirsub
├── hiddenfile2
└── not.hidden
Comment puis je faire ça?
Je suis encore nouveau dans ce domaine et j'essaie de trouver une solution en utilisant find
, mais je suis bloqué à -exec
et rename
(ou mv
) car j'ai toujours du mal à comprendre comment cette combinaison fonctionne. :( Alors, j'apprécierais que quelqu'un ici puisse donner une solution et une explication détaillée également. Merci.
Vous pouvez le faire avec find
comme suit:
find /path/to/test -depth -name ".*" -execdir rename -n 's|/\.|/|' {} +
Ceci n’imprime que les actions de changement de nom, s’il indique ce que vous voulez supprimer de l’option -n
.
-depth
- permet à find
de traiter de bas en haut, en renommant les fichiers avant leurs répertoires parents-name ".*"
- laisse find
rechercher des fichiers ( tout est un fichier ) commençant par un point - le point est littéral ici, car il ne s'agit pas d'une expression régulière-execdir … +
- exécute …
dans le répertoire du fichier correspondantrename 's|/\.|/|' {}
- remplace la première occurrence de "/." du chemin du fichier correspondant (espace réservé de find
qui correspond à {}
) par "/", supprimant essentiellement le point du début du nom de fichierrename 's|/\.|/|' ./.hiddenfile1
dans votre cas, il serait renommé ./hiddenfile1
.$ tree -a
.
├── sub1
│ └── .hiddenfile1
└── sub2
└── .hiddendir
├── .hiddendirsub
├── .hiddenfile2
└── not.hidden
$ find ~/test -depth -name ".*" -execdir rename 's|/\.|/|' {} +
$ tree -a
.
├── sub1
│ └── hiddenfile1
└── sub2
└── hiddendir
├── hiddendirsub
├── hiddenfile2
└── not.hidden
Dans un script, vous pouvez simplement utiliser des paramètres de position à la place du chemin, il peut être relatif ou absolu - rappelez-vous simplement de citation correcte :
#!/bin/bash
find "$1" -depth -name ".*" -execdir rename -n 's|/\.|/|' {} +
$ tree -a test
test
├── .alsohidden
├── sub1
│ └── .hiddenfile1
└── sub2
├── .hiddendirsub
├── .hiddenfile2
└── not.hidden
3 directories, 4 files
$ find test/ -depth -name ".*" -exec rename -n 's|(.*/)\.(.*)|$1$2|' {} +
rename(test/.alsohidden, test/alsohidden)
rename(test/sub2/.hiddendirsub, test/sub2/hiddendirsub)
rename(test/sub2/.hiddenfile2, test/sub2/hiddenfile2)
rename(test/sub1/.hiddenfile1, test/sub1/hiddenfile1)
find test/
commencer les chemins avec test/
, recherche récursive à partir de ce chemin-depth
volé de réponse du dessert - semblait être une bonne idée-name ".*"
nom de fichier commence par .
-exec command {} +
exécuter command
sur les fichiers trouvés, en construisant une liste d'arguments.rename -n
ne fait rien, affiche uniquement ce qui sera fait (supprimez -n
après le test pour renommer réellement)s|old|new|
remplace old
par new
(.*/)\.(.*)
enregistrer tous les caractères jusqu'au dernier séparateur de répertoire inclus, /
, ignorer un .
littéral, enregistrer tous les caractères suivants$1$2
imprimer les motifs sauvegardés