Les scripts BASH AWK SED

Site de reference : http://unstableme.blogspot.com

MANIPULATION SUR UNE LISTE DE FICHIERS
  1. Boucle 'for' en bash sur une liste de fichiers
REGROUPER : DE LA COLONNE A LA LIGNE - DEGROUPER : DE LA LIGNE A LA COLONNE
  1. Regrouper sur une ligne des patterns semblables
  2. Regrouper des lignes consecutives avec choix des patterns de regroupement
  3. Degrouper
COMPTEURS
  1. Inserer un compteur dans une colonne avec un separateur defini
  2. Numeroter les occurrences d'un pattern a l'interieur d'un fichier
  3. Compteur de mots par ligne
  4. Numeroter des groupes de patterns semblables
BOUCLES qui peuvent dépanner
  1. Compter des occurrences de patterns (non choisis) dans 1 colonne (utilise 1 seul fichier)
  2. "for" + "sed" : Capture de patterns (choisis) dans 1 colonne (utilise 2 fichiers)
  3. "for" + "awk -v" : Capture de patterns (choisis) dans 1 colonne (utilise 2 fichiers)
  4. "for" + "awk -v" : Nombre d'occurrences de patterns (choisis) (utilise 2 fichiers)
  5. "while" : Nombre d'occurrences de patterns (choisis) (utilise 2 fichiers)
  6. Utilisation d'un tableau : Capture de patterns (choisis) (utilise 2 fichiers)
  7. Utilisation de FNR==NR : Capture de patterns (choisis) (utilise 2 fichiers)
  8. Boucle "while" dans une boucle "until" : un compteur alimente une variable lectrice de lignes d'un fichier
  9. Boucle "until" pour capturer un groupe de 2 variables a chaque passage
  10. Boucle "until" dans une boucle "while" : Cumul d'une colonne avec choix de coupe (utilise 2 fichiers)
  11. Boucle "until" dans une boucle "while" dans une boucle "until" : encadrer des coupes a l'aide d'une liste (utilise 2 fichiers)
LE CARACTERE
  1. Position et extraction d'un caractere dans une chaine ; remplacement de caracteres ; longueur de la chaine
  2. Le caractere est le critere de selection de lignes (2 boucles while)
PARAGRAPHE
  1. Capture d'un paragraphe avec pattern de debut mais pas de fin (exemple 1)
  2. Capture d'un paragraphe avec pattern de debut mais pas de fin (exemple 2)
  3. Capture d'un paragraphe avec pattern de debut mais pas de fin (exemple 3)
  4. Capture d'un paragraphe avec pattern de debut et de fin dans plusieurs fichiers (exemple court)
  5. Capture d'un paragraphe avec pattern de debut et de fin dans plusieurs fichiers (exemple long)
  6. Supprimer un paragraphe s'il contient un pattern
  7. Capturer un paragraphe s'il contient un pattern
  8. Chercher les paragraphes qui contiennent une serie de patterns et ceux qui ne les contiennent pas
UNTIL
  1. Capture de lignes avec pattern de debut et de fin
ACCEDER AU PATTERN EN LE CAPTURANT
  1. Capturer le pattern pour une comparaison, un cumul ...
ACCEDER AU PATTERN EN MARQUANT SON OCCURRENCE
  1. Marquer les occurrences d'un pattern (exemple 1)
  2. Marquer les occurrences d'un pattern (exemple 2)
  3. Compter le nombre de mots d'un fichier
  4. Compter le nombre d'occurrences de chaque mot d'une colonne
  5. Compter le nombre d'occurrences de chaque mot d'un fichier
  6. Compter le nombre d'occurrences d'une lettre d'un fichier
  7. Compter le nombre de champs de chaque ligne
  8. Compter le nombre d'occurrences d'un caractere dans plusieurs fichiers
ACCEDER AU PATTERN EN MARQUANT SA PLACE
  1. Marquer en utilisant des conditions
ACCEDER AU PATTERN EN TESTANT SA FORME
  1. Comparer la forme d'une variable sur un modele
ACCEDER AU PATTERN EN CONDITIONNANT SA CAPTURE
  1. Le pattern est capture selon sa position, sa valeur, sa longueur
LENGTH
  1. LENGTH ajoute des digits a une colonne
IF en BASH
  1. IF dans une boucle while
  2. IF ELIF en BASH
IF en AWK
  1. IF ELSE IF en AWK
ARRAY
  1. Substitution d'une chaine
  2. Mettre un fichier dans un array
VARIABLE
  1. Mettre en variable chaque mot d'un fichier
  2. Mettre en variable chaque ligne d'un fichier (methode courte)
  3. Mettre en variable chaque ligne d'un fichier (methode longue)
  4. Mettre en variable chaque colonne d'un fichier
  5. Mettre en variable une colonne pour une action avec un 2eme fichier
  6. Appel d'une variable
BREAK
  1. Soumettre l'arret d'un script a l'absence d'un pattern
  2. Soumettre l'arret d'un script a la presence d'un pattern
TESTS ET CODES RETOURS
  1. Tester si un fichier existe
  2. Tester si un fichier a une taille non nulle
  3. Tester sur 2 fichiers
  4. code retour (0 ou 1)
  5. Tester la presence d'un pattern
  6. Tester si la ligne ne contient ni majuscule ni minuscule
  7. Tester la presence d'un pattern en lisant ligne par ligne
REDIRIGER L'ECRAN DU TERMINAL VERS UN FICHIER
  1. L'ecran du terminal est ecrit dans un fichier
SEPARATEUR
  1. Changer le separateur
  2. Separateurs multiples (1 er exemple)
  3. Separateurs multiples (2 eme exemple)
SUB - GSUB
  1. sub - gsub ( 1er exemple )
  2. sub - gsub ( 2eme exemple )
  3. sub - gsub ( 3eme exemple )
  4. sub - gsub ( 4eme exemple )
  5. gensub
  6. sub=substitution
GETLINE
  1. Un signe en debut de ligne 1, fait joindre la ligne 2 a la suite de la 1
SEQ
  1. Ajouter le nom des fichiers devant chaque ligne
  2. Compteur d'occurrences
  3. Repeter une syntaxe un nombre de fois precise dans une colonne
SET
  1. set (1er exemple)
  2. set (2eme exemple)
  3. set (3eme exemple)
EVAL
  1. eval
SPLIT
  1. split
  2. n=split
  3. 'csplit' coupe a un pattern et cree des fichiers
NEXT
  1. next pour sauter une ligne
CASE
  1. 'case' pour tester de nombreuses conditions
FORMATAGE
  1. Formater une sequence
FOR
  1. FOR
  2. FOR et IFS
POSITIONNEMENT
  1. index : capture d'une 1ere occurrence d'un pattern
  2. match : capture a un pattern avec choix sur la longueur avant ou apres
  3. pos : se positionner dans un fichier
RENOMMER
  1. renommer des extensions .TXT en .txt
  2. renommer des prefixes
  3. renommer une selection de noms de fichiers (noms avec espaces)
  4. renommer en s'aidant d'un separateur
  5. renommer une serie de 15 fichiers
FNR==NR
  1. Mise en evidence de la difference de numerotation
  2. FNR==NR : precision des captures de patterns
  3. FNR==NR : ecrire les lignes d'un fichier qui ne sont pas dans un autre fichier
FONCTIONS
  1. utiliser une fonction pour renommer des fichiers
RECHERCHER
  1. find avec xargs
  2. chercher un pattern avec "if" dans une boucle for
  3. Rechercher tous les emplacements d'un mot dans un fichier
  4. Rechercher le mot le plus long dans un fichier
SCRIPTS COMPLETS
  1. Couper des lignes a une position precise (utilise FOLD)

haut

Boucle 'for' en bash sur une liste de fichiers


# in1.txt                                  # in2.txt      
line captured file1 pattern1 old           data4
data2                                      line captured file2 pattern1 old
line captured file1 data3 old              data5

for fichier in `ls in*.txt`
do
numero=${fichier:2:1}
sed -e "/line captured/!d" -e "s/pattern1/ /g" -e "s/old/new/g" $fichier > "out"${numero}".txt"
done

# resultat
# out1.txt                                # out2.txt     
line captured file1  new                  line captured file2  new
line captured file1 data3 new

haut

Regrouper sur une ligne des patterns semblables


# in.txt
100 data1 data2
100 data3 data4 data5
100 data6 data7
101 data8 data9
101 data10

# methode 1
#!/bin/bash
awk 'BEGIN{FS=OFS=" "}
{a[$1]++ ; b[$1] = b[$1] " "$2" "$3" "$4}
END{ for( i in a )
print i, a[i], b[i]}
' in.txt

#resultat
100 3 data1 data2 data3 data4 data5 data6 data7
101 2 data8 data9 data10

# methode 2
#!/bin/bash
awk 'BEGIN{FS=OFS=" "}
!arr[$1] {arr[$1] = $0; next}
{arr[$1] = arr[$1] " "$2" "$3" "$4}
END{ for( i in arr )
print arr[i]}
' in.txt

# resultat
100 data1 data2 data3 data4 data5 data6 data7
101 data8 data9 data10

haut

Regrouper des lignes consecutives avec choix des patterns de regroupement


# in.txt
1Mr data1 a
data2 b
2Mrs data3 c
data4 d
1Mr data5 e
data6 f

#!/bin/bash
cat in.txt | sed -e 's/.$/& /g' |
awk 'NR > 1 && /^1Mr|^2Mrs/ {print ""}  # {print ""} ajoute un retour charriot
{printf $0}
END {print ""}'   # {print ""} ajoute un retour charriot

#resultat
1Mr data1 a data2 b 
2Mrs data3 c data4 d 
1Mr data5 e data6 f 

haut

Degrouper


# in.txt
100 data1 data2
101 data3 data4

#!/bin/bash
# 1ere methode
awk '{
key=$1 ; $1="" ; n=split( $0, parties, "[ ]" )
for( k=1; k<=n; k++ )
print ""key" "parties[k] ""
}' in.txt | awk '{if( $2>0 ) print $0}'

# 2eme methode
awk '{print $1"|"$2,$3}' in.txt |
awk -F "|" '{
n=split( $2, Arr, " " )
for( i=1; i<=n; i++ )
{printf "%s %s\n",$1,Arr[i]}}'

# resultat
100 data1
100 data2
101 data3
101 data4

haut

Inserer un compteur dans une colonne avec un separateur defini


# in.txt
001//data1////a
002//data2////b
003//data3////c
004//data4////d
005//data5////e
006//data6////f

#!/bin/bash
#############  parametres

SEPAR=/        # separateur
MARK=@         # nouveau separateur # (par defaut ; ne pas changer)
COL=5          # colonne de l'insertion du compteur

########################  fin des parametres

# 1- methode courte

# ajouter un marqueur
sed 's_'$SEPAR'_'\/$MARK'_'$(echo `expr $COL - 1`)'' in.txt > out1.txt

awk -F"$MARK" '{print $1"100"NR+3$2}' out1.txt > out2.txt

# resultat : out2.txt
001//data1//1004//a
002//data2//1005//b
003//data3//1006//c
004//data4//1007//d
005//data5//1008//e
006//data6//1009//f

############################################

echo

# 2- methode longue

# compteur
seq 1001 1006 > out-temp.txt

# ajouter un marqueur
sed 's_'$SEPAR'_'\/$MARK'_'$(echo `expr $COL - 1`)'' in.txt > out1.txt

# partie avant le marqueur
awk -F"@" '{print $1}' out1.txt > out1g.txt

# partie apres le marqueur
awk -F"@" '{print $2}' out1.txt > out1d.txt

# inserer le compteur
paste out1g.txt out-temp.txt out1d.txt | sed 's/\t//g' > out2b.txt

# resultat : out2b.txt
001//data1//1001//a
002//data2//1002//b
003//data3//1003//c
004//data4//1004//d
005//data5//1005//e
006//data6//1006//f

haut

Numeroter les occurrences d'un pattern a l'interieur d'un fichier


# in.txt
pattern
line2 data
line3 data
pattern
line5 data
pattern
line7 data

#!/bin/bash
awk '/pattern/ {i=i+1} {print $0,i}' in.txt |
awk '!a[$NF]++ {print $0 ; next} {sub($NF, "") ; print}'

# resultat
pattern 1
line2 data
line3 data
pattern 2
line5 data
pattern 3
line7 data

haut

Compter le nombre de mots par ligne


# in.txt
line1 data string
line2
line3 data

#!/bin/bash
c=0
while read line
do
((c+=1))
numfields=`echo $line | awk '{print NF}'`
echo "$c) $line ($numfields)"
done < in.txt

#resultat
1) line1 data string (3)
2) line2 (1)
3) line3 data (2)

haut

Numeroter des groupes de patterns semblables


# in.txt
data
data
a data
a data
gz string
gz string

#!/bin/bash
OLD_IFS= $IFS
IFS=$'\n'
c=0
id2="z"   #indefini
for line in `cat in.txt`
do
id=`echo $line | cut -d " " -f1`
[ $id != $id2 ] && ((c+=1)) && id2=$id
echo "$line  part $c"
done
IFS=$OLD_IFS

# resultat
data  part1
data  part1
a data  part2
a data  part2
gz string  part3
gz string  part3

haut

Compter des occurrences de patterns (non choisis) dans 1 colonne (utilise 1 seul fichier)


# in.txt
data1 1
data1 1
data1 2
data1 2
data1 2
data1 3
data1 3
data1 3

#!/bin/bash
awk '{count[$2]++}
END { for ( i in count )
print count[i] " fois " i }' FS=" " in.txt

# resultat
2 fois 1
3 fois 2
3 fois 3

haut

"for" + "sed" : Capture de patterns (choisis) dans 1 colonne (utilise 2 fichiers)


# in.txt
1589 line1
1590 line2
1591 line3
1592 line4
1593 line5

# count.txt
1589
1591
1593

#!/bin/bash
for i in `cat count.txt`
do
sed -n '/'$i'/p' in.txt |awk '{if($1 == '$i') print $0}' 
done

# resultat
1589 line1
1591 line3
1593 line5

haut

"for" + "awk -v" : Capture de patterns (choisis) dans 1 colonne (utilise 2 fichiers)


# in.txt
data1 1
data1 1
data1 2
data1 2
data1 2
data1 3
data1 3
data1 3

# count.txt     # =liste des patterns a capturer (= grep)
1
3

#!/bin/bash
for i in `cat count.txt`
do
awk -F" " -v x=$i '
{ for ( j=2; j<=2; j++ )   # oubien : ( j=1; j<=NF; j++ )
if ( $j == x ) 
print}' in.txt
done

# resultat
data1 1
data1 1
data1 3
data1 3
data1 3

haut

"for" + "awk -v" : Nombre d'occurrences de patterns (choisis) (utilise 2 fichiers)


# in.txt
data1 1
data1 1
data1 2
data1 2
data1 2
data1 3
data1 3
data1 3

# count.txt     # =liste des patterns a capturer (= grep)
1
3

#!/bin/bash
count=0
for i in `cat count.txt`      # equivalent a boucle "while read line"  .... done < count.txt
do
awk -F" " -v x=$i '{count[$2]++}
#{ for ( j=1; j<=NF; j++ )  {if ( $j == x )
{if ($2 == x)
print count[$2] " fois " $2}' in.txt | tail -1  
#                                      ^^^^^^^  #capture la derniere occurrence
done 
   
# resultat
2 fois 1
3 fois 3

haut

"while" : Nombre d'occurrences de patterns (choisis) (utilise 2 fichiers)


# in.txt
data1 1
data1 1
data1 2
data1 2
data1 2
data1 3
data1 3
data1 3

# count.txt
1
3

#!/bin/bash
while read line
do
awk '$2 ~ '$line' {n++}
END {print n " fois " '$line'}' in.txt
done < count.txt

# resultat
2 fois 1
3 fois 3

haut

Utilisation d'un tableau : Capture de patterns (choisis) (utilise 2 fichiers)


# in.txt
data1 1
data1 1
data1 2
data1 2
data1 2
data1 3
data1 3
data1 3

# count.txt
1
3

#!/bin/bash
awk '{
if (NF==1)    #si la ligne contient 1 champ
_[$0]=$0      #mise en tableau des mots uniques du fichier
else
for ( i in _ )
if ($2==i)
print
}' FS=" " count.txt in.txt

#resultat
data1 1
data1 1
data1 3
data1 3
data1 3

haut

Utilisation de FNR==NR : Capture de patterns (choisis) (utilise 2 fichiers)


# in.txt
data1 1
data1 1
data1 2
data1 2
data1 2
data1 3
data1 3
data1 3

# count.txt
1
3

#!/bin/bash
awk 'BEGIN{FS=" "}
FNR==NR {ex[$1]; next}
($2 in ex)     
' count.txt in.txt

# resultat
data1 1        # inverse:
data1 1        # data1 2
data1 3        # data1 2
data1 3        # data1 2
data1 3          
#### !($2 in ex)   pour l'inverse
#-------------------------

# modifier la capture
awk 'BEGIN{FS=" "}
FNR==NR {ex[$1]; next}
{ $2 = ($2 in ex) ? "0" : $2; print }
' count.txt in.txt

#resultat
data1 0
data1 0
data1 2
data1 2
data1 2
data1 0
data1 0
data1 0
#### { $2 = !($2 in ex) ? "0" : $2; print }   pour l'inverse

haut

Boucle "while" dans une boucle "until" : un compteur alimente une variable lectrice de lignes d'un fichier


##### parametres
NBPASSAGE=3
DEPART=fichieralire.txt
##### fin des parametres

# fichieralire.txt
data-1pass.led
data-2pass.led
data-3pass.led
data-4pass.led

#!/bin/bash
j=1
until [ "$j" -gt "$NBPASSAGE" ]
do

# creer une variable indexee sur la boucle "until"
variable=`awk 'NR=='$j' {print}' $DEPART`

   # condition de lecture des variables
   if [[ "$variable" != "data-2pass.led" ]]
   then
   echo
   echo "contenu du fichier : "  $variable
   
      # boucle sur le contenu de chaque fichier *.led
      while read line
      do
      echo $line
      done < $variable
   fi

let j=j+1
done   2>/dev/null

# resultat
contenu du fichier : data-1pass.led
.............

(le fichier: data-2pass.led n'est pas lu)

contenu du fichier : data-3pass.led
.............

haut

Boucle "until" pour capturer un groupe de 2 variables a chaque passage


# in.txt 
data1
pattern1 data2
data3 pattern2
data4

# liste.txt
arise    a01
achieve  a02
   ^       ^
#pattern1  pattern2

#!/bin/bash

###### parametres
count=1    # toujours =1
nbline=2   # changer ici nombre de lignes de: liste.txt
LISTE=liste.txt
###### fin des parametres

until [ "$count" -gt $nbline ]
do
echo $count > echocount.txt   #ici = 2

acount=`awk 'NR=='$count' {split( $0, d, " " ) ; print d[1]}' $LISTE`  
bcount=`awk 'NR=='$count' {split( $0, d, " " ) ; print d[2]}' $LISTE`

echo $acount  > result-a"$count".txt     
echo $bcount  > result-b"$count".txt

sed 's/pattern1/'$acount'/g' in.txt | sed 's/pattern2/'$bcount'/g' > c-$bcount-$acount.txt

let count=count+1
done

# resultats

# fichier c-a01-arise.txt
data1
arise data2
data3 a01
data4

# fichier c-a02-achieve.txt
data1
achieve data2
data3 a02
data4

haut

Boucle "until" dans une boucle "while" : Cumul d'une colonne avec choix de coupe (utilise 2 fichiers)


# in.txt (le 1er digit de la colonne 2 doit obligatoirement etre "1")
70 1001
50 1002
30 1003
20 1005
30 1006
40 1007

# compteur.txt (le 1er digit de chaque valeur doit obligatoirement etre "1")
1001 1003
1005 1007

#!/bin/bash
while read var1 var2
do
sum=0      # desactiver pour le cumul de toutes les lignes
   until [ $var1 -gt $var2 ]
   do
   var3=`awk '$2 ~ '$var1' {print $1}' in.txt`
   echo $var3
   ((sum+=$var3))
   let var1=var1+1
   done
echo "s= " $sum
done < compteur.txt > tmp1.txt
awk '/s=/ {print $2}' tmp1.txt > tmp2.txt
paste compteur.txt tmp2.txt

# resultat
1001 1003  150
1005 1007  90

haut

Boucle "until" dans une boucle "while" dans une boucle "until" : encadrer des coupes a l'aide d'une liste (utilise 2 fichiers)


Le script obeit a 2 exigences :
   1- couper a 80 gigabytes
   2- se conformer au fichier de coupes : DERNCOUPE
      (on retire 1 a la coupe naturelle jusqu'a tomber sur la coupe la plus proche du fichier : exemple 1018-1-1-1=1015)
#ATTENTION SI 1er DIGIT DE "derncoupe.txt" EST UN ZERO , AJOUTER "1" DEVANT
#SINON LE SCRIPT NE MARCHE PAS
# exemple de : DERNCOUPE :
1004
1008
1012
1015    
1020
1023
1028
1031
1036    
1040
1044
1048
1052    
1056
1060

#exemple de IN
32260554512 1001
32234319632 1002
32234985752 1003
8283995528 1004
32238992720 1005
32250757424 1006
32247232112 1007
2186732720 1008
32256352832 1009
32237035352 1010
32224502048 1011
5211655376 1012
32248472120 1013
32241708440 1014
29798462264 1015
32255768696 1017
32227391984 1018
32234893520 1019
1018061048 1020   # le curseur doit etre ici (pas de retour chariot sur la ligne suivante)

#!/bin/bash
###########  parametres   ######
IN=SY.txt
DERNCOUPE=derncoupe.txt
LIMIT=110
LOOP=10

# attention 3 lignes a activer oubien desactiver (au debut du script)

###########  fin des parametres   ######

###########  preparation    ##########
#deleter les anciens resultats
rm coupe*.txt

#habillage (conversion en Giga bytes)
awk '{print NR,$1/1024/1024/1024}' $IN > ina.txt 
paste ina.txt $IN > inb.txt

########  attention si un caractere sur chaque fin de lignes provoque une erreur, il faut l'enlever ainsi:
#executer les 2 lignes suivantes
#sed 's/\t/ /g' inb.txt | sed 's/.$//g' > inc.txt                                   # <-- activer ici si besoin
#awk '{print $1,$4,$2}' inc.txt > ind1.txt  # attention au 1 ici (fichier de base)  # <-- activer ici si besoin
########

########  si aucun caractere ne gene : changer seulement inc.txt en inb.txt
awk '{print $1,$4,$2}' inb.txt > ind1.txt  # attention au "1" ici (fichier de base)   # <-- activer ici si besoin
########

#nb de lignes a traiter
nbtotalignes=`cat ind1.txt|wc -l`
nbtotalignesfin=`expr $nbtotalignes + 1`  # pour l'arret du script

#1ere ligne de DERNCOUPE
firstcoupe=`sed '1q;d' $DERNCOUPE`

##########   fin de preparation     ###########

###########    boucles des coupes obligees   ####################

N=1
until [ "$N" == $LOOP ]    #syntaxe de debut des boucles
do                         
  echo "boucle numero "$N " (fichier coupe"$N".txt)"   #syntaxe de debut des boucles
  # le script
  awk '{
  $4=total+=$3 
  $5=$4 <= '$LIMIT' ? $4 : ""
  {print $1,$2,$3,$4,$5}
  }' ind$N.txt > in-resultemp$N.txt  

  #noter le pattern (SY) de la derniere ligne
  var=`awk '$5 != "" {print}' in-resultemp$N.txt | tail -n1 | awk '{print $2}'` 
  echo "coupe naturelle : "$var " ; 1ere coupe du fichier "$DERNCOUPE " = " $firstcoupe              
  echo $var > var.txt       
  
  #creation du fichier des variables decroissantes
  awk '{print $1" "$1-10}' var.txt > vardecroi.txt  
    
  #boucle pour trouver le numero de coupe le + proche de $var.txt
     while read var varlast            
     do
        until [ $var -eq $varlast ]         
        do
        varnew=`awk '$1 ~ '$var' {print $1}' $DERNCOUPE`         
        echo $varnew     #indispensable pour ecrire ds fichier       
        let var=var-1                            
        done
     done < vardecroi.txt  > vardecroitemp.txt  
       
  #capture de la 1ere ligne de data du fichier correspondant a la coupe
  varstop=`awk '/./ {print $0}' vardecroitemp.txt | head -n1`  
  echo "coupe obligee : "$varstop  
  
  #arret du script si la 1ere coupe du fichier $DERNCOUPE est trop petite
  if [[ $varstop = "" ]]
  then echo "attention : ajouter une coupe plus petite dans le fichier $DERNCOUPE"
  exit
  fi

  #capture du numero de ligne ou il faut stopper  
  varstopnbline=`awk '$2 == '$varstop' {print}' in-resultemp$N.txt | awk '{print $1}'` 
  echo $varstopnbline " / " $nbtotalignes  " (numero de la derniere ligne)"   
  #sortie a la ligne suivante et ecriture dans "coupe...txt
  let varstopnblinenext=varstopnbline+1 ; echo $varstopnblinenext
  
  #signaler que le nombre de boucles n'est pas suffisant
  if [[ $varstopnbline < $nbtotalignes ]]
  then echo "attention le nb de boucles n'est pas suffisant ("$LOOP")"
  elif [ $varstopnbline = $nbtotalignes ]
  then echo "ok le nb de boucles est suffisant"
  fi

  echo "-------------------"        
  #ecriture dans les fichiers "coupes*.txt"
  awk '$1 == '$varstopnblinenext' {exit} {print}' in-resultemp$N.txt > coupe$N.txt 
  
  #arret du script a la fin des lignes (+1)
  if [ $varstopnblinenext = $nbtotalignesfin ] 
  then echo "FIN : nb de boucles faites : "$N" (sur "$LOOP" programmees)"
  exit
  fi
  #nouveau fichier pour la boucle suivante : de la ligne suivante a la fin 
  sed ''$varstopnblinenext',$!d' ind1.txt > ind`expr $N + 1`.txt   #ne pas changer ind1.txt
N=`expr $N + 1`  
done             #syntaxe de fin des boucles

# resultat
#1er cas : le message est le suivant:
#      "attention : ajouter une coupe plus petite dans le fichier $DERNCOUPE
#exemple : si la coupe naturelle = 1002
#et que la 1ere coupe du fichier $DERNCOUPE = 1004
#il faut ajouter une coupe plus petite dans le fichier (exemple: 1002)

#2eme cas : le message est le suivant:
#      "attention le nombre de boucles n'est pas suffisant"
#dans ce cas : augmenter la variable "LOOP"

#3eme cas : le message est le suivant :
#      "ok le nombre de boucles est suffisant"
#      "FIN : nombre de boucles faites : 9 sur 12"
#dans ce cas 9 fichiers coupe*.txt ont ete crees
#le script est termine

haut

Position et extraction d'un caractere dans une chaine ; remplacement de caracteres ; longueur de la chaine


# position d'un caractere
chaine=abcABCabc
echo `expr index "$chaine" c`
# resultat : 3

# extraction d'un caractere
chaine=abcABCabc
echo `expr substr $chaine 2 2`
# resultat : bc

echo `expr match "$chaine" '.*\([A-C][A-C][A-C][a-c]*\)'`
echo `expr "$chaine" : '.*\(......\)'`
# resultat : ABCabc

# remplacer 1ere occurrence de abc par xyz
echo ${chaine/abc/xyz}
echo ${chaine/#abc/xyz}
# resultat : xyzABCabc

# remplacer toutes les occurrences de abc par xyz
echo ${chaine//abc/xyz}
# resultat : xyzABCxyz

# remplacer la derniere occurrence de abc par xyz
echo ${chaine/%abc/xyz}
# resultat : abcABCxyz

# longueur de la chaine
chaine=abcABCabc
echo ${#chaine}
echo `expr length $chaine`
echo `expr "$chaine" : '.*'`
# resultat : 9

haut

Le caractere est le critere de selection de lignes d'un fichier (utilise 2 boucles while)


# in.txt
"quiet the dragons of worry and fear" 43
"steady yourself" 60
"After the fight both men need to cool off." 95
"It took a while after the baby was born for things to settle down again." 97
"The patient must be sedated before the operation" 122

#!/bin/bash
# deleter,les resultats precedents
rm inter*.txt

# les lignes sont lues en selectionnant leurs 2eme caractere
while read minline
do
  var4=`echo $minline | cut -c2-2`
  echo $var4 >> inter1.txt     

  var5=`cat inter1.txt | awk '$0 ~ /[a-z]/ {print}'`
  echo "$var5" > inter2.txt

    while read minlineletter
    do
    if [[ $var4 = $minlineletter ]] ; then echo $minline ; fi
    done < inter2.txt 

done < in.txt >> out.txt   

# out.txt
# "quiet the dragons of worry and fear" 43
# "steady yourself" 60

haut

Capture d'un paragraphe avec pattern de debut mais pas de fin (exemple 1)


#!/bin/bash

# separ.txt :
# pattern titre1
# data1 line1
# data1 line2
# data1 line3
# pattern titre2
# data2 line1
# data2 line2
# data2 line3

awk 'BEGIN{ line = "line" }
{if ($1 == "pattern") line = substr($2,3,4)
print > line
}' separ.txt

# tre1 :
# separ.txt
# pattern titre1
# data1 line1
# data1 line2
# data1 line3

# tre2 :
# pattern titre2
# data2 line1
# data2 line2
# data2 line3

haut

Capture d'un paragraphe avec pattern de debut mais pas de fin (exemple 2)


# csplit.txt :
% verb1
data1
data2
% verb2
data3
data4

# 'csplit' va creer autant de fichiers que de patterns %
# compter auparavant le nombre de patterns %
# et indiquer dans {1} ce nombre retranche de 1 (ici: 2-1=1)

#!/bin/bash
csplit -z -f file csplit.txt "/^%/" {1}

# resultat: creation de 2 fichiers : file00 et file01
# contenu de file00
% verb1
data1
data2

# contenu de file01
% verb2
data3
data4

haut

Capture d'un paragraphe avec pattern de debut mais pas de fin (exemple 3)


# in.txt

data0
AA 1
data1
AA 2
data2
AA 3
data3
AA 4
data4
AA 5
data5

#!/bin/bash

awk '$1 == "AA" {c++}
{if ((c == 1) || (c == 3)) print}
c == 4 {exit}
' in.txt

# resultat
AA 1
data1
AA 3
data3

haut

Capture d'un paragraphe avec pattern de debut et de fin dans plusieurs fichiers (exemple court)


# file1.txt
line1
start data1
area 1
data1
stop
line6
data

# file2.txt
line1
start data3
area 3
data3
stop 3
inter 1
inter 2
start data3bis
line9
data
stop 3bis

#!/bin/bash
for i in file*.txt
do
sed -n '
/start/ {:a
N
/stop/ !ba
p
}' $i
done

# resultat
start data1
area 1
data1
stop
start data3
area 3
data3
stop 3
start data3bis
line9
data
stop 3bis

haut

Capture d'un paragraphe avec pattern de debut et de fin dans plusieurs fichiers (exemple long)



# test1-listoread.txt : fichier contenant: in1.txt in2.txt in3.txt 

# fichier : in1.txt

H0100AREA NAME : BLOCK 660                               
V00669-002      1     101
S00669-002      11    101
Z00669-002      11    101
T00669-002      1 1   101
R   1 486096.47362886.9 8.0   
R   4 486133.47362881.6 8.0   
V00669-002      1     102    # ligne "S" manquante
Z00669-002      11    102
T00669-002      1 1   102
R   1 486077.77362889.9 8.0  
R   4 486114.77362884.6 8.0  
V00669-002      1     103
S00669-002      11    103
Z00669-002      11    103
T00669-002      1 1   103
R   1 486059.17362893.1 8.0   
R   4 486096.17362887.8 8.0   
-------------
# fichier : in2.txt

H0100AREA NAME : BLOCK 661                             
V00669-002      1     110    # ligne "S" manquante
Z00669-002      11    110
T00669-002      1 1   110
R   1 486096.47362886.9 
R   4 486133.47362881.6 
V00669-002      1     111
S00669-002      11    111
Z00669-002      11    111
T00669-002      1 1   111
R   1 486077.77362889.9 
R   4 486114.77362884.6 
V00669-002      1     112
S00669-002      11    112
Z00669-002      11    112
T00669-002      1 1   112
R   1 486059.17362893.1  
R   4 486096.17362887.8 
------------
# fichier : in3.txt

H0100AREA NAME : BLOCK 661                             
V00669-002      1     120
S00669-002      11    120
Z00669-002      11    120
T00669-002      1 1   120
R   1 486096.47362886.9 
R   4 486133.47362881.6 
V00669-002      1     121
S00669-002      11    121
Z00669-002      11    121
T00669-002      1 1   121
R   1 486077.77362889.9 
R   4 486114.77362884.6 
V00669-002      1     122    # ligne "S" manquante
Z00669-002      11    122
T00669-002      1 1   122
R   1 486059.17362893.1  
R   4 486096.17362887.8 

#!/bin/bash

# but du script : capturer les paragraphes entre "S" et "V"

# deleter les anciens resultats
ls out*.txt > delete-fichiers.txt
while read line
do
if [ -e $line ] ; then rm $line ; fi
done < delete-fichiers.txt


while read line
do

awk 'BEGIN{ outV = "outV.txt"    # print la ligne "V"
            outbetweenpatterns = "outbetweenpatterns.txt"    # print entre le pattern de debut et celui de fin
            outwithoutS = "outwithoutS.txt"       # signale les lignes "S" manquantes
          }
{
# definir le pattern du debut
if ( $0 ~ /^S/ )    #pattern debut       
     flag = 1    
     {
     # deleter des lignes commentaires 
           # if ( $0 ~ /^Z/ ) {next}  #desactiver car on se sert des lignes "Z" pour la suite
           # if ( $0 ~ /^T/ ) {next}
     # marquer des lignes qui servent de compteurs
     if ( $0 ~ /^V/ ) {print $0 >> outV}
     
     # definir le pattern de la fin
     if ( $0 ~ /^V/ )    #pattern fin
          flag = 0     
          {
          # traitement du data entre les patterns
          if ( flag == 1 )
          print $0 >> outbetweenpatterns
          
          # signalement des patterns de debut manquant  (lignes "S" manquantes)
          if ( flag == 0 && $0 ~ /^Z/ )        # on se sert des lignes "Z" ici
          print "sp " substr($0,21,5) " missing on nav for line " substr($0,2,9) >> outwithoutS
          }
     }
}' $line

done < test1-listoread.txt

# resultats
# fichier : outV.txt

V00669-002      1     101
V00669-002      1     102
V00669-002      1     103
V00669-002      1     110
V00669-002      1     111
V00669-002      1     112
V00669-002      1     120
V00669-002      1     121
V00669-002      1     122

#fichier : outbetweenpatterns.txt

S00669-002      11    101
Z00669-002      11    101
T00669-002      1 1   101
R   1 486096.47362886.9 8.0   
R   4 486133.47362881.6 8.0   
S00669-002      11    103
Z00669-002      11    103
T00669-002      1 1   103
R   1 486059.17362893.1 8.0   
R   4 486096.17362887.8 8.0   

S00669-002      11    111
Z00669-002      11    111
T00669-002      1 1   111
R   1 486077.77362889.9 
R   4 486114.77362884.6 
S00669-002      11    112
Z00669-002      11    112
T00669-002      1 1   112
R   1 486059.17362893.1  
R   4 486096.17362887.8 

S00669-002      11    120
Z00669-002      11    120
T00669-002      1 1   120
R   1 486096.47362886.9 
R   4 486133.47362881.6 
S00669-002      11    121
Z00669-002      11    121
T00669-002      1 1   121
R   1 486077.77362889.9 
R   4 486114.77362884.6 

# fichier : outwithoutS.txt

sp  102 missing on nav for line 00669-002
sp  110 missing on nav for line 00669-002
sp  122 missing on nav for line 00669-002

haut

Supprimer un paragraphe s'il contient un pattern


# IN
% 1
data2
titi
line 6

% 2
data3
pattern
line 9

% 3
data4
tutu
line 12

% 4
data5
col1 pattern
line 15

% 5
data1
toto
line 3

#!/bin/bash

#################   parametres

PATTERN=pattern       # 1/4  pattern qui selectionne le paragraphe
SEPAR=%               # 2/4  caractere separant les paragraphes
IN=z-parag.txt          # 3/4  fichier entree
OUT=z-parag-OUT.txt     # 4/4  fichier sortie

################   fin des parametres

# deleter le fichier s'il contient le pattern

echo $SEPAR
echo $PATTERN

# compter nb de paragraphes (= nb fois la variable SEPAR)
LIMIT=`grep "^$SEPAR" $IN | wc -l`
echo "nb total de paragraphes separes par $SEPAR = " $LIMIT

rm zpar*
sleep 5

# ecrire 1 paragraphe par fichier
i=1
until (( $i > "$LIMIT" ))
do
awk '$1 == "'"$SEPAR"'" {c++}
{if (( c == '$i' )) print}
' $IN > zpar$i
((i++))
done

# deleter le fichier s'il contient le pattern
for i in `ls zpar*`
do
   while read line
   do
   if [[ $line =~ "$PATTERN" ]] ; then rm $i ; fi
   done < $i
done

# rassembler les paragraphes ne contenant pas: "PATTERN"
cat zpar* > $OUT

echo "nb total de paragraphes separes par $SEPAR = " $LIMIT    #5
AFTER=`ls zpar* | wc -l`
echo "nb de paragraphes ne contenant pas: $PATTERN = " $AFTER    #3

# resultat
% 1
data2
titi
line 6

% 3
data4
tutu
line 12

% 5
data1
toto
line 3

haut

Capturer un paragraphe s'il contient un pattern


# IN
% 1
data2
titi
line 6

% 2
data3
pattern
line 9

% 3
data4
tutu
line 12

% 4
data5
col1 pattern
line 15

% 5
data1
toto
line 3

#!/bin/bash

#################   parametres

PATTERN=pattern       # 1/4  pattern qui selectionne le paragraphe
SEPAR=%               # 2/4  caractere separant les paragraphes
IN=z-parag.txt          # 3/4  fichier entree
OUT=z-parag-OUT.txt     # 4/4  fichier sortie

################   fin des parametres

# garder le fichier s'il contient un pattern

#script
echo $SEPAR
echo $PATTERN

# compter nb de paragraphes (= nb fois la variable SEPAR)
LIMIT=`grep "^$SEPAR" $IN | wc -l`
echo "nb total de paragraphes separes par $SEPAR = " $LIMIT

rm zpar*
rm yzpar*
sleep 5

# ecrire 1 paragraphe par fichier
i=1
until (( $i > "$LIMIT" ))
do
awk '$1 == "'"$SEPAR"'" {c++}
{if (( c == '$i' )) print}
' $IN > zpar$i
((i++))
done

# renommer le fichier s'il contient le pattern
for i in `ls zpar*`
do
   while read line
   do
   if [[ $line =~ "$PATTERN" ]] ; then mv $i y$i ; fi
   done < $i  
done

rm zpar*
# rassembler les paragraphes contenant "PATTERN"
cat yzpar* > $OUT

echo "nb total de paragraphes separes par $SEPAR = " $LIMIT    #5
AFTER=`ls yzpar* | wc -l`
echo "nb de paragraphes contenant: $PATTERN = " $AFTER     #2

# resultat
% 2
data3
pattern
line 9

% 4
data5
col1 pattern
line 15

haut

Chercher les paragraphes qui contiennent une serie de patterns et ceux qui ne les contiennent pas


# z-parag.txt
% 1
data2
titi
line 6

% 2
data3
adjective
line 9

% 3
data4
tutu
line 12

% 4
data5
col1 objet
line 15

% 5
data1
toto
line 3

#   contenu de $FILEPATTERN :
#   adjective
#   objet

#!/bin/bash

#################   parametres

FILEPATTERN=z-multipattern.txt  # 1/5 fichier contenant les patterns
SEPAR=%                         # 2/5  caractere separant les paragraphes
IN=z-parag.txt                  # 3/5  fichier entree
WITH=z-out-ok-pattern.txt       # 4/5  fichier sortie contenant les paragraphes avec patterns
WITHOUT=z-out-no-pattern.txt    # 5/5  fichier sortie contenant les paragraphes sans patterns

################   fin des parametres

# compter nb de paragraphes (= nb fois la variable SEPAR)
LIMIT=`grep "^$SEPAR" $IN | wc -l`

# deleter les resultats precedents
rm zpar*
rm yzpar*
sleep 3

# ecrire 1 paragraphe par fichier
i=1
until (( $i > "$LIMIT" ))
do
awk '$1 == "'"$SEPAR"'" {c++}
{if (( c == '$i' )) print}
' $IN > zpar$i
((i++))
done

# renommer les fichiers de paragraphes s'ils contiennent les patterns
for i in `ls zpar*`
do
   while read line     # boucle sur les paragraphes
   do
        for j in `cat $FILEPATTERN`    # boucle sur les patterns
        do        
             if [[ $line =~ "$j" ]] ; then mv $i y$i ; fi
        done   
   done < $i  
done  
     
# ajouter zero devant 1 a 9  --->  01 a 09 (pour zpar)
for i in `seq 1 9`
do
mv zpar$i zpar0$i
done   2>dev>null

# ajouter zero devant 1 a 9  --->  01 a 09 (pour yzpar)
for i in `seq 1 9`
do
mv yzpar$i yzpar0$i
done   2>dev>null

# regrouper les paragraphes :
cat yzpar* > $WITH      # contenant les patterns
cat zpar* > $WITHOUT    # ne contenant pas les patterns

echo "nb total de paragraphes separes par $SEPAR = " $LIMIT
AFTER=`ls yzpar* | wc -l`
AFTER2=`ls zpar* | wc -l`
echo "nb de paragraphes contenant les patterns = " $AFTER
echo "nb de paragraphes ne contenant pas les patterns = " $AFTER2


# $WITH
% 2
data3
adjective
line 9

% 4
data5
col1 objet
line 15


# $WITHOUT
% 1
data2
titi
line 6

% 3
data4
tutu
line 12

% 5
data1
toto
line 3

haut

Capture de lignes avec pattern de debut et de fin


in.txt
line1
data1
_start
data2
line5
_end
data3
line8
data4

#!/bin/bash
i=1
until [ $i -gt "10" ]
do
S=`grep -n "start" in.txt | awk -F":" '{print $1}'`
S=`expr $S + $i`
var=`sed -n "$S p" in.txt`
echo $var
if [[ $var =~ "end" ]] ; then break ; fi
let i=i+1
done

# resultat
data2
line5
_end

haut

Capturer le pattern pour une comparaison, un cumul ...


#!/bin/bash
# in.txt
# 10001 30
# 10002 2
# 10003 25
# 10004 30
# 10005 14

NBLINES=`sed -n -e '$=' in.txt` ; echo "nombre de lignes : $NBLINES"

# boucle sur les lignes
COUNT=1
until [[ "$COUNT" -gt "$NBLINES" ]]
do
echo "--> nb of line = $COUNT :"

cat in.txt | awk '{print $2}' | head -$COUNT | tail -1

sleep 1
let COUNT=COUNT+1
done

# resultat
# nombre de lignes : 5
# --> nb of line = 1 :
# 30
# --> nb of line = 2 :
# 2
# --> nb of line = 3 :
# 25
# --> nb of line = 4 :
# 30
# --> nb of line = 5 :
# 14

haut

Compter le nombre de mots d'un fichier


#!/bin/bash
awk 'BEGIN{n=0} {n+=NF} END {print "words: ",n}' in.txt

# autre methode
cat in.txt | wc -w

haut

Compter le nombre d'occurrences de chaque mot d'une colonne


# in.txt
data1 line1
data1 line2
data1 line3
data2 line4
data2 line5

#!/bin/bash
awk '{count[$1]++}
END { for ( i in count )
print count[i] " fois " i }' FS=" " in.txt

# resultat
3 fois data1
2 fois data2

haut

Compter le nombre d'occurrences de chaque mot d'un fichier


#!/bin/bash
awk '{
for (i=1; i<=NF; i++)
mot[$i]++        # mot[$i]=mot[$i]+1
}
END {
for (i in mot)
print mot[i],i
}' in.txt | sort -n -r

haut

Compter le nombre d'occurrences d'une lettre d'un fichier


# in.txt
data1 unix line1
data2 bash
data3 unix line3

#!/bin/bash
string=`cat in.txt`
string="${string//[^i]/}"     # 'i' est la lettre recherchee
echo "nombre d'occurrences de la lettre: " ${#string}
echo "trouvee aux lignes:"
awk -v c="i" '{ if( gsub(c, "")) print NR, "found" }' in.txt

# resultat
nombre d'occurrences de la lettre : 4
trouvee aux lignes:
1 found
3 found

haut

Compter le nombre de champs de chaque ligne


# in.txt
exemple pour 
connaitre le nombre
de champs de chaque ligne

# 1_ en "awk"

#!/bin/bash
awk '{cnt=0 ; for ( i=1; i<=NF; i++ )
{ if ( $i != "" ) {cnt++}}
{print cnt " fields"}
}' FS=" " in.txt

# 2_ en "bash"

#!/bin/bash
while read line
do
echo $line | awk 'BEGIN{FS=OFS=" "} {x=x+NF} END {print x " fields"}'
done < in.txt

# resultat
2 fields
3 fields
5 fields

haut

Compter le nombre d'occurrences d'un caractere dans plusieurs fichiers


#!/bin/bash
# fichier z1.txt
# 123 234 3451 456 567
# 123 234 0001 456 567
# 123 234 9991 456 567
# 123 234 8881 456 567
# 123 234 7771 456 567
# 123 234 6661 456 567

# fichier z2.txt
# 123 234 3452 456 567
# 123 234 0002 456 567
# 123 234 9992 456 567
# 123 234 8881 456 567
# 123 234 7771 456 567
# 123 234 6661 456 567

# capture du 4eme caractere de la colonne 3
for i in `ls z*.txt`
do
awk '{print substr($3,4,1)}' $i > y-$i
done

# supprimer les lignes vides
for i in `ls y-z*.txt`
do
sed '/^$/d' $i > x$i
done

# frequence
for j in `ls xy-z*.txt`
do
   awk '{
   for (i=1 ; i<=NF ; i++)
   mot[$i]++
   }
   END {
   for (i in mot)
   print i " -->" , mot[i]" occurrences"
   }' $j > v$j
done

# marquer le nom du fichier devant chaque ligne
for i in vxy-z*.txt
do
seq=`ls $i | cut -c5-10`
awk '{print seq" : ",$0}' seq=${seq} $i
echo "-----"
done

# resultat
z1.txt:  1 --> 6 occurrences
# -----
z2.txt:  1 --> 3 occurrences
z2.txt:  2 --> 3 occurrences
# -----

haut

Marquer les occurrences d'un pattern (exemple 1)


# in.txt
pattern
line2
line3
pattern
line5
pattern
line7

# marquer numeriquement l'occurrence d'un pattern (en awk)
awk '/pattern/ {i=i+1} {print $0,i}' in.txt |
awk '!a[$NF]++ {print $0 ; next} {sub($NF, "") ; print}'

# resultat
pattern 1
line2
line3
pattern 2
line5
pattern 3
line7

haut

Marquer les occurrences d'un pattern (exemple 2)


# in.txt
line1 data1
line2 data2 -
line3 data3
line3 data4
line3 data5 -
line3 data6 -

# marquer numeriquement l'occurrence d'un pattern (ici "-")

awk '$3 ~ /^-/ {i=i+1} {print $0,i} 
     $3 !~ /^-/ {next}
     ' in.txt | awk '$3 ~ /^[0-9]/ {$3 = ""} {print}'

# resultat
line1 data1
line2 data2 - 1
line3 data3 
line3 data4 
line3 data5 - 2
line3 data6 - 3

haut

Marquer des patterns en utilisant des conditions


# in.txt
line 1
line 2 -
line 3 data 1 -
line 4 data 4 g -
line 5 data 5 h -
line 6 data 6 -

#!/bin/bash

# exemple 1 : awk + if/else
#--------------------------

awk '
{if($3 ~ /^-/) {print $0"@"}
else
{print}
}' in.txt

# exemple 2 : awk + condition sans 'if'
#----------------------------------------

awk '
$3 ~ /^-/ {print $0"@"}
$3 !~ /^-/ {print}
' in.txt

# resultat identique pour scripts 1 et 2
# line 1
# line 2 -@
# line 3 data 1 -
# line 4 data 4 g -
# line 5 data 5 h -
# line 6 data 6 -

# exemple 3 : awk + plusieurs conditions
#---------------------------------------

awk '
$0 !~ /-/ {print}
$0 ~ /-/ && $5 == "g" {print $0"@"}
$0 ~ /-/ && $5 != "g" {print $0"%%"}' in.txt

# resultat
# line 1
# line 2 -%%
# line 3 data 1 -%%
# line 4 data 4 g -@
# line 5 data 5 h -%%
# line 6 data 6 -%%

# exemple 4 : bash + if/elif/fi
#------------------------------

while read line 
do
if [[ $line =~ "-" && $line =~ "g" ]] ; then echo $line | awk '{print $0"@"}'
elif [[ $line =~ "h" ]] ; then echo $line | awk '{print $0"%"}'
else
echo $line
fi
sleep 1
done < in.txt

# resultat
# line 1
# line 2 -
# line 3 data 1 -
# line 4 data 4 g -@
# line 5 data 5 h -%
# line 6 data 6 -

haut

Comparer la forme d'une variable sur un modele


#!/bin/bash

########### parametres
VAR=HEllo
MODEL="^[[:upper:]]{2}[[:lower:]]*$"

############## fin des parametres

if [[ $VAR =~ $MODEL ]] ; then echo "same model"
else
echo "no match with model"
fi

# resultat
same model

haut

Conditionner l'acces au pattern par sa position, sa valeur, sa longueur


# in.txt
line 1
line 2 -
line 3 data 1 -
line 4 data 4 g -
line 5 data 5 h -
line 6 data 6 -

# 1 - la position est la condition d'acces au pattern

#!/bin/bash
while read line
do
echo `expr substr "$line" 15 1`
done < in.txt

# resultat
-
g
h
-

######################

# 2 - la valeur est la condition d'acces au pattern

while read line
do
a=`expr "$line" : '.....\(.\).*'`
if [[ $a != "4" ]] ; then
echo "no"
else
echo $line
fi
done < in.txt

# resultat
no
no
no
line 4 data 4 g
no
no

######################

# 3 - la longueur est la condition d'acces au pattern

while read line
do
a=`expr length "$line"`
if [[ $a = "15" ]] ; then echo $line
else
echo "no"
fi
done < in.txt

# resultat
no
no
line 3 data 1 -
no
no
line 6 data 6 -

haut

IF dans une boucle while


# in.txt
line1 %% data1
data2
line3 data3#
line4

#!/bin/bash
while read line
do
if [[ $line =~ "%%" ]] || [[ $line =~ "#" ]] ; then echo $line 
else
continue 
fi
done < in.txt

# resultat
line1 %% data1
line3 data3#

haut

IF ELIF en BASH


# in.txt
data1 03 5000 data2 18 6500 
data3 07 4000 data4 07 5000 
data5 23 7000 data6 23 4000 
data7 25 5000 data8 19 6500 

#!/bin/bash
while read line
do
  if [[ `echo $line|awk '{print $2}'` < `echo $line|awk '{print $5}'` ]] ; then echo $line"   -> ok"

    elif [[ `echo $line|awk '{print $2}'` = `echo $line|awk '{print $5}'` ]] && [[ `echo $line|awk '{print $3}'` < `echo $line|awk '{print $6}'` ]] ; then echo $line"   -> egal ok"

    elif [[ `echo $line|awk '{print $2}'` = `echo $line|awk '{print $5}'` ]] && [[ `echo $line|awk '{print $3}'` > `echo $line|awk '{print $6}'` ]] ; then echo $line"   -> egal --- attention a verifier"

else
echo $line"   -> attention a verifier"
fi
done < in.txt 

# resultat
data1 03 5000 data2 18 6500   -> ok
data3 07 4000 data4 07 5000   -> egal ok
data5 23 7000 data6 23 4000   -> egal --- attention a verifier
data7 25 5000 data8 19 6500   -> attention a verifier

haut

LENGTH ajoute des digits a une colonne


# But : ajouter 1 digit a une collonne, sans demolir la synthaxe du reste
# in.txt
accept 1 to take; to receive
accept 2 to regard as true

awk '{if(length($2) == 1) {$2="0"$2} {print}}' in.txt

# resultat
accept 01 to take; to receive
accept 02 to regard as true

haut

IF ELSE IF en AWK


# in.txt
data1 03 5000 data2 18 6500 
data3 07 4000 data4 07 5000 
data5 23 7000 data6 23 4000 
data7 25 5000 data8 19 6500 

#!/bin/bash
awk '{
if($2 < $5) {print $0" ok"}
else if($2 == $5 && $3 < $6) {print $0" egal ok"}
else if($2 == $5 && $3 > $6) {print $0" to check"}
else
{print $0" no"}
}' in.txt

# resultat
data1 03 5000 data2 18 6500  ok
data3 07 4000 data4 07 5000  egal ok
data5 23 7000 data6 23 4000  to check
data7 25 5000 data8 19 6500  no

haut

Substitution d'une chaine


#!/bin/bash
string="abcABC123ABCabc"
echo ${string/abc/xyz}      # xyzABC123ABCabc
echo ${string//abc/xyz}     # xyzABC123ABCxyz
echo ${string/#abc/XYZ}     # XYZABC123ABCxyz
echo ${string/%abc/XYZ}     # abcABC123ABCXYZ   
echo | awk '{ print substr("'"${string}"'",5 ,4) }'     # BC12

haut

Mettre un fichier dans un array


# in.txt
data1 a
data2 b

#!/bin/bash
array=(`cat in.txt`)
echo "${array[*]}"    # data1 a data2 b
len=${#array[*]}    # nombre d'elements dans array
echo $len         # 4

i=0
while [ $i -lt $len ]
do
echo "$i : ${array[$i]}"
let i++
done

# resultat
0 : data1
1 : a
2 : data2
3 : b

haut

Mettre en variable chaque mot d'un fichier


# in.txt
mot1 mot2 mot3 mot4 mot5
mot6 mot7 mot8 mot9 mot10

#!/bin/bash
variable=`cat in.txt`
set -- $variable
# 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 > tempw.txt

while read line;do eval $line;done < tempw.txt > /dev/null
#variable valable  a l'exterieur du script:
echo $var7   # mot7

# pour lister toutes les variables:
for j in $@
do
echo $j
done

haut

Mettre en variable chaque ligne d'un fichier (methode courte)


#mettre en variable le contenu d'une liste de fichiers
for i in fichier*; do echo $i; done > liste1.txt
#creer un fichier de lignes de commandes
for i in `ls fichier*`
do
seq=`ls $i | cut -c8`   #les numeros des fichiers sont mis en variable
echo var$seq=\`awk \'NR==$seq {print}\' liste1.txt\` "; echo \$var$seq"
done > liste2.txt
#executer les lignes de commandes
while read line; do eval $line; done < liste2.txt > /dev/null
#nombre de lignes
nb=`awk 'END{print NR}' liste1.txt`
#boucle sur toutes les variables
for ((j=1; j<=$nb; j++)); do eval echo \$var$j; done

haut

Mettre en variable chaque ligne d'un fichier (methode longue)


# in.txt
mot1 mot2 mot3 mot4 mot5
mot6 mot7 mot8 mot9 mot10

#!/bin/bash
#nombre de lignes dans fichier (attention ajouter un retour charriot apres la derniere ligne)
nb=`awk 'END{print NR}' in.txt`
#enregistrer chaque ligne dans 1 variable 
for i in `seq 1 $nb`
do
echo tab$i="\$(cat in.txt | awk 'NR == "$i" {print}') ; echo \$"tab$i
done > templ.txt

while read line; do eval $line; done < templ.txt > /dev/null
#variable valable  a l'exterieur du script
#boucle pour recuperer toutes les variables
for ((j=1; j<=$nb; j++))
do
eval echo \$tab$j
done

haut

Mettre en variable chaque colonne d'un fichier


# in.txt
mot1 mot2 mot3 mot4 mot5
mot6 mot7 mot8 mot9 mot10

#!/bin/bash
#nombre de champs du fichier
awk '{print NF}' in.txt > nbchamps.txt
#prendre le nombre maxi de colonnes
awk 'max=="" || $1 > max {max=$1} END{print max}' FS=" " nbchamps.txt > nbchamps2.txt

f=`cat nbchamps2.txt`
for i in `seq 1 $f`
do
echo "var$i=\`awk '{j=$i ; print \$j}' in.txt\` ; echo \"\$var$i\""
done > tempc.txt
while read line;do eval $line;done < tempc.txt > /dev/null
#variables peuvent etre lues a l'exterieur: #echo "$var2" 

#recuperer toutes les variables
for ((i=1; i<=$f; i++))
do
eval echo \$var$i | tr " " "\n"
done

#print une seule fois les elements de la colonne 1 
w=`echo "$var1" | awk '{g[$1]++} END {for (a in g) {print a}}' | sort`
echo "$w"

haut

Mettre en variable une colonne pour une action avec un 2eme fichier


# in1.txt           # in2.txt
a                   data1 a something1
b                   data2 b something2
d                   data3 c something3
                    data4 d something4

# methode 1 :
for id in `cat in1.txt`
do
awk -F " " -v x=$id '$2==x {print}' in2.txt
done

# methode 2 :
awk '{if(NF==1) _[$0]=$0
else
for (i in _) if ($2==i) print
}' FS=" " in1.txt in2.txt

# resultat
data1 a something1
data2 b something2
data4 d something4

haut

Appel d'une variable


# in.txt
my name is OLD
the OLD engine

#!/bin/bash
var="OLD"
awk '{
sub(/'$var'/, "NEW")
print}' in.txt

#resultat
my name is NEW
the NEW engine

haut

Soumettre l'arret d'un script a l'absence d'un pattern


# L'absence de "pattern" dans le fichier in2.txt provoquera l'arret du script.

# in1.txt
data1
data2 pattern

# in2.txt
data3
data4

# in3.txt
data5
data6 pattern

#!/bin/bash
j=1
until [ "$j" -gt "3" ]
do
VAR="pattern"
lecture=`cat in"$j".txt`

   # l'option -q de grep supprime l'affichage de la ligne trouvee
   if echo "$lecture" | grep -q "$VAR"
   then
   echo \"$VAR\" "trouve dans le fichier " $j
   else
   echo \"$VAR\" "non trouve dans le fichier " $j
   break      # arret du script
   fi

let j=j+1
done    2>/dev/null

# resultat
"pattern" trouve dans le fichier 1
"pattern" non trouve dans le fichier 2

haut

Soumettre l'arret d'un script a la presence d'un pattern


# in.txt
line1
line2
line3
pattern
line5

#!/bin/bash
while true
do
read line
if [ "$line" = "pattern" ] ; then break ; fi
echo $line
sleep 1
done < in.txt

# resultat
line1
line2
line3

haut

Tester si un fichier existe


# on cree 1 fichier in.txt vide

# tester si le fichier existe

test -e in.txt  
     
var1=`echo $?`    # code retour = 0 -> commande bien executee 
                  # -> le fichier existe
echo $var1

if [ "$var1" -eq "0" ] ; then
echo "code retour=0 - bien execute - fichier existe"    # ; exit
else
echo "code retour=1 - mal execute - fichier n'existe pas"
fi

haut

Tester si un fichier a une taille non nulle


# tester si le fichier a une taille non nulle

test -s in.txt       #  Check if file is nonzero size

var2=`echo $?`   # code retour = 0 -> commande bien executee  
                 # -> le fichier a une taille non nulle
echo $var2

if [ "$var2" -eq "0" ] ; then
echo "code retour=0 - bien execute - file is nonzero size"  
else
echo "code retour=1 - mal execute - file is zero size"
fi

haut

Tester sur 2 fichiers


#!/bin/bash
if [[ -s in1.txt ]] && [[ -s in2.txt ]]
then echo "in1.txt et in2.txt ne sont pas vides"     # cas 1
   elif [[ -s in1.txt ]] || [[ -s in2.txt ]]
   then
      if [[ -s in1.txt ]] && [[ ! -s in2.txt ]]
      then echo "in1.txt est non vide et in2.txt est vide"   # cas 2
      elif [[ ! -s in1.txt ]] && [[ -s in2.txt ]]
      then echo "in1.txt est vide et in2.txt est non vide"   # cas 3
      fi
else
echo "in1.txt et in2.txt sont vides"   # cas 4
fi

haut

Code retour : 0 (vrai) ou 1 (faux)


# in.txt
123 data1 data2 456@

#!/bin/bash
for f in `cat in.txt`
do
[[ $f == *@ ]]
done
echo $?

#code retour : 0 : vrai

haut

Tester la présence d'un pattern


# in.txt
R
D
a

#!/bin/bash

#########  parametres
PATTERN=[a-z]
#########  fin des parametres

if [[ `while read line
     do
     if [[ $line =~ $PATTERN ]]
     then echo $line
     fi
     done < in.txt | wc -l` == "0" ]]
then echo "pas de minuscule"
else
echo "ok minuscule"
fi

# resultat
ok minuscule

haut

Tester si la ligne ne contient ni majuscule ni minuscule


# file.txt
"-"

#!/bin/bash
if [[ (`while read line
        do
        if [[ $line =~ [a-z] ]]
        then echo $line
        fi
        done < file.txt | wc -l` == "0")
        && (`while read line
        do
        if [[ $line =~ [A-Z] ]]
        then echo $line
        fi
        done < file.txt | wc -l` == "0") ]]
then
echo "ni minuscule ; ni majuscule"
else
echo "Une minuscule ou une majuscule"
fi

# resultat
ni minuscule ; ni majuscule

haut

Tester la presence d'un pattern en lisant ligne par ligne


# in.txt
line1
data2 toto
line3 pattern data3
data4

#!/bin/bash

#####   parametres
SEARCH=pattern
#####   fin des parametres

n=1
while read line
do
echo $line > tmp.txt
if grep -q "$SEARCH" tmp.txt ; then
echo "line : " $n " : ok pattern - code retour : "$?
else
echo "line : " $n " : pas de pattern sur cette ligne - code retour : "$?
fi
let n=n+1
sleep 1
done < in.txt 2>/dev/null

# resultat
line :  1  : pas de pattern sur cette ligne - code retour :  1
line :  2  : pas de pattern sur cette ligne - code retour :  1
line :  3  : ok pattern -  - code retour :  0
line :  4  : pas de pattern sur cette ligne - code retour :  1

haut

L'ecran du terminal ecrit dans un fichier


# script
# faire de Filedescriptor 6 (FD6) une copie de stdout (FD1)
exec 6>&1
# ouvrir le fichier 'out.txt' pour ecrire dedans
exec 1>>out.txt
echo "Cette ligne est envoyee dans le fichier: out.txt"
# fermer le fichier
exec 1>&-
# faire de stdout une copie de FD6 (reset stdout)
exec 1>&6
# fermer FD6
exec 6>&-

# resultat de 'out.txt':
Cette ligne est envoyee dans le fichier: out.txt

haut

Changer de separateur


# in.txt
data1,new1
data2,new2

#!/bin/bash
awk 'BEGIN{FS="," ; OFS=" "}
{$1=$1 ; print}' in.txt

# resultat
data1 new1
data2 new2

haut

Separateurs multiples (1 er exemple)


# in.txt
data1 | between two separators @ after second delimiter line1
data2 data3 | between two separators @ after second delimiter line2
data4 | between two separators @ line3

awk -F"[|,@]" '{printf ("%-15s %-15s\n",$1,$3)}' in.txt

# resultat
data1            after second delimiter line1
data2 data3      after second delimiter line2
data4            line3         

haut

Separateurs multiples (2 eme exemple)


# in.txt
one:data1/data2-data3
two:data1/data3
three: -data3

awk 'BEGIN{FS="[:,/,-]"}
{ for ( i=1; i<=NF; i++ )
{ if ( $i ~ /data3/ )
{ print "line " NR " column " i }}
}' in.txt

# resultat
line 1 col 4
line 2 col 3
line 3 col 3

haut

sub - gsub ( 1er exemple )


# in.txt
100KG 100KG
200MI 200MI
300GR 300GR

#!/bin/bash
awk 'sub( "..$", "" )' in.txt

# resultat
100KG 100
200MI 200
300GR 300

#!/bin/bash
var="MI" ; awk '{gsub( /'$var'/, "new" ) ; print}' in.txt

# resultat
100KG 100KG
200new 200new
300GR 300GR

haut

sub - gsub ( 2eme exemple )


# in.txt
data1 unix unix
UNIX data2
UniX data3 UniX

#!/bin/bash
awk 'BEGIN{IGNORECASE=1}
{sub( /unix/, "BEST" ) ; print}' in.txt

# resultat
data1 BEST unix
BEST data2
BEST data3 UniX

haut

sub - gsub ( 3eme exemple )


# in.txt
100 data1
100 data2
101 data3
101 data4

#!/bin/bash
awk -F " " '!arr[$1]++ {print $0 ; next}
{gsub( $1, "" ) ; print}' in.txt

# resultat
100 data1
 data2
101 data3
 data4

haut

sub - gsub ( 4eme exemple )


# in.txt
line1data1
line2data2
line3data3

#!/bin/bash
awk '{ first=substr($0,1,5)
gsub(/./,"X",first)
end=substr($0,6)
print first end
}' in.txt

# resultat
XXXXXdata1
XXXXXdata2
XXXXXdata3

haut

gensub


# in.txt
a line1 a data1 a
a line2 a data2 a

awk '{print gensub(/a/, "AA", 2)}' in.txt

# resultat
a line1 AA data1 a
a line2 AA data2 a

haut

sub=substitution


# in.txt
(reach a destination; arrive by movement or progress)
"These shoes come in three colors; The furniture comes unassembled"

awk '
$0 ~ /^"/ {sub("; " , "%") ; print}
$0 !~ /^"/ {print}
' in.txt | sed 's/%/%\n/g' | sed 's/%$//g'

# resultat
(reach a destination; arrive by movement or progress)
"These shoes come in three colors
The furniture comes unassembled"

haut

Un signe en debut de ligne 1, fait joindre la ligne 2 a la suite de la 1


# in.txt
@ arise
intransitive verb  
1.	 [appear, happen]     survenir,   se presenter 
2.	 [result]   resulter 

###### parametres
SIGNE="@"
###### fin des parametres

awk '
$0 ~ /^'$SIGNE'/ {e=$0 ; getline record ; f=e" "record}
{if( $1 == "'$SIGNE'" ) 
print f

else
print

}' in.txt

# resultat
@ arise intransitive verb  
1.	 [appear, happen]     survenir,   se presenter 
2.	 [result]   resulter 

haut

Ajouter le nom des fichiers devant chaque ligne


# file1-a.txt
data 1
data 2

# file2-b.txt
data 3
data 4

rm out.txt

for i in file*
do
seq=`ls $i | cut -c5-7`
# awk '{print seq,$0}' seq=${seq} $i  
# awk '/ciel/{print seq,$0}' seq=${seq} $i
awk '{printf ("%-10s %-10s\n",seq,$0)}' seq=${seq} $i >> out.txt
done

# resultat
1-a        data 1    
1-a        data 2    
                  
2-b        data 3    
2-b        data 4    

haut

Compteur d'occurrences


# repeat.txt
3
2
4

while read line
do
seq 1 $line
done < repeat.txt

# resultat
1
2
3
1
2
1
2
3
4

haut

Repeter une syntaxe un nombre de fois precise dans une colonne


# in.txt
data1  	3
data2 	2
data3 	4

while read col1 col2
do

   COUNTER=1
   until [  $COUNTER -gt $col2 ]
   do          
   echo $col1 
   let COUNTER=COUNTER+1               
   done                                    

done < in.txt 

# resultat
data1
data1
data1
data2
data2
data3
data3
data3
data3

haut

set (1er exemple)


#!/bin/bash
var="A B C D E F"
set -- $var
foo=$1      
shift 3
bar=$@
echo $foo     # A
echo $bar     # D E F

haut

set (2eme exemple)


# in.txt
line1 data1 string
line2
line3 data2

#!/bin/bash
c=0
while read line
do
((c+=1))
set -- $line
if [[ "$3" == "string" ]] ; then echo $c $1 
elif [ "$1" == "line3" ] ; then echo $c $2 
else
echo "nothing"
fi
done < in.txt

# resultat
1 line1
nothing
3 data2

haut

set (3eme exemple)


#!/bin/bash
set "11" "22a 22b"
echo "Positionnels: \$1=='$1'  \$2=='$2'"
for i in "$@"
do
echo "${i}"
done

# resultat
Positionnels: $1=='11'  $2=='22a 22b'
11
22a 22b

haut

eval


#!/bin/bash
string="Quelle est la date d'aujourd'hui?"
set $string
echo $#       # 6
echo $4       # date
eval $4       # affiche la date du jour

haut

split


# in.txt
1 a
2 b

#!/bin/bash
awk '{split ($0, col, " "); print col[2]}' in.txt

# resultat
a
b

haut

n=split


#in.txt
1 a
2 b

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

#resultat
1
a
2
b

haut

'csplit' coupe a un pattern et cree des fichiers



# csplit.txt :
% verb1
data1
data2
% verb2
data3
data4

# 'csplit' va creer autant de fichiers que de patterns %
# compter auparavant le nombre de patterns %
# et indiquer dans {1} ce nombre retranche de 1 (ici: 2-1=1)

#!/bin/bash
csplit -z -f file csplit.txt "/^%/" {1}

# resultat: creation de 2 fichiers : file00 et file01
# contenu de file00
% verb1
data1
data2

# contenu de file01
% verb2
data3
data4

haut

next pour sauter une ligne


#in.txt
1 a
2 pattern
3 c

#!/bin/bash
awk '$2 ~ /pattern/ {next}
{print}' in.txt

#resultat
1 a
3 c

haut

'case' pour tester de nombreuses conditions


echo "entrer un nombre entre 0 et 20"
read nb
case $nb in
[0-9]) echo "$nb est inferieur a 10"
;;
[1][1-9]) echo "$nb est entre 10 et 20"
;;
[1][0]) echo "$nb est egal a 10"
;;
[2][0]) echo "$nb est egal a 20"
;;
*) echo "$nb est superieur a 20"
;;
esac

haut

Formater une sequence


# exemple 1
seq -w 12

# exemple 2
#!/bin/bash
for z in `seq 1 12`
do
i=$(($i+1))
echo $(printf "%02d" $i)
done

# exemple 3
seq 12 | awk '{
f[$1] = (length($1)==1 ? "0"$1 : $1)}
END { for (i in f) {print f[i]}}' | sort -n

# resultat
01 02 ...12

haut

FOR


#!/bin/bash
limit=10
for ((a=1; a <= limit; a++))
do
echo "$a"
done
------------------------------------
for a in `seq 10`
do
echo "$a"
done
------------------------------------
for a in {1..10}
do
echo "$a"
done

haut

FOR et IFS


# in.txt
line1 data string
line2
line3 data

#!/bin/bash
OLD_IFS=$IFS
IFS=$'\n'
c=0
for line in `cat in.txt`
do
((c+=1))
numfields=`echo $line | awk '{print NF}'`
echo "$c) $line ($numfields)"
done
IFS=$OLD_IFS

haut

index : capture d'une 1ere occurrence d'un pattern


# in.txt
123 ping
12345 data 123
data 456

#!/bin/bash
var1=`cat in.txt`
var2="data"
awk -v a="$var1" -v b="$var2" 'BEGIN{f=index(a,b) ; print substr(a,f,8)}'

# resultat
data 123

haut

match : capture a un pattern avec choix sur la longueur avant ou apres


# in.txt
100 @ un set @ data2
100 @ deux
100 1003 @ trois

#!/bin/bash
awk 'match( $0, "@" ) {print substr( $0, RSTART+2, RLENGTH+5)}' in.txt

# resultat
un set
deux
trois

haut

pos : se positionner dans un fichier


# in.txt (fichier en argument)
data1
data2
data3
data4

#!/bin/bash
[ -z $1 ] && echo "one file please" && exit $NOARG || FILE=$1
lines=`awk 'END {print NR}' $FILE`
mid=$((lines / 2))
awk -v pos="$mid" '{
if ( NR <= pos )
print}' $FILE
echo "---------"
awk -v pos="$mid" '{
if ( NR > pos )
print}' $FILE

#resultat
data1
data2
----------
data3
data4

haut

renommer des extensions .TXT en .txt


#!/bin/bash
SUFF=TXT
suff=txt
for i in $(ls *.$SUFF)
do
mv -f $i ${i%.$SUFF}.$suff
done

haut

renommer des prefixes


#exemple
fichier1-old.txt
fichier2-old.txt

#!/bin/bash
find . -name "fichier*-old.txt" |
while read i
do
mv -v "$i" `echo "$i" | sed "s/old/new/g"`
done

# resultat
fichier1-new.txt
fichier2-new.txt

haut

renommer une selection de noms de fichiers (noms avec espaces)


#!/bin/bash

# DIR
# file with space.txt

DIR="/home/test"
##############

find $DIR -type f | while read file
do
   if [[ "$file" = *[[:space:]]* ]]
   then
   mv "$file" `echo $file | tr ' ' '_'`
   fi
done 

# resultat
# file_with_space.txt

haut

renommer en s'aidant d'un separateur


# liste-a.txt
accept
access
accommodate

######  parametres

LETTRE=a
LISTE=liste-a.txt

##########  fin des parametres

#!/bin/bash
while read verb
do
  source="wget "http://oxforddictionaries.com/definition/$verb?q=$verb""
eval $source
   sleep 1

# renommer accept?q=accept en : accept.txt
   for i in $LETTRE*?*
   do
   seq=`echo $i|cut -d '?' -f1`
   mv "$i" "7$seq.txt"
   done
done < $LISTE

# resultat
7accept.txt
7access.txt
7accommodate.txt

haut

renommer une serie de 15 fichiers


#!/bin/bash
# etape 1 : creation de 15 fichiers
cd /chemin_du_dossier_vide
for numero in `seq 1 15`
do
touch old"$numero"     
done
sleep 30      # pause pour verifier la creation de : old1 ...old15

# etape 2 : renommer les 15 fichiers
for fichier in `ls old*`
do
i=$(($i+1))
mv "$fichier" $(printf "new_%03d.txt" $i)
done

#resultat:
new_001.txt
....
new_015.txt

haut

Mise en evidence de la difference de numerotation


# file1.txt
data1
data2
data3

# file2.txt
data4
data5
data6

awk '{print NR,$0}' file*.txt

# resultat
1 data1
2 data2
3 data3
4 data4
5 data5
6 data6

awk '{print FNR,$0}' file*.txt

# resultat
1 data1
2 data2
3 data3
1 data4
2 data5
3 data6

haut

FNR==NR : precision des captures de patterns


# in.txt
t 6 data1
m 5 data2
d 4 data3 3
s 6 data4

awk 'FNR==NR && a[$2]=/6/ || a[$4]=/3/ {b[$0] ; next} $0 in b' in.txt in.txt

# resultat
t 6 data1
d 4 data3 3
s 6 data4

haut

FNR==NR : ecrire les lignes d'un fichier (in1.txt) qui ne sont pas dans un autre fichier (in2.txt)


# in1.txt
# t 6 data1
# m 5 data2
# d 4 data3 3
# s 6 data4

# in2.txt
# t 6 data1
# s 6 data4

# lignes de in1.txt pas dans in2.txt (in2.txt est plus petit que in1.txt)
awk 'NR == FNR {b[$0] ; next} !($0 in b)' in2.txt in1.txt

# resultat
# m 5 data2
# d 4 data3 3

haut

Utiliser une fonction pour renommer des fichiers


z-a1.txt
z-a2.txt
z-a3.txt

#!/bin/bash
rename()
{ echo $@ | cut -d '-' -f2 }
for i in z*.txt
do
mv "$i" "`rename $i`"
done

# resultat
a1.txt
a2.txt
a3.txt

haut

find avec xargs


#!/bin/bash
find /chemin_du_directory -type f | xargs grep "pattern"

haut

chercher un pattern avec "if" dans une boucle for


# in.txt
line1
line2 pattern
line3
pattern

#!/bin/bash
awk 'END { if (!f++) print "pattern not found" }
{ for(i=1; i<=NF; i++)
{ if($i ~ /pattern/)
{ print (f++)+1 ": line number "NR" | column number " i }}
}' in.txt

# resultat
1: line number 2 | column number 2
2: line number 4 | column number 1

haut

Rechercher tous les emplacements d'un mot dans un fichier


# in.txt
line1 unix data1
line2 data2 unix
unix data3

#!/bin/bash
awk '{for( i=1;i<=NF; i++)
{if( $i ~ /unix/)
{print $i " found line nb : " NR , " column : " i}}
}' in.txt

# resultat
unix found line nb : 1 column : 2
unix found line nb : 2 column : 3
unix found line nb : 3 column : 1

haut

Rechercher le mot le plus long dans un fichier


# in.txt
quel est le mot
le plus long 
dans ce texte ?

#!/bin/bash
awk '{ for ( i=1; i<=NF; i++ )
if ( length($i) > L ) 
{ L=length($i) ; s=$i } }
END { print L " : " s }' in.txt

# resultat
5 : texte

haut

Couper des lignes a une position precise (avec FOLD UNTIL WHILE IF-ELIF-ELSE


#!/bin/bash

# couper des lignes a un caractere precis avec: fold - until - while - if-elif-else

##########   parametres   ###########
# 1/4 : fournir 1 fichier ayant obligatoirement ce nom : z-depart-1pass.led    (contenant le data a couper)
#              attention de creer ce fichier de depart contenant le data a decouper  (avec F a la fin des lignes)             

pos=44               # 2/4 changer ici la position du caractere de coupe
NBRETOURVIRG=20      # 3/4 changer ici le nombre de recul en arriere pour chercher la virgule et couper  (par defaut=20)
NBPASSAGE=15         # 4/4 changer ici le nombre de boucle pour ne plus avoir de lignes > $pos caracteres  (par defaut=15)

# les 3 fichiers suivants sont crees automatiquement :
DEPART=zfichieralire.txt    #  fichier contenant les noms des fichiers a lire de la partie 1
#      ^^^^^^^^^^^^^^^^^   cree automatiquement  (don't bother with it)  (ne pas changer le nom)
DEPART2=zfichieralire2.txt  #  fichier contenant les noms des fichiers a lire de la partie 2
#       ^^^^^^^^^^^^^^^^^^   cree automatiquement  (don't bother with it)  (ne pas changer le nom)
ARRIVEE=z-result-pos"$pos".txt  #  fichier du resultat final
 
###########    fin des parametres    ###########

# le contenu des 2 fichiers suivants est cree automatiquement
### contenu de: zfichieralire.txt             ### contenu de: zfichieralire2.txt 
#  z-depart-1pass.led                       z-depart-1pass2.led
#  z-depart-2pass.led                       z-depart-2pass2.led
#  z-depart-3pass.led                       z-depart-3pass2.led
#  z-depart-4pass.led                       z-depart-4pass2.led
#  z-depart-5pass.led                       z-depart-5pass2.led
#  z-depart-6pass.led                       z-depart-6pass2.led
#  z-depart-7pass.led                       z-depart-7pass2.led 
#  z-depart-8pass.led                       z-depart-8pass2.led
#  z-depart-9pass.led                       z-depart-9pass2.led
#  z-depart-10pass.led                      z-depart-10pass2.led
#  z-depart-11pass.led                      z-depart-11pass2.led
#  z-depart-12pass.led                      z-depart-12pass2.led
#  z-depart-13pass.led                      z-depart-13pass2.led
#  z-depart-14pass.led                      z-depart-14pass2.led
#  z-depart-15pass.led                      z-depart-15pass2.led

### exemple de fichier de depart : z-depart-1pass.led
# (101),(100,1001,1002,1003,1004,1005,1006,1007,1008,1009,1,10,1011,10,12,1023-1015,1016,2003,2004,2005,2006,2007,2008,2009,2010,2011,2012,2023-2015,2016,3023-3035,3011,3012,3023-3015,3016)F
# (102),(1004,1005,1006,1007,1008,1009,1010,1011,1012,11011-11013,1013,1014,1015-1017,1019)F
# (103),(198,1099,1001,1002,1003,1004,1005,1006,1007,1008,1009)F
# (104),(362,385,746,855,1623,1703,266,292,314,434,512,817-819,1430-1431)F
# (105),(362,385,746,855,1623,1703,266,292,314,434,512,817-819,1430-1431)F
# (106),(100,1001,1002,1003,1004,1005,1006,1007,1008,1009)F
# (107),(100,101,102,1003,1004,1005,1006,1007,1008,1009)F
# (108),(100,1001,1002,1003,1004,1005,1006,1007)F
# (109),(1006,1007,1008,1009,1010,1011,11012,11013,11014,11015,1016,11017,1018-1019,1020)F

##################"
# deleter les actions precedentes
rm zlog*.txt   # delete les fichiers logs
rm zhabill*.txt   # delete les fichiers habillages (E a I)

# attention ne pas deleter le fichier depart : z-depart-1pass.led
rm z-depart-2pass.led  
rm z-depart-3pass.led
rm z-depart-4pass.led
rm z-depart-5pass.led
rm z-depart-6pass.led
rm z-depart-7pass.led
rm z-depart-8pass.led
rm z-depart-9pass.led
rm z-depart-10pass.led

rm z-depart-*pass2.led
rm z-depart-*pass3.led
rm zpos-*blanc.txt

#creation automatique des fichiers necessaires a la bonne marche du script
for i in `seq 1 15`
do
echo "z-depart-"$i"pass.led" 
done > zfichieralire.txt

for i in `seq 1 15`
do
echo "z-depart-"$i"pass2.led" 
done > zfichieralire2.txt

##################  PARTIE 1  ################
# script :

j=1      # j=1 par defaut
until [ "$j" -gt "$NBPASSAGE" ]    # sert a lire les lignes de $DEPART
do

variable=`awk 'NR=='$j' {print}' $DEPART`    # lit 1pass.led ; 2pass.led .....

 N=0      # important: N=0
 while read line    # contenu des fichiers ou la coupe est a faire
 do

     N=$((N+1))   # sert pour les numeros de lignes
     var=`echo $line | awk '{print substr($0,'$pos',1)}'` 

     i=1
     until [ $i -gt "$NBRETOURVIRG" ]    # nb de retours arrieres pour chercher le caractere "virgule" 
     do
         
          if [[ "$var" == "," ]]
          then
          echo $line | sed 's/^.\{'$pos'\}/& /1' | sed 's/, / /1'
          echo $line | sed 's/^.\{'$pos'\}/& /1' | sed 's/, / /1' >> z-depart-"$j"pass2.led 
          echo "line $N = be careful - virgule a la position $pos ; pas de recul necessaire" >> zlog"$j".txt
                        # laisser >> pour y deposer toutes les lignes
          break  # important

             elif [[ "$var" = [0-9A-Z] ]] || [[ "$var" == "-" ]] || [[ "$var" == ")" ]] || [[ "$var" == "." ]]
                            # si 1er caractere = chiffre ou lettre maj ou signe
             then     
             pos$i=`expr $pos - $i`   
             symb=$(echo $line | awk '{print substr($0,'`expr $pos - $i`',1)}')
             echo "line $N (lignes lues  $j  fois) : be careful - fait apres $i eme boucle arriere (pos `expr $pos - $i`/$pos) :" $symb
             echo "line $N ( passage $j )  : be careful - fait apres $i eme boucle arriere (pos `expr $pos - $i`/$pos) :" $symb >> zlog"$j".txt 

                if [[ "$symb" == "," ]]    # test du nouveau symbole (a la position -1)
                then
                echo $line | sed 's/^.\{'`expr $pos - $i`'\}/& /1' | sed 's/, / /1'
                echo $line | sed 's/^.\{'`expr $pos - $i`'\}/& /1' | sed 's/, / /1' >> z-depart-"$j"pass2.led

                echo "line $N = coupe avec recul de position" >> zlog"$j".txt    # controle des lignes
                break   # important : passe a la ligne suivante si tombe sur ","  (sans continuer apres la ",")
                fi       

             elif [[ `expr length "$line"` < "$pos" ]]
             then
             echo "line $N a `expr length "$line"` caracteres (inf a $pos)"
             echo "line $N a `expr length "$line"` caracteres (inf a $pos)" >> zlog"$j".txt
             echo "line $N = ligne inferieure a  $pos caracteres" >> zlog"$j".txt
             echo $line >> z-depart-"$j"pass2.led 
             break

          else break  # commande au cas ou  "if" et tous les "elif" sont faux 
          fi
 
   #  sleep 1   
     let i=i+1   # (boucle until sur le nombre de retour arriere de la virgule)
     done      

done <  $variable     # lit les fichiers: z-depart-1pass.led ; z-depart-2pass.led .....

##################  PARTIE 2  ################
# coupe au blanc (= espace)

   variable2=`awk 'NR=='$j' {print}' $DEPART2`    # lit les fichiers: z-depart-1pass2.led ; z-depart-2pass2.led .....

     while read line    # contenu des fichiers ou la coupe est a faire
     do
     echo `expr index "$line" " "` >> zpos-"$j"blanc.txt
      blanc=$(echo `expr index "$line" " "`)     # echo $blanc

# condition de coupe a l'espace 
     blancexiste=`echo $line | awk '$0 ~ / / {print}'`

     if [[ $blancexiste != "" ]] ; then echo $line | fold -s --width=`expr $blanc + 2` ; fi
     if [[ $blancexiste = "" ]] ; then echo $line  ; fi

     done < $variable2  >> z-depart-"$j"pass3.led   

##################  PARTIE 3  ###############
# habillage
# but : mettre bout a bout les lignes qui demandent a etre coupees
 
awk '{
if(( $0 ~ /^[(]/) || ($0 ~ /FF$/) || ($0 ~ /F$/)) {print $0}
else
{print $0":"}
}' z-depart-"$j"pass3.led  > zhabillE"$j".txt

# joindre la ligne suivant ":" avec la precedente
sed -e :a -e '/:$/N ; s_\n__ ; ta' zhabillE"$j".txt | sed 's/://g' > zhabillF"$j".txt 

# habillage et ajouter les sequences aux lignes qui n'en ont pas
# et deleter les lignes vides
sed 's/,(/ /1' zhabillF"$j".txt > zhabillG"$j".txt
sed 's/[(]/@/1' zhabillG"$j".txt | grep '.' > zhabillH"$j".txt

awk -F " " '
$0 ~ /^@/  {e=$1} {print}
$0 !~ /^@/ {print e,$0}
' zhabillH"$j".txt | grep "@" | sed 's/@/(/1' | sed 's/) /),(/1' > zhabillI"$j".txt

awk '{ if ( length($0) >= '`expr $pos + 1`' ) 
{print "#########  attention necessite un '`expr $j + 1`'eme passage  #########"}
else
{print "#####   ok termine - a necessite '$j' boucles sur un total parametre a : '$NBPASSAGE'  ###"}
}' zhabillI"$j".txt >> zlog"$j".txt

# copie du resultat final
# cp zhabillI"$j".txt z-depart-`expr $j + 1`pass.led    # sortie d'un passage = entree du passage suivant
cp zhabillI"$j".txt z-depart-`expr $j + 1`pass.led

echo "#########   fin du " $j "eme passage (sur un total de $NBPASSAGE)   #########"

#####################
# test pour arreter le script selon l'existence d'1 pattern

VAR=`[ -z "$(grep "be careful" zlog"$j".txt)" ] && echo "termine" || echo "d'autres boucles sont necessaires"`
if [ "$VAR" == "d'autres boucles sont necessaires" ] ; then
echo "#########  d'autres boucles sont necessaires  ##########"
else 
echo "################   termine  (fin de la coupe au caractere $pos)   #################"
break
fi

sleep 2
let j=j+1
done    2>/dev/null     # boucle until sur le nombre de passages

#####################
# habillage final (avec: ,F1.0)

dernpassage=`ls z-depart-*pass.led | tail -n1`
cp $dernpassage z-depart-result.txt

while read line
do
#definir les 2 derniers caracteres comme pattern
a=`expr "$line" : '.*\(..\)'`
#condition sur le pattern
if [[ $a != ")F" ]] ; then
echo $line")F"
else
echo "$line"
fi
done < z-depart-result.txt > z-depart-result2.txt

awk '{print "                               "$0}' z-depart-result2.txt | sed 's/F/,F1.0/g' > $ARRIVEE


# resultat
#                              (101),(100,1001,1002,1003,1004,1005,1006),F1.0
#                              (101),(1007,1008,1009,1,10,1011,10,12),F1.0
#                              (101),(1023-1015,1016,2003,2004,2005,2006),F1.0
#                              (101),(2007,2008,2009,2010,2011,2012),F1.0
#                              (101),(2023-2015,2016,3023-3035,3011,3012),F1.0
#                              (101),(3023-3015,3016),F1.0
#                              (102),(1004,1005,1006,1007,1008,1009,1010),F1.0
#                              (102),(1011,1012,11011-11013,1013,1014),F1.0
#                              (102),(1015-1017,1019),F1.0
#                              (103),(198,1099,1001,1002,1003,1004,1005),F1.0
#                              (103),(1006,1007,1008,1009),F1.0
#                              (104),(362,385,746,855,1623,1703,266,292),F1.0
#                              (104),(314,434,512,817-819,1430-1431),F1.0
#                              (105),(362,385,746,855,1623,1703,266,292),F1.0
#                              (105),(314,434,512,817-819,1430-1431),F1.0
#                              (106),(100,1001,1002,1003,1004,1005,1006),F1.0
#                              (106),(1007,1008,1009),F1.0
#                              (107),(100,101,102,1003,1004,1005,1006,1007),F1.0
#                              (107),(1008,1009),F1.0
#                              (108),(100,1001,1002,1003,1004,1005,1006),F1.0
#                              (108),(1007),F1.0
#                              (109),(1006,1007,1008,1009,1010,1011,11012),F1.0
#                              (109),(11013,11014,11015,1016,11017),F1.0
#                              (109),(1018-1019,1020),F1.0

haut

Derniere modification : JUIN 2015