Formulaire de contact

 
Un épisode sur la fonction en bash



PLAN

INTRODUCTION
MÉTHODES
APPLICATION
RÉFÉRENCES

INTRODUCTION
Après un examen rétrospectif de notre script, nous avons décidé de le reprogrammer dans l’intention de 1) clarifier les chaînes de traitement ; 2) de simplifier des codes répétitifs ; et 3) de récolter un corpus plus satisfaisant. Pour ce faire, nous avons réorganiser des structures de contrôles, créé 19 fonctions, et amélioré des « algorithmes » de formalisation et normalisation des textes.
Dans ce blog, nous nous concentrerons sur la création des fonctions. Nous commencerons par une brève présentation pour ensuite expliquer notre application. Quant à les objectifs 1) et 3) supra, nous les détaillerons dans le prochain blog.

I METHODES

Considérons une fonction comme un petit script dans un script. Au lieu d’écrire le même code encore et encore, nous pouvons le définir une fois dans une fonction puis l’appeler à chaque fois. Elle est particulièrement utile si nous avons certaines tâches qui doivent être effectuées plusieurs fois.
1.1 Syntaxe
Il existe deux formats pour créer une fonction en bash.
      

nom_fonction () {
              <commandes>
       }
       

function nom_fonction () {
              <commandes>
       }


La définition de la fonction doit apparaître dans le script avant tout appel.
1.2 Passer des arguments
A l’intérieur d’une fonction, nous pouvons accéder à des arguments à l’aide des paramètres positionnels ($1, $2, $3, … , ${10}, $(n) ).
Attention : les nombres qui sont supérieurs à 9 doivent être inclus dans une paire d’acclolade {}.
De plus, il faut considérer la portée de variables : locale ou globale. Une variable locale n’est visible qu’à l’intérieur de la fonction, tandis qu’une variable globale est visible partout dans le script.

1.3 Design

Créer des fonctions est facile. Créer de bonnes fonctions qui facilitent l’écriture et la maintenance exige cependant du temps et de l’expérience...
Quelquefois, mieux est le moins de lignes de code, parfois mieux est plus facile à modifier plus tard si les besoins changent. L’approche qui est la moins sujette aux erreurs est parfois meilleure.

II APPLICATION
Nous avons créé 19 fonctions, dont 3 concernent l’écriture des tableaux et 11 servent à générer des données ainsi que des fichiers nécessaires ; le reste nous permet de formaliser/ normaliser des fichiers et de manipuler des fichiers temporaires.

2.1 Écriture des tableaux
write_thead()

Fonction qui permet d'écrire des en-têtes (th) d'un tableau.
Pour créer n en-têtes, il faut appeler n fois la fonction et passer 2 variables pour chaque appel.
$1 : la largeur de la colonne en pourcentage (width) ;
$2 : le titre de la colonne


write_thead () {
 echo -e "\t\t\t\t<th width = \"$1\" align = \"center\">$2</th>";
}

write_cell ()

Fonction qui écrit le contenu de chaque case (cell) sur le stdOUT ; elle constitue la fonction write_line (). Une variable à passer pour chaque appel.


write_cell () {
 echo -e "\t\t\t\t<td align = \"center\">$1</td>";
}

write_line ()

Fonction qui remplit le tableau ligne par ligne en appelant la fonction write_cell(). Dans notre script, il y a 14 variables à passer pour cette fonction : chacune d’entre elles correspond à une colonne. Notre tableau en comporte 14.
Les deux variables $i et $j sont locales ; tandis que $COL_NUM est globale et constante. $j est assignée par référence indirecte.


write_line () {
 echo -e "\t\t\t<tr>";
 local i=1;
 local j;
 while [ $i -le $COL_NUM ] ; do
     eval j=\${$i}; 
     write_cell "$j"; 
     ((i++));
 done 
 echo -e "\t\t\t</tr>";
}

2.2 Récupération de données et de fichiers nécessaires
get_remote_encoding ()
Fonction qui récupère l’encodage à l’aide de curl, commande qui envoie au serveur une requête de l’en-tête.
La valeur est passée par substitution de commande.
$1 : à passer : $line : une URL


get_remote_encoding () {
 curl -sIL $1|grep -i -Po '(?<=charset=).+(?=\b)' | \
 awk '{print tolower($0)}';
}

get_page_encoding ()
Fonction qui récupère l’encodage dans le balise <meta> d’une page HTML ;
La valeur est passée par substitution de commande.
$1 : à passer : $page : une page HTML aspirée


get_page_encoding () {
 egrep -i 'meta.+charset' $1 |awk '{print tolower($0)}' | \
 egrep -o "charset[=\s\"a-Z0-9\-]*" |cut -d"=" -f2 | \
 sed  's/\s//g'|sed 's/\"//g';
}

check_encoding ()
Fonction qui vérifie si l’encodage est reconnu par la commande iconv.
La valeur est passée par substitution de commande. Si celle-ci est vide, le fichier correspondant ne peut pas être transcodé par iconv.
$1 : à passer : $encodage


check_encoding () { 
 iconv -l | egrep -io $1 | sort -u;
}

get_text ()
Fonction qui décharge la page HTML d’une URL
$1 : à passer : $encodage, l’encodage de la page
$2 : à passer : $line, une URL
Par défaut, la sortie est sur stdOUT


get_text () {
 lynx -dump -nolist -assume_charset=%{charset} -display_charset=$1 $2;
}

get_context ()
Fonction qui produit le contexte d'un motif. Les -- lignes qui délimitent des contextes ainsi que des lignes vides sont enlevés.
$1 : à passer : nombre de ligne(s) à extraire avant/après la ligne contenant le motif
$2 : à passer : le motif
$3 : à passer : un fichier texte


get_context () {
 egrep -i -C $1 "$2" $3 | sed '/^--|^$/d';
}

get_context_html ()
Fonction qui produit le contexte d’un motif à l’aide de minigrep et le déplace dans un répertoire souhaité.
$minigrep, globale : le chemin du programme minigrep
$1 : à passer : un fichier dump (formatté)
$2 : à passer : nom du fichier de motif
$3 : à passer : $minigrep_out, le fichier html généré par minigrep
$4 : à passer : la destination du déplacement du fichier $3

get_context_html () {
 perl $minigrep "UTF-8" $1 $2;
 mv $3 $4
}

get_frequency ()
Fonction qui calcule le nombre d’occurrences d’un motif dans un fichier texte.
La valeur est passée par substitution de commande.
$1 : à passer : $motif
$2 : à passer : un fichier texte formatté avec la fonction supra. Sinon, on risque de perdre certaine occurrence à cause de « line wrap ».


get_frequency () {
 egrep -io "$1" $2 | wc -l;
}

get_index ()

Fonction qui produit un index de tokens (formes) ou de types (lemmes) par ordre de fréquence décroissante.
$1 : à passer : fichier de liste de tokens ( ou de types)


get_index () {
 sort -bdfi $1 |uniq -ci | sort -gr;
}

get_2gram ()

Fonction qui crée une liste de 2gram d’un fichier de liste de tokens
$1 : à passer : fichier de liste de tokens


get_2gram () {
 temp1=$1;
 local temp2=tp2;
 tail -n +2 $temp1 > $temp2;
 paste $temp1 $temp2 | get_index;
 rm $temp2;
}

get_ttr ()

Fonction qui calcule le type/token ratio (ttr) d’un certain fichier.
La valeur est passée par substitution de commande.
$type_nb et $token_nb : variables locales
$1 : à passer : fichier de l'index de lemmes
$2 : à passer : fichier de liste de tokens (ie, le « contexte » des lemmes)


get_ttr () {
 local type_nb=`cat $1 | wc -l`;
 local token_nb=`cat $2 | wc -l`;
 echo $(( 100 * type_nb / token_nb ));
}

concatenate ()

Fonction qui concatène des fichiers dans un seul fichier. Comme les signes <, > sont enlevés dans les phases (fonctions) précédentes, on ne les traite pas ici.
$1 : à passer : nom du balise, par exemple $line_iterator
$2 : à passer : nom du fichier à concaténer


concatenate () {
    echo "<t=\"$1\">"
    cat $2;
    echo -e "\n</t>";
}
2.3 Formalisation/normalisation de textes, manipulation de fichiers temporaires
format_latin_text ()
Fonction qui 1) nettoie un fichier composé de l'alphabet latin en supprimant des « bruits », tels que des titres des rubriques, des listes des articles récents, des noms des images, etc, qui sont en général marqués par des caractères spéciaux ; 2) et le formatte de manière « syntaxique », c'est-à-dire que l’on touche le « line wrap » et met chaque phrase par ligne.
$1 : à passer : un ficher texte, dans notre script, un fichier dump utf-8 de l’anglais ou du français.


format_latin_text () {
 sed -r "/[\*\+▪] |\*$|\#|\[.*\]|[=&]|IFRAME|__|©|(c|C)opyright|\
 \( \)|(BUTTON)|http|www|  \b[0-9]+\.|\.jpe?g|png|JPE?G|PNG|\
 <.*[^>]>|[<>]|[a-Z0-9+=%]{30}|^$/d" $1 | tr '\n' ' '| \
 tr -s ' ' | sed 's/[.?!]/&\n/g'; 
}

format_chinese_text ()
Fonction similaire, mais ne traite que des textes chinois (sans délimiteur). Elle permet de 1) nettoyer et 2) formatter un texte, 3) et de le segmenter avec le tokenizer scws (cf le blog précédent).
$1 : à passer : un ficher texte chinois encodé en utf-8
$dictionnaire_scws, globale : le chemin du dictionnaire du tokenizer


format_chinese_text () {
 sed -r "/[\*\+] |\[.*\]|[=&¿]|IFRAME|__|©|(c|C)opyright|\( \)|\
 BUTTON|\||http|www|  \b[0-9]+\.|\.jpe?g|png|JPE?G|PNG|<.*[^>]>|\
 [<>]|^$/d" $1 | tr -d '\n' | \
 tr -d ' ' |sed "s/[。?!]/&\n/g" | \
 scws -c utf8 -d $dictionnaire_scws;
}

token_to_line ()
Fonction qui sépare des tokens par ligne. Quelque fois, \w produit des bruits, on énumère donc bêtement des signes de ponctuations. On garde des tokens de genre mots polylexicaux composés par des traits d'union, tels que « chassé-croisé » ;
$1 : à passer : fichier (con)texte formatté, selon des objectifs.


token_to_line () {
 sed -r "s/[,.«»()\?\!…:;\"\‘\’*#。?!,、…+=%&:;【】\
 · —“”–《》()<>_■€\$\¥£•@②]|--| - / /g" $1 | \
 tr '\n' ' ' | tr ' ' '\n'| tr -s '\n'| sed "/^$/d" ;
}

lemmatize ()
Fonction qui lemmatize une liste de tokens avec tree-tagger. Les nombres, marqués par NUM en français et CD en anglais, sont enlevés.
$1 : à passer : fichier de liste de tokens à traiter
$2 : à passer : fichier paramètre du tree-tagger


lemmatize () {
 sed -r "s/[’\']/\n/g" $1| tree-tagger $2 -lemma -no-unknown | \
 sed -r "/NUM.+|CD.+/d" |sed "/^$/d" | cut -f2 ;
}

remove_stopwords ()
Fonction qui enlève des mots vides (stopwords) à partir d'un antidictionnaire
-F interprète MOTIF comme une liste de chaînes fixées et séparées par ligne
-f lit MOTIF depuis un fichier
-v sélectionne des « non-matching » lignes
-x sélectionne ceux qui « match » exactement la ligne
$1 : à passer : fichier d’antidictionnaire (un token par ligne)
$2 : à passer : fichier de liste de tokens à nettoyer (un token par ligne)


remove_stopwords () {
    grep -Fvxf $1 $2;
}


REFERENCES

Total comment

Auteurs

AI_PLURITAL