2009-11-16 7 views
3

J'ai un répertoire qui ressemble à ceci:Strip caractères avant la période Si Nom du fichier A Prefix Bash

pages/ 
    folder1/ 
     folder1.filename1.txt 
     folder1.filename2.txt 
    folder2/ 
     folder2.filename4.txt 
     folder2.filename5.txt 
    folder3/ 
     filename6.txt 

Je veux qu'il ressemble à ceci:

pages/ 
    folder1/ 
     filename1.txt 
     filename2.txt 
    folder2/ 
     filename3.txt 
     filename4.txt 
    folder3/ 
     filename5.txt 

Avec ls * | sed -e s/^[^.]*.// > /tmp/filenames.txt je reçois un fichier contenant:

filename1.txt 
filename2.txt 
filename3.txt 
filename4.txt 
txt 

Comment puis-je savoir sed ignorer les noms de fichiers de la forme [filename].[suffix] et seulement regarder les noms de fichiers de la forme [foldername].[filename].[suffix]?

Le script final (comme l'a souligné, la commande find simplifierait les choses, mais cela a fonctionné):

for folder in $(ls .) 
do 
    if test -d $folder 
    then 
     pushd $folder 
       ls * | sed 's/.*\.\(.*\..*\)/\1/' > /tmp/filenames.txt 
       ls * > /tmp/current.txt 

       exec 3</tmp/current.txt 
       exec 4</tmp/filenames.txt 

       while read file <&3; read name <&4; 
       do 
        mv "$file" "$name" 
       done 

       rm /tmp/current.txt 
       rm /tmp/filenames.txt 
     popd 
    else 
     echo $folder "not a directory" 
    fi 
done 

exit 0 

Cette page est maintenant un wiki communautaire. Vous pouvez ajouter des solutions plus élégantes ci-dessous:

for folder in $(ls .) 
do 
    something better 
+0

Vous avez probablement/vouloir un 'pushd' quelque part là-dedans. –

+0

Aussi vous voulez précisément "$ {folder}". préfixe supprimé, ou la première section d'un nom de fichier à trois blocs (séparés par des points)? –

+0

@Douglas Oups, accidentellement retiré le pushd. Je l'ai remis dedans. Oui, c'est exactement ça. – terrace

Répondre

3

pour cette solution:

sed 's/.*\.\(.*\..*\)/\1/' 

Vous devriez vraiment utiliser find alors vous ne besoin de la vérification pour "-d dossier" ou le fichier temporaire et execs ou la boucle while.

Vous pouvez éviter le fichier temporaire en utilisant processus Substition:

while read line 
do 
    echo $line 
done < <(ls) 

Un autre élément intéressant: votre système peut déjà avoir un script Perl appelé rename ou prename qui renommer des fichiers en utilisant une expression régulière.

+0

Cela a fait l'affaire. Je cherche à trouver la prochaine fois que je dois faire quelque chose comme ça. Ne pas savoir regexp est un handicap ennuyeux. Merci! – terrace

0

utiliser l'expression rationnelle suivante:

/\A(.\*?\\.){2,2}.+\Z/ 
+0

Er, déclenche une erreur de syntaxe. Je ne connais pas assez les expressions régulières pour savoir comment le réparer. – terrace

+0

remplacez \ A par^et \ Z par $ et essayez à nouveau – ennuikiller

2

Vous n'avez pas besoin d'utiliser sed:

ls * > /tmp/current.txt 
exec 3</tmp/current.txt 
while read file <&3; 
do 
    replacement=${file#${folder}.} 
    if [ "$replacement" != "txt" ] ; then 
     mv "$file" "$replacement" 
    fi 
done 
+0

Will donne un coup de feu. Merci. – terrace

+0

Ah, le problème avec cette méthode est qu'il y a des cas où j'ai ceci: Folder1/Folder1.txt. Cette méthode renomme ces fichiers "txt". – terrace

+1

Vous avez dit que vous vouliez supprimer "Folder1". préfixe :-). –

Questions connexes