2013-04-05 1 views
0

j'ai un dossier avec plusieurs fichiers texte à l'intérieur que je dois traiter et le format en utilisant plusieurs listes de remplacement qui ressemble à ceci:remplacements regex multiples basés sur des listes dans plusieurs fichiers

old string1~new string1 
old string2~new string2 
etc~blah 

Je cours chaque paire de remplacement de remplacement listes sur chaque ligne de ces fichiers de texte multiples. Maintenant, j'ai un ensemble de scripts python pour effectuer cette opération. Ce que je m'interroge, c'est de rendre le code plus simple et mieux maintenable si je passe à sed ou awk? Est-ce que ce sera une meilleure solution ou devrais-je améliorer mon code Python? Je demande parce que les fichiers texte entrants viennent sur une base régulière et ont souvent une structure différente de ce qu'elle était avant, comme les erreurs, les fautes d'orthographe, les espaces multiples, car ces fichiers sont créés par des humains. Donc, je dois constamment modifier mon code et les listes de remplacement pour le faire fonctionner correctement. Merci.

+2

Difficile à dire sans voir votre code Python donc on a une meilleure idée si c'est un goulot de bouteille là ... –

+0

Vous avez utilisé le mot "string" dans votre question mais la solution que vous avez acceptée utilise des expressions régulières à la place donc qui est-ce sur côté gauche des "~" s ci-dessus - les chaînes ou les expressions régulières? –

+0

Oui, je suis désolé pour la confusion, j'utilise des expressions régulières et ces chaînes avec ~ sont en fait des expressions régulières. –

Répondre

4

À moins que votre code python ne soit vraiment mauvais, il est peu probable que le passage à awk le rende plus facile à maintenir. Cela dit, il est assez simple awk, mais n'échelle pas bien:

cat replacement-list-files* | awk 'FILENAME == "-" { 
    split($0, a, "~"); repl[ a[1] ] = a[2]; next } 
    { for(i in repl) gsub(i, repl[i]) }1' - input-file 

Notez que cela fonctionne sur un fichier à la fois. Remplacez 1 avec quelque chose comme { print > (FILENAME ".new") } pour travailler sur plusieurs fichiers, mais alors vous devez faire face à la fermeture des fichiers si vous voulez travailler sur un grand nombre de fichiers, et cela devient rapidement un gâchis impossible à maintenir. Stick avec Python si vous avez déjà une solution de travail.

+1

FYI Vous n'avez pas besoin de vous soucier de fermer les fichiers avec GNU awk, peu importe combien vous travaillez. –

0

est ici le script de remplacement d'expression régulière (la plupart du temps juste cosmétiquement différent de ce que @WilliamPursell posté):

awk -F'~' ' 
    NR==FNR{ map[$1] = $2; next } 
    { 
     for (old in map) { 
     gsub(old,map[old] 
     } 
    } 
    ' /wherever/mappingFile file 

mais voici le script de remplacement de chaîne que je pense que vous avez vraiment besoin:

awk -F'~' ' 
    NR==FNR{ map[$1] = $2; next } 
    { 
     for (old in map) { 
     rlength = length(old) 
     while (rstart = index($0,old)) { 
      $0 = substr($0,1,rstart-1) map[old] substr($0,rstart+rlength) 
     } 
     } 
    } 
    ' /wherever/mappingFile file 

En Dans les deux cas, il suffit de l'entourer d'une boucle de shell pour affecter plusieurs fichiers:

for file in * 
do 
    awk -F'~' '...' /wherever/mappingFile "$file" > tmp && mv tmp "$file" 
done 
Questions connexes