2017-10-01 5 views
0

J'ai des centaines de sous-répertoires dans un répertoire qui contiennent tous des fichiers cachés dont j'ai besoin de supprimer la période au début pour les rendre visibles . J'ai trouvé une commande pour aller dans chaque répertoire et les changer pour les rendre visibles mais j'ai besoin de savoir comment faire fonctionner cette commande depuis un répertoire.Comment changer tous les dossiers/fichiers cachés visibles dans plusieurs sous-répertoires

rename 's/\.//;' .* 

J'ai essayé une heure de modifier cela fonctionne à un niveau supérieur, mais ne comprennent pas la chaîne assez Perl pour le faire. Si quelqu'un peut aider, je suis sûr que c'est simple et que je ne peux pas me poser la bonne réponse.

+0

Vous pourriez probablement obtenir une liste de tous dirs/fichiers qui doivent être renommés via la commande 'find' - mais récursion dans un répertoire vous êtes également rena ming pourrait conduire à des problèmes. – amon

+0

J'ai juste besoin d'ajouter ./* à cette commande, fondamentalement, je n'ai pas besoin de renommer dans le répertoire parent, je dois seulement renommer dans les centaines de sous-répertoires. J'ai donc besoin de trouver un moyen de lui dire de pointer vers tous les répertoires d'un niveau vers le bas au lieu de la façon dont il est écrit qui est dans le répertoire courant. – Ortoch

+0

Stack Overflow est un site de questions de programmation et de développement. Cette question semble être hors sujet car il ne s'agit pas de programmation ou de développement. Voir [Quels sujets puis-je poser à ce sujet?] (Http://stackoverflow.com/help/on-topic) dans le centre d'aide. Peut-être [Super utilisateur] (http: // superuser.com /) ou [Unix & Linux Stack Exchange] (http://unix.stackexchange.com/) serait un meilleur endroit à demander. – jww

Répondre

4

Cela nécessite une découverte qui prend en charge le + (peut utiliser à la place \;, qui appellera rename plusieurs fois), mais même POSIX find le précise:

find -mindepth 1 -depth -exec rename -n 's{/\.([^\/]*$)}{/$1}' {} + 
  • L'option -depth empêche les répertoires d'être renommé avant tous les fichiers qui s'y trouvent sont renommés
  • -mindepth 1 empêche find de tenter de renommer le répertoire en cours, ..
  • -n est juste d'imprimer ce qui serait renommé au lieu de renommer réellement (doit être retiré pour faire le renommage).
  • L'expression régulière supprime la dernière période après laquelle il n'y a pas de barre oblique, si elle est précédée d'une barre oblique.

rename ne remplace pas les fichiers existants, sauf si l'option -f ("force") est utilisé.

Pour une structure de répertoire de test comme celui-ci:

. 
├── .dir1 
│   ├── .dir2 
│   │   ├── .dir3 
│   │   │   └── .file2 
│   │   └── .file1 
│   ├── file3 
│   └── .file6 
├── dir5 
│   └── .file5 
├── .file4 
├── test1.bar 
└── test1.foo 

la sortie est

rename(./dir5/.file5, ./dir5/file5) 
rename(./.file4, ./file4) 
rename(./.dir1/.file6, ./.dir1/file6) 
rename(./.dir1/.dir2/.file1, ./.dir1/.dir2/file1) 
rename(./.dir1/.dir2/.dir3/.file2, ./.dir1/.dir2/.dir3/file2) 
rename(./.dir1/.dir2/.dir3, ./.dir1/.dir2/dir3) 
rename(./.dir1/.dir2, ./.dir1/dir2) 
rename(./.dir1, ./dir1) 

et le résultat après le retrait -n est

. 
├── dir1 
│   ├── dir2 
│   │   ├── dir3 
│   │   │   └── file2 
│   │   └── file1 
│   ├── file3 
│   └── file6 
├── dir5 
│   └── file5 
├── file4 
├── test1.bar 
└── test1.foo 
+0

Vous êtes un bon génie Monsieur – Ortoch

+1

Intéressant sur POSIX et '+', parce que j'ai rencontré de nombreuses personnes qui avaient un 'find' qui n'acceptait pas' + '. – ikegami

+0

@ikegami Ce n'est même pas si nouveau, déjà la spécification 2004 l'indique, mais je ne me fie pas à son existence sur tous les systèmes. –

3

safely_unhide:

#!/usr/bin/perl 
use strict; 
use warnings; 
use File::Basename qw(fileparse); 
for (@ARGV) { 
    my $o = $_; 

    my ($fn, $dir_qfn) = fileparse($_); 
    $fn =~ s/^\.// 
     or next; 

    my $n = "$dir_qfn/$fn"; 
    if (stat($n)) { 
     warn("Skipping \"$o\": \"$n\" already exists\n"); 
     next; 
    } 
    elsif (!$!{ENOENT}) { 
     warn("Skipping \"$o\": Can't stat \"$n\": $!\n"); 
     next; 
    } 

    rename($n, $o) 
     or warn("Skipping \"$o\": Can't rename to \"$n\": $!\n"); 
} 

Utilisation:

find -type f -exec safely_unhide {} +   # Supports all file names. Requires GNU find 
find -type f | xargs safely_unhide    # Doesn't support newlines in file names. 
find -type f -print0 | xargs -0 safely_unhide # Supports all file names. 

Goutte -type f et ajoutez -depth si vous souhaitez renommer dirs cachés aussi.

+0

find -type f -print0 | xargs -0 safe_unhide Ignorer "./safely_unhide": Impossible de stat "safe_unhide //": Pas un répertoire Ignorer "./remove_hidden": Impossible de stat "remove_hidden //": Pas un répertoire Ignorer ". /T2/.test3 ": Impossible de renommer en" .test3 // T2/": aucun fichier ou répertoire de ce type – Ortoch

+0

Fixe. Avait les valeurs retournées par 'fileparse' dans le mauvais ordre. – ikegami