Scripts AWK

@-1 Regrouper des valeurs - ( cas source unique: sans tableau)

@fichier in.txt
line1
line2
line3
line4
line5
line6

@le script :
#!/bin/bash
awk '{
#separateur entre guillemets ""
{f=f " " $0; i++}
#formater sur n colonnes (changer ici la variable n)
n=3;
#pas de formatage pour i=n+1
if (i>=n) {print f; f=""; i=0}
}
END {
print f
}' in.txt

#Si n=2 , le script peut se ramener a la ligne de commande suivante :
# cat in.txt | sed "N;s/\n/ /"

@resultat :
line1 line2 line3
line4 line5 line6

@-2 Trier sur la longueur des elements d'un tableau

@fichier in.txt
gien orleans
strasbourg lille
aix rennes

@le script :
#!/bin/bash
awk '{
for(i=1; i<=NF; i++)
f[$i]=1}
END {
for(x in f)
if(length(x) > 4)
{nb++; print x}
print nb " mots > 4 caracteres"
}' in.txt

@resultat :
lille
rennes
orleans
strasbourg
4 mots > 4 caracteres

@-3 Regrouper des valeurs - ( cas source multiple: avec tableau f[key] )

@fichier in.txt
1 8
1 69
1 7
2 78
2 3
3 47
3 22

@le script :
#!/bin/bash
awk '{
key=$1; $1="";
f[key]=f[key] s[key] $0;
s[key]=","}
END {
for(key in f)
{gsub(/[[:space:]]/,"",f[key]);
printf "%s %s\n",key,f[key]}
}' in.txt

@resultat :
1 8,69,7
2 78,3
3 47,22

@-4 Regrouper et cumuler des valeurs

@fichier in.txt
A monday red 12
B tuesday yellow 13
A wednesday blue 13
C thursday green 34
B monday white 13

@le script :
#!/bin/bash
awk '{
arr[$1]+=$4}
END {for(i in arr)
{print i,arr[i]}
}' in.txt

@resultat :
A 25
B 26
C 34

@-5 Compter les occurrences des éléments selon un pattern

@fichier in.txt
01 a rouge
02 b rouge
02 c jaune
02 d vert
02 e rouge
03 f jaune

@le script :
#!/bin/bash
awk '{
if($1=="02") IP[$3]++}
END {
for(a in IP)
{print a " repete " IP[a] " fois "}
}' in.txt

@resultat :
vert repete 1 fois
rouge repete 2 fois
jaune repete 1 fois

@-6 Separer des valeurs

@fichier in.txt
01 8 ,69,7
02 78,3
03 47,22

@le script :
#!/bin/bash
awk '{
key=$1;$1="";
n=split($0,parties,"[,]");
for(k=1; k<=n; k++)
print ""key" "parties[k]""
}' in.txt

@resultat :
01 8
01 69
01 7
02 78
02 3
03 47
03 22

@-7 Frequence de tous les mots (=patterns) dans un fichier

@fichier in.txt
jaune vert
vert bleu
rouge jaune
vert

@le script :
#!/bin/bash
awk '{
for(i=1; i<=NF; i++)
#equivalent : freq[$i]+=1
freq[$i]++}
END {
for(word in freq)
print freq[word]" : "word
}' in.txt | sort -r

@resultat :
3 : vert
2 : jaune
1 : rouge
1 : bleu

@-8 Frequence d'un pattern dans un fichier

@fichier in.txt
jaune vert
vert bleu
rouge jaune
vert

@le script :
#!/bin/bash
awk '
/vert/ {n++}
END {
print "vert ecrit " n " fois"
}' in.txt

@resultat :
vert ecrit 3 fois

@-9 Frequence de mots dans une colonne d'un fichier

@fichier in.txt
jaune toto
vert violet
rouge bleu
vert orange

@le script :
#!/bin/bash
awk 'BEGIN{
nb=0}
{count[$1] += 1
if(count[$1] == 1)
{f[nb] = $1;
nb += 1}
}
END {for(i=0; i!=nb; i++)
{print f[i],":",count[f[i]]
}
}' in.txt

@resultat :
vert : 2
jaune : 1
rouge : 1

@-10 Selection de champs sur une ligne de titres

@fichier in.txt
champ1..total1..champ2..total2..champ3..total3
01 ..........57 ........01 ........34 ........01 ........92
02 ..........65 ........02 ........123 .....02 ........59

@le script :
#!/bin/bash
awk 'BEGIN {
getline
for (i=1; i<=NF; i++)
if ($i ~ /total/)
{n++; arr[n]=i}
}
{for (i=1; i<=n; i++)
printf "%4d ", $arr[i]
printf "\n"
}' in.txt

@resultat :
57 ..34 ..92
65 ..123 ..59

@-11 Afficher le nombre de caracteres devant chaque ligne

@fichier in.txt
zz toto
vert jaune
bleu rouge orange

@le script :
#!/bin/bash
awk '{
f[NR]=" nb caracteres " length($0) " " $0}
END {
for( i=1; i<=NR; i++ )
{printf ("%5d %s\n", i " ", f[i])}
}' in.txt

@resultat :
1 nb caracteres 7 zz toto
2 nb caracteres 10 vert jaune
3 nb caracteres 17 bleu rouge orange

@-12 Numeroter les lignes. En tres court : awk '{print NR" : "$0}' in.txt

@fichier in.txt
rouge
jaune
vert

@le script :
#!/bin/bash
awk '{
f[NR] = $0}
END {
for(i=1; i<=NR; i++)
{print i " : " f[i]}
}' in.txt

@resultat :
1 : rouge
2 : jaune
3 : vert

@-13 Indexer en numerotant 'ligne' et 'colonne'

@fichier in.txt
rouge route
jaune auto vert

@le script :
#!/bin/bash
awk 'BEGIN{SUBSEP=":"}
{for(i=1; i<=NF; i++)
{f[NR,i] = $i}
}
END {
#affichage du contenu du tableau f
for(i in f)
{print i " : "f[i] | "sort -n -t: "}
}' in.txt

@resultat :
1:1 : rouge
1:2 : route
2:1 : jaune
2:2 : auto
2:3 : vert

@-14 Changer une colonne en ligne en formatant une sequence

@fichier in.txt
sy1500
sy1524

sy1528
sy1540

sy1544
sy1560

@le script :
#!/bin/bash
seq 1 3 | awk '{printf "%d\n%d\n%d\n",$1,$1,"0"}'>count.txt
paste count.txt in.txt > temp1.txt

awk '{
key=$1;$1="";
f[key] = f[key] $0}
END {
for(key in f)
{print key,f[key]}
}' temp1.txt | sed -n '/^0/!p' > temp2.txt

@resultat (temp2.txt):
1 sy1500 sy1524
2 sy1528 sy1540
3 sy1544 sy1560

@-15 'getline' : capture de donnees en definissant une clef

@fichier in.txt
1
rouge pomme ok
2
jaune citron
3
vert salade ok

@le script :
#!/bin/bash
awk -F " " '
/^[0-9]/ {
key=$1
#capture 1 ligne apres le pattern
getline
#getline;getline #pour 2 lignes apres
if($3 == "ok" )
print key";"$2
}' in.txt

@resultat :
1;pomme
3;salade

@-16 Printer dans autant de fichiers que d'elements de la colonne 1, en additionnant le contenu

@fichier in.txt
01 55
01 66
02 88
02 99

@le script :
#!/bin/bash
awk '{
for (k=01; k<03; k++)
if ($1 == $k) print $0 > $k
}' in.txt
for i in 0*
do
awk '{print (total += $2)}' $i | tail -n1 > a$i
done

@resultat :
fichier 01 :
55
66
fichier 02 :
88
99
fichier a01 :
121
fichier a02 :
187

@-17 Comparer 2 fichiers

@file1 :
kumarfghh,23,12000,5000
rajakumar,24,14000,2500
rajeshchauhan,25,16000,2600
manoj,26,17000,2300

@file 2 :
123,kumar,US,
123,sukumar,UK
123,raj,Germany
40,rajesh,Australia
40,jerome,swiss
40,rakesh,india

@le script :
#!/bin/bash
awk -F',' 'BEGIN{
while ((getline < "file2")>0)
file2[$2]=$3
}
{longest=0
for (name in file2)
if(name == substr($1,1,length(name)))
if(length(name)>longest)
{holdname=name
longest=length(name)}
if(longest>0)
loc=file2[holdname]
else
loc=""
print $0 "," loc
}' file1

@resultat :
kumarfghh,23,12000,5000,US
rajakumar,24,14000,2500,Germany
rajeshchauhan,25,16000,2600,Australia
manoj,26,17000,2300,