Les fonctions sur les chaines de caractères

Les chaines de caractères

En plus de fonctions de base, awk dispose également de fonctions dédiées aux traitements des chaines de caractères, facilitant ce genre d'opérations. La liste de ces fonctions est la suivante :

Fonction de string Description
gsub(exp,sub,str) Substitue globalement par la chaine sub chaque expression régulière exp trouvée dans la chaine str et retourne le nombre de substitutions. Si str n'est pas indiquée, par défaut $0 est utilisé.
index(str,st)

Retourne la position du string st dans la chaine str, ou 0 si non trouvé.

length(str) Retourne la longueur de la chaine str. Si str n'est pas indiquée, par défaut $0 est utilisé.
match(str,exp) Retourne la position de l'expression régulière exp dans la chaine str, ou 0 si non trouvé. Affecte les valeurs aux variables RSTART et RLENGTH.
split(str,tab,sep) Sépare la chaine str en éléments dans un tableau tab et en utilisant le séparateur sep. Si sep n'est pas renseigné, FS est utilisé par défaut.
sprintf("format",exp) Retourne une chaine au lieu de l'affichage vers la sortie standard, contrairement à printf().
sub(exp,sub,str) Comme gsub(), mais ne substitue par sub que la première expression exp trouvée dans str.
substr(str,pos,long) Retourne une partie du string str commançant à la position pos et de longueur long. Si long n'est pas indiqué, substr() utilise tout le reste de str.
tolower(str) Met en minuscules toute la chaine str et retourne la nouvelle chaine.
toupper(str) Met en majuscules toute la chaine str et retourne la nouvelle chaine.

Exemple :

gsub : remplacer par un @ toutes les lettres a et A du fichier depts2012.txt

$ head depts2012.txt | awk '{gsub(/a|A/,"@") ; print}'
REGION  DEP     CHEFLIEU        TNCC    NCC     NCCENR
82      01      01053   5       @IN     @in
22      02      02408   5       @ISNE   @isne
83      03      03190   5       @LLIER  @llier
93      04      04070   4       @LPES-DE-H@UTE-PROVENCE @lpes-de-H@ute-Provence
93      05      05061   4       H@UTES-@LPES    H@utes-@lpes
93      06      06088   4       @LPES-M@RITIMES @lpes-M@ritimes
82      07      07186   5       @RDECHE @rdèche
21      08      08105   4       @RDENNES        @rdennes
73      09      09122   5       @RIEGE  @riège
$

index : connaitre la position d'un caractère dans une chaine

$ head depts2012.txt | awk '{pos=index($5,"-") ; print "Position du tiret : " , pos , "\tdans la chaine : " , $5}'
Position du tiret :  0  dans la chaine :  NCC
Position du tiret :  0  dans la chaine :  AIN
Position du tiret :  0  dans la chaine :  AISNE
Position du tiret :  0  dans la chaine :  ALLIER
Position du tiret :  6  dans la chaine :  ALPES-DE-HAUTE-PROVENCE
Position du tiret :  7  dans la chaine :  HAUTES-ALPES
Position du tiret :  6  dans la chaine :  ALPES-MARITIMES
Position du tiret :  0  dans la chaine :  ARDECHE
Position du tiret :  0  dans la chaine :  ARDENNES
Position du tiret :  0  dans la chaine :  ARIEGE
$

length : connaitre le nombre de caractères dans une chaine

$ tail depts2012.txt | awk '{lg=length($5) ; printf ("Il y a %3d caracteres dans la chaine %30s\n" , lg , $5)}'
Il y a   7 caracteres dans la chaine                        ESSONNE
Il y a  14 caracteres dans la chaine                 HAUTS-DE-SEINE
Il y a  17 caracteres dans la chaine              SEINE-SAINT-DENIS
Il y a  12 caracteres dans la chaine                   VAL-DE-MARNE
Il y a  10 caracteres dans la chaine                     VAL-D'OISE
Il y a  10 caracteres dans la chaine                     GUADELOUPE
Il y a  10 caracteres dans la chaine                     MARTINIQUE
Il y a   6 caracteres dans la chaine                         GUYANE
Il y a  10 caracteres dans la chaine                     LA_REUNION
Il y a   7 caracteres dans la chaine                        MAYOTTE
$

match : connaitre la position d'une expression dans une chaine

$ tail depts2012.txt | awk '{pos=match($5,/-DE-/) ; printf("Position de l expression recherchee \"-DE-\" : %2d dans la chaine %20s\tRSTART = %2d\tRLENGTH = %2d\n" , pos , $5 , RSTART , RLENGTH)}'
Position de l expression recherchee "-DE-" :  0 dans la chaine              ESSONNE     RSTART =  0     RLENGTH = -1
Position de l expression recherchee "-DE-" :  6 dans la chaine       HAUTS-DE-SEINE     RSTART =  6     RLENGTH =  4
Position de l expression recherchee "-DE-" :  0 dans la chaine    SEINE-SAINT-DENIS     RSTART =  0     RLENGTH = -1
Position de l expression recherchee "-DE-" :  4 dans la chaine         VAL-DE-MARNE     RSTART =  4     RLENGTH =  4
Position de l expression recherchee "-DE-" :  0 dans la chaine           VAL-D'OISE     RSTART =  0     RLENGTH = -1
Position de l expression recherchee "-DE-" :  0 dans la chaine           GUADELOUPE     RSTART =  0     RLENGTH = -1
Position de l expression recherchee "-DE-" :  0 dans la chaine           MARTINIQUE     RSTART =  0     RLENGTH = -1
Position de l expression recherchee "-DE-" :  0 dans la chaine               GUYANE     RSTART =  0     RLENGTH = -1
Position de l expression recherchee "-DE-" :  0 dans la chaine           LA_REUNION     RSTART =  0     RLENGTH = -1
Position de l expression recherchee "-DE-" :  0 dans la chaine              MAYOTTE     RSTART =  0     RLENGTH = -1
$

split : séparer une chaine en éléments dans un tableau

$ tail depts2012.txt | awk '/-/{split($5,tab,"-") ; printf("tab1 = %10s\ttab2 = %10s\ttab3 = %10s\n" , tab[1] , tab[2] , tab[3])}'
tab1 =      HAUTS       tab2 =         DE       tab3 =      SEINE
tab1 =      SEINE       tab2 =      SAINT       tab3 =      DENIS
tab1 =        VAL       tab2 =         DE       tab3 =      MARNE
tab1 =        VAL       tab2 =     D'OISE       tab3 =
$

sprintf (contrairement à la commande printf, avec sprintf le retour chariot \n n'est pas obligatoire)

$ tail depts2012.txt | awk '/-/{split($5,tab,"-") ; chaine=sprintf("tab1 = %10s\ttab2 = %10s\ttab3 = %10s" , tab[1] , tab[2] , tab[3]) ; print chaine}'
tab1 =      HAUTS       tab2 =         DE       tab3 =      SEINE
tab1 =      SEINE       tab2 =      SAINT       tab3 =      DENIS
tab1 =        VAL       tab2 =         DE       tab3 =      MARNE
tab1 =        VAL       tab2 =     D'OISE       tab3 =
$

sub : remplacer par un @ la première lettre a ou A de chaque ligne du fichier depts2012.txt

$ head depts2012.txt | awk '{sub(/a|A/,"@") ; print}'
REGION  DEP     CHEFLIEU        TNCC    NCC     NCCENR
82      01      01053   5       @IN     Ain
22      02      02408   5       @ISNE   Aisne
83      03      03190   5       @LLIER  Allier
93      04      04070   4       @LPES-DE-HAUTE-PROVENCE Alpes-de-Haute-Provence
93      05      05061   4       H@UTES-ALPES    Hautes-Alpes
93      06      06088   4       @LPES-MARITIMES Alpes-Maritimes
82      07      07186   5       @RDECHE Ardèche
21      08      08105   4       @RDENNES        Ardennes
73      09      09122   5       @RIEGE  Ariège
$

substr : extraire une partie d'une chaine

$ tail depts2012.txt | awk '{chaine=substr($5,1,3) ; printf("Les 3 premieres lettres de %20s sont : %3s\n" , $5 , chaine)}'
Les 3 premieres lettres de              ESSONNE sont : ESS
Les 3 premieres lettres de       HAUTS-DE-SEINE sont : HAU
Les 3 premieres lettres de    SEINE-SAINT-DENIS sont : SEI
Les 3 premieres lettres de         VAL-DE-MARNE sont : VAL
Les 3 premieres lettres de           VAL-D'OISE sont : VAL
Les 3 premieres lettres de           GUADELOUPE sont : GUA
Les 3 premieres lettres de           MARTINIQUE sont : MAR
Les 3 premieres lettres de               GUYANE sont : GUY
Les 3 premieres lettres de           LA_REUNION sont : LA_
Les 3 premieres lettres de              MAYOTTE sont : MAY
$

tolower : convertir une chaine majuscule en minuscule

$ tail depts2012.txt | awk '{chaine=tolower($5) ; printf("%20s en minuscule : %20s\n" , $5 , chaine)}'
             ESSONNE en minuscule :              essonne
      HAUTS-DE-SEINE en minuscule :       hauts-de-seine
   SEINE-SAINT-DENIS en minuscule :    seine-saint-denis
        VAL-DE-MARNE en minuscule :         val-de-marne
          VAL-D'OISE en minuscule :           val-d'oise
          GUADELOUPE en minuscule :           guadeloupe
          MARTINIQUE en minuscule :           martinique
              GUYANE en minuscule :               guyane
          LA_REUNION en minuscule :           la_reunion
             MAYOTTE en minuscule :              mayotte
$

toupper : convertir une chaine minuscule en majuscule

$ tail depts2012.txt | awk '{chaine=toupper($6) ; printf("%20s en MAJUSCULE : %20s\n" , $6 , chaine)}'
             Essonne en MAJUSCULE :              ESSONNE
      Hauts-de-Seine en MAJUSCULE :       HAUTS-DE-SEINE
   Seine-Saint-Denis en MAJUSCULE :    SEINE-SAINT-DENIS
        Val-de-Marne en MAJUSCULE :         VAL-DE-MARNE
          Val-d'Oise en MAJUSCULE :           VAL-D'OISE
          Guadeloupe en MAJUSCULE :           GUADELOUPE
          Martinique en MAJUSCULE :           MARTINIQUE
              Guyane en MAJUSCULE :               GUYANE
             Mayotte en MAJUSCULE :              MAYOTTE
$

Etiquettes: 

Commentaires

Bonjour,

Merci pour tous ces éclaircissements. Je chercher à remplacer un caractère dans l'ensemble des champs d'une colonne. Comment peut on restreindre votre ligne de commande dans ce sens ?

Merci

.....de cette manière.

Dans le fichier suivant:

$ head stats
01      Ain     1.5
02      Aisne   2.4
03      Allier  2.2
04      Alpes-de-Haute-Provence 2.1
05      Hautes-Alpes    1.7
06      Alpes-Maritimes 1.8
07      Ardèche 1.8
08      Ardennes        2.3
09      Ariège  2
10      Aube    2

Je vais remplacer toutes les lettres "A" ou "a" dans la seconde colonne, celle qui contient les noms des départements par le caractère "@".

Pour ce faire, je vais utiliser la fonction gsub de awk mais uniquement sur la seconde colonne à l'aide de la variable $2 ($0 = ligne entière, $1 = 1ère colonne, $2 = 2ème colonne etc etc) et je réaffiche le résultat à l'aide de la fonction printf.

$ head stats | awk '{gsub(/a|A/, "@", $2); printf "%s\t%s\t%s\n", $1, $2, $3}'
01      @in     1.5
02      @isne   2.4
03      @llier  2.2
04      @lpes-de-H@ute-Provence 2.1
05      H@utes-@lpes    1.7
06      @lpes-M@ritimes 1.8
07      @rdèche 1.8
08      @rdennes        2.3
09      @riège  2
10      @ube    2

 

Ajouter un commentaire

Filtered HTML

  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Les lignes et les paragraphes vont à la ligne automatiquement.

Plain text

  • Aucune balise HTML autorisée.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Les lignes et les paragraphes vont à la ligne automatiquement.
CAPTCHA
Cette question permet de s'assurer que vous êtes un utilisateur humain et non un logiciel automatisé de pollupostage.
CAPTCHA visuel
Entrez les caractères (sans espace) affichés dans l'image.