Les scripts BASH AWK SED
Syntaxes equivalentes a : "grep -v"
- Une commande equivalente a "grep -v" utilise "split" et est construite automatiquement par le script
- Une commande equivalente a "grep -v" utilise "set" : affichage des variables
La commande SED
- la syntaxe print 'p' : sed -n '....p' fichier.txt
LES LIGNES SONT DANS UN TABLEAU
- Le tableau permet le cumul
- Le tableau permet l'ordre inverse
- Le tableau permet de selectionner des lignes
- Le tableau permet de modifier des fins de lignes
- Le tableau permet de modifier des lignes
- Le tableau permet d'ajouter des digits
- Le tableau permet d'avoir les elements uniques d'une colonne
haut
Une commande equivalente a "grep -v" utilise "split" et est construite automatiquement par le script
# in.txt
the workplace where we carry out our professional activities
it is a melting pot in which we join our energies
the purpose of the company is to offer an harmonious context
strategically situated in a booming business quarter
that will allow us to efficiently adapt to the evolving needs
up and above its functional aspect , the building embodies the values of excellence
in a multicultural context, the building reflects our unity
# except.txt # patterns qui vont deleter les lignes
company
building
#!/bin/bash
# le but du script est de deleter les lignes contenant des patterns (equivalent a "grep -v" pour plusieurs patterns)
################# parametres
count=1
LISTE=except.txt
START=in.txt
RESULT=out.txt # fichier du resultat
################# fin des parametres
# deleter les anciens resultats
rm part2.txt
# nb lignes sans les lignes vides
nbline=`grep "." $LISTE | wc -l`
echo $nbline
# boucle sur le nb lignes
until [ "$count" -gt $nbline ]
do
echo $count > echocount.txt
acount=`awk 'NR=='$count' {split( $0, d, " " ) ; print d[1]}' $LISTE`
#creation de la syntaxe equivalente a "grep -v"
echo "awk 'FNR==NR &&" > part1.txt
echo "a[\$0]=/$acount/ ||" >> part2.txt ; sed -e '$ s/||//g' part2.txt > part2b.txt
echo "{b[\$0] ; next} !(\$0 in b)' \$START" > part3.txt
cat part1.txt part2b.txt part3.txt > action.txt
ACTION=`cat action.txt`
eval `echo $ACTION` > $RESULT
let count=count+1
done
# resultat
the workplace where we carry out our professional activities
it a melting pot in which we join our energies
strategically situated in a booming business quarter
that will allow us to efficiently adapt to the evolving needs
haut
Une commande equivalente a "grep -v" utilise "set" : affichage des variables
# in.txt
the workplace where we carry out our professional activities
it is a melting pot in which we join our energies
the purpose of the company is to offer an harmonious context
strategically situated in a booming business quarter
that will allow us to efficiently adapt to the evolving needs
up and above its functional aspect , the building embodies the values of excellence
in a multicultural context, the building reflects our unity
# except.txt # patterns qui vont deleter les lignes
company
building
#!/bin/bash
# le but du script est de deleter les lignes contenant des patterns (equivalent a "grep -v" pour plusieurs patterns)
################# parametres
count=1
LISTE=except.txt
START=in.txt
RESULT=out.txt # fichier du resultat
################# fin des parametres
# deleter auciens resultats
rm part2.txt
# nb lignes sans les lignes vides
nbline=`grep "." $LISTE | wc -l`
echo $nbline
# initialiser les variables
variables=`cat except.txt`
set -- $variables
# nombre de mots dans le fichier: variable speciale $#
for i in `seq 1 $#`
do
t=`echo var$i="\$"{$i} "; echo \$"var$i`
echo $t
done > tmp.txt
# creation des variables
while read line ; do eval $line ; done < tmp.txt
until [ "$count" -gt $nbline ]
do
echo "awk 'FNR==NR &&" > part1.txt
echo "a[\$0]=/'\$var$count'/ ||" >> part2.txt ; sed -e '$ s/||//g' part2.txt > part2b.txt
echo "{b[\$0] ; next} !(\$0 in b)' \$START" > part3.txt
cat part1.txt part2b.txt part3.txt > action.txt
ACTION=`cat action.txt`
eval `echo $ACTION` > $OUT
let count=count+1
done
# resultat
the workplace where we carry out our professional activities
it is a melting pot in which we join our energies
strategically situated in a booming business quarter
that will allow us to efficiently adapt to the evolving needs
haut
la syntaxe print 'p' : sed -n '....p' fichier.txt
# in.txt
line1 data
line2 data2 test sed command
line3 513
line4 data4
line5
# print la ligne 2 :
sed -n '2p' in.txt
# resultat :
line2 data2 test sed command
#-----------------------
# print de la ligne 2 a 4 :
sed -n '2,4p' in.txt
# resultat :
line2 data2 test sed command
line3 513
line4 data4
#-----------------------
# print la 1ere et derniere ligne :
sed -n '1p ; $p' in.txt
# resultat :
line1 data
line5
#-----------------------
# print si la ligne a au moins 6 caracteres :
sed -n '/^.\{6\}/p' in.txt
# resultat :
line1 data
line2 data2 test sed command
line4 data4
#-----------------------
# print un pattern :
sed -n '/data/p' in.txt
# resultat :
line1 data
line2 data2 test sed command
line4 data4
#-----------------------
# print entre 2 patterns :
sed -n '/data2/,/data4/p' in.txt
# resultat :
line2 data2 test sed command
line3 513
line4 data4
#-----------------------
# print un pattern mis en variable :
var=sed
sed -n '/'$var'/p' in.txt
# resultat :
line2 data2 test sed command
#-----------------------
# ne pas printer un pattern :
sed -n '/data/!p' in.txt
# resultat :
line3 513
line5
#-----------------------
# print 3 digits consecutifs :
sed -n '/[0-9]\{3\}/p' in.txt
# resultat
line3 513
#-----------------------
# print le nombre minimum de champs des lignes d'un fichier :
awk '{print NF}' in.txt | sort -n | sed -n '1p'
# resultat
1
#-----------------------
# print le nombre maximum de champs des lignes d'un fichier :
awk '{print NF}' in.txt | sort -n | sed -n '$p'
# resultat
5
haut
Le tableau permet le cumul
# in.txt
line1 1
line2 2
line3 3
line4 4
awk '{arr[NR] = $2 ; sum+= $2} # oubien : {arr[NR] = $0 " " sum+= $2}
END {
for (i = 1 ; i<= NR ; i++)
printf "%s(%2.2f %)\n" , arr[i],(100 * arr[i])/sum
}' FS=" " in.txt
# resultat
1(10.00 %)
2(10.00 %)
3(10.00 %)
4(10.00 %)
haut
Le tableau permet l'ordre inverse
Noter que ce qui suit peut etre obtenu plus rapidement avec : tac in.txt
# in.txt
line1 1
line2 2
line3 3
line4 4
awk '{ arr[NR]=$0 }
END {
for (i=NR; i>=1; i--)
print arr[i]
}' in.txt
# resultat
line4 4
line3 3
line2 2
line1 1
haut
Le tableau permet de selectionner des lignes
# voici une liste de magasins (de marque 1, 2 ou 3) avec leur nombre de parkings dans quelques villes
# le but est de selectionner la ville qui n'a que le magasin1 et plus de 5 parkings
# in.txt (colonne 1 : ville /// colonne 2 : magasin /// colonne 3 : nombre de parkings)
marseille marque1 7
marseille marque2 10
marseille marque3 3
lyon marque1 2
lyon marque3 9
rennes marque1 3
bordeaux marque2 4
strasbourg marque1 8
#!/bin/bash
###### parametres
parking="5"
###### fin des parametres
# cas ou on s'interesse uniquement au magasin marque[$1]
awk '
# creer le tableau marque1[$1]
# (on ne peut ecrire ici la synthaxe « delete marque1[$1] »
# puisque le tableau marque1[$1] n’est pas encore cree)
$3 > '$parking' && $2 == "marque1" && !($1 in marque2) && !($1 in marque3) {marque1[$1]}
# si la ville possede marque2 , retirer la ville de marque1
$3 > '$parking' && $2 == "marque2" {marque2[$1] ; delete marque1[$1]}
# si la ville possede marque3 , retirer la ville de marque1
$3 > '$parking' && $2 == "marque3" {marque3[$1] ; delete marque1[$1]}
END {
for (ville in marque1) print "la ville qui n a que la marque1 et plus de 5 parkings est : " ville
}
' in.txt
# resultat
la ville qui n a que la marque1 et plus de 5 parkings est : strasbourg
haut
Le tableau permet de modifier des fins de lignes
# in.txt
H0104 STREAMER DETAILS MAL PORT STREAMER 1 0
H0105 OTHER DETAILS OEX Outer STBD TAILBUOY 1 0
R 283 487217.26818026.9 284 487229.76818026.3 285 487242.26818025.6 9
R 286 487254.66818025.0 287 487267.16818024.3 288 487279.66818023.7 9
R 1 483732.86818401.6 2 483745.26818400.0 3 483757.66818398.4 0
R 4 483770.06818396.8 5 483782.46818395.3 6 483794.86818393.9 0
awk '{ f[NR]=$0 }
END {
for (i=1; i<=NR; i++)
if (length(f[i]) == 80)
{print f[i]"@"}
else
{print f[i]}
}' in.txt | sed 's/9@/9/g' | sed 's/0@/A/g'
# resultat (attention de ne pas transformer toutes les lignes se terminant par 0)
H0104 STREAMER DETAILS MAL PORT STREAMER 1 0
H0105 OTHER DETAILS OEX Outer STBD TAILBUOY 1 0
R 283 487217.26818026.9 284 487229.76818026.3 285 487242.26818025.6 9
R 286 487254.66818025.0 287 487267.16818024.3 288 487279.66818023.7 9
R 1 483732.86818401.6 2 483745.26818400.0 3 483757.66818398.4 A
R 4 483770.06818396.8 5 483782.46818395.3 6 483794.86818393.9 A
haut
Le tableau permet de modifier des lignes
# in.txt
line1 1 data1
line2 2 data1
line3 3 data2
line4 4 data2
awk '{ f[NR]=$3 ; g[NR]=$1" "$2 }
END {
for (i=1; i<=NR; i++)
if (f[i] != f[i-1])
{print "@",f[i],g[i]}
else
{print f[i],g[i]}
}' in.txt | sed '/@/G'
# resultat
@ data1 line1 1
data1 line2 2
@ data2 line3 3
data2 line4 4
haut
Le tableau permet d'ajouter des digits
Noter que ce qui suit peut etre obtenu plus rapidement avec : seq -w 11
seq 11 | awk '{
arr[NR] = $0
arr[NR] = (length(NR)==1 ? "0"NR : NR) }
END {
for (i=1; i<=NR; i++)
{print i,arr[i]}
}' | sort -n
# resultat
.....
8 08
9 09
10 10
11 11
haut
Le tableau permet d'avoir les elements uniques d'une colonne
# in.txt
100
100
100
101
101
102
102
awk '{ arr[$1]++ }
END {
for (i in arr) print i}
' in.txt
# resultat
100
101
102
haut
Derniere modification : Fevrier 2013