web-dev-qa-db-fra.com

Comment trouver et remplacer une chaîne en augmentant sa partie numérique?

Mon fichier d'entrée est,

AMI21 AMI65
AMI67 AMI66
AMI88 AMI76 AMI29
AMI55 
AMI54
AMI32

En utilisant une seule ligne de commande, j'ai besoin de la sortie sous forme de,

AMI22 AMI66
AMI68 AMI67
AMI89 AMI77 AMI30
AMI56
AMI55
AMI33

J'ai utilisé la commande

awk -vRS=AMI '{$0=$0+1;ORS=RT}++n' inputfile > outputfile

mais j'ai le fichier de sortie comme AMI21AMI65AMI67AMI66AMI88AMI76AMI29AMI55AMI54AMI32

c'est-à-dire que toutes les chaînes sont écrites dans la même ligne et sans espace. Quelqu'un pourrait-il me suggérer une meilleure ligne de commande?.

3
tamal

Il serait peut-être plus facile d'utiliser Perl pour cela:

$ Perl -pe 's/(\d+)/$1+1/eg' foo
AMI22 AMI66
AMI68 AMI67
AMI89 AMI77 AMI30
AMI56 
AMI55
AMI33
  • -pe: boucle le fichier, ligne par ligne, en imprimant chaque ligne après avoir évalué l'expression
  • s/(\d+)/$1+1/e: correspond à un nombre (\d+) et remplacez-le par son incrément ($1+1), avec e utilisé pour indiquer à Perl d'évaluer le remplacement.

Avec awk, vous devez inclure les espaces dans le séparateur d’enregistrements:

$ awk -v RS='[[:space:]]*AMI[[:space:]]*' '$0{$0++;}{ORS=RT}1' foo
AMI22 AMI66
AMI68 AMI67
AMI89 AMI77 AMI30
AMI56 
AMI55
AMI33
5
muru

Outre l'excellente réponse fournie par "muru" si vous voulez essayer quelque chose de différent, voici une méthode pythonique:

#!/usr/bin/env python2
import re
with open('file_name.txt') as f:
    for line in f:
        final_list = ['AMI' + str(int(value) + 1) for value in re.findall('\d+', line)]
        print ' '.join(final_list)
2
heemayl

Une autre solution python via re.sub.

$ python3 -c 'import re, sys
with open(sys.argv[1]) as f:
    for line in f:
        print(re.sub(r"\d+", lambda x: str(int(x.group())+1), line), end="")' file
AMI22 AMI66
AMI68 AMI67
AMI89 AMI77 AMI30
AMI56 
AMI55
AMI33
1
Avinash Raj