Trouver la deuxième instance d'un mot dans un fichier et renommer le fichier

4

I fichiers qu'un système génère avec un nom de fichier générique. Je veux avoir un script que je peux exécuter qui analyse ces fichiers pour la deuxième instance du mot ProcID (après le mot ProcID est un nombre), puis renomme le fichier avec le numéro ProcID. Actuellement, j'ai ce qui suit:

FILEPATH; awk -F '[:)]' '/ProcID./{printf "mv %s %s.txt\n", FILENAME,  | "/bin/sh"; nextfile}' O*.TXT

Par exemple, le script analyse les fichiers et trouve la seconde instance de (ProcID:0000014778) , puis renomme le fichier avec ce numéro d'identification de processus.

Le script ci-dessus ne trouve que la première instance et, par conséquent, les fichiers sont renommés avant que le système ait fini de sortir dans le fichier.

    
posée IanG 27.01.2017 - 16:58
la source

2 réponses

5

Le script ci-dessous renomme tous les fichiers d’un répertoire, en id dans la deuxième chaîne trouvée, en commençant par ProcID: :

1. Renommer l'ID dans la deuxième chaîne correspondante (littéralement; pas d'extension)

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename if the second instance exists
        new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    except (IndexError, IsADirectoryError):
        pass
    else:
        # rename the file
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))

Pour utiliser

  1. Copiez le script dans un fichier vide, enregistrez-le sous le nom rename_files.py
  2. exécutez-le avec le répertoire comme argument:

    python3 /path/to/rename_files.py /path/to/directory_with_files
    

Notes

  • Le script prend le format (exact): ProcID:0000014778
  • Le script ne pas renommera les fichiers s’il n’ya pas de seconde instance de ProcID (ou pas du tout)

2. Ne renommez que les fichiers .txt et conservez l’extension

... Utilisez ensuite la version ci-dessous, il ne renommera que les fichiers .txt et conservera l'extension dans le fichier renommé. L’utilisation est exactement la même.

#!/usr/bin/env python3
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename is the second instance exists
        new = [s for s in open(file).read().split() if all([
            s.startswith("(ProcID:"), f.endswith(".txt")
            ])][1]
    except (IndexError, IsADirectoryError):
        pass
    else:
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]+".txt"))

Que fait le script

  • il répertorie les fichiers du répertoire:

    for f in os.listdir(dr)
    
  • répertorie les chaînes à l'intérieur du fichier, en commençant par ProcID:

    new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    

    L’extrémité [1] extrait la seconde occurrence des chaînes, en commençant par ProcID: ( [0] est le premier)

  • les divisions de l’identifiant:

    new.split(":")[-1].strip()
    
  • et renomme le fichier en utilisant l'identifiant:

    shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))
    

EDIT

La version Python2 du script 1. Python2 est installé sur OP, qui nécessite IOError au lieu de IsADirectoryError pour éviter les erreurs si le script est exécuté dans un répertoire plutôt que dans un fichier.

#!/usr/bin/env python
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename if the second instance exists
        new = [s for s in open(file).read().split() if s.startswith("(ProcID:")][1]
    except (IndexError, IOError):
        pass
    else:
        # rename the file
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()[:-1]))

... et pour être complet, une version python2 du second script:

#!/usr/bin/env python
import shutil
import os
import sys

dr = sys.argv[1]

for f in os.listdir(dr):
    file = os.path.join(dr, f)
    try:
        # only rename is the second instance exists
        new = [s for s in open(file).read().split() if all([
            s.startswith("(ProcID:"), f.endswith(".txt")
            ])][1]
    except (IndexError, IOError):
        pass
    else:
        shutil.move(file, os.path.join(dr, new.split(":")[-1].strip()+".txt"))
    
réponse donnée Jacob Vlijm 27.01.2017 - 17:42
la source
2

Votre script d'origine était un peu proche et il peut être modifié pour compter les instances via l'instruction if et une variable de compteur:

FILEPATH; awk -F '[:)]' '/ProcID./{ count++; if(count == 2 ){ printf "mv %s %s.txt\n", FILENAME,  | "/bin/sh"; nextfile}}' O*.TXT

Si vous cherchez une solution alternative, vous pouvez utiliser ce Perl script:

#!/usr/bin/env perl
use strict;
use warnings;

my $cnt=0;
open(my $fh,'<',$ARGV[0]) or die "open failed";
my $new_name;
while ( my $line = <$fh> ){
    $cnt+=1 if $line =~ /ProcID/;
    if($cnt==2){
        chomp $line;
        my @words = split(/[:)]/,$line); 
        $new_name = $words[1] . ".TXT";
        last;
    }
}
if (defined $new_name){
   rename $ARGV[0], $new_name;
}
close($fh)

Exemple d'exécution:

$ ls
0000014777.TXT  rename_by_procid.pl*

$ ./rename_by_procid.pl 0000014777.TXT                                                                                                

$ ls
0000014778.TXT  rename_by_procid.pl*
    
réponse donnée Sergiy Kolodyazhnyy 27.01.2017 - 20:52
la source

Lire d'autres questions sur les étiquettes