Sed and awk

De Octet.ca

Cet article présente les lignes de commande de sed qui sont pratiques. Voir aussi Awk and Sed One-Liners Explained.

Sommaire

[modifier] Classes pour sed

Citation1.png
GNU sed supports "character classes" in addition to regular character sets, such as [0-9A-F]. Like regular character sets, character classes represent any single character within a set.
Citation2.png
Source.
    [[:alnum:]]  - [A-Za-z0-9]     Alphanumeric characters
    [[:alpha:]]  - [A-Za-z]        Alphabetic characters
    [[:blank:]]  - [ \x09]         Space or tab characters only
    [[:cntrl:]]  - [\x00-\x19\x7F] Control characters
    [[:digit:]]  - [0-9]           Numeric characters
    [[:graph:]]  - [!-~]           Printable and visible characters
    [[:lower:]]  - [a-z]           Lower-case alphabetic characters
    [[:print:]]  - [ -~]           Printable (non-Control) characters
    [[:punct:]]  - [!-/:-@[-`{-~]  Punctuation characters
    [[:space:]]  - [ \t\v\f]       All whitespace chars
    [[:upper:]]  - [A-Z]           Upper-case alphabetic characters
    [[:xdigit:]] - [0-9a-fA-F]     Hexadecimal digit characters

[modifier] Lignes

[modifier] Mettre chaque colonne sur une ligne

Pour des éléments séparés par une virgule:

datamash transpose -t, < fichier

[modifier] Remplacer un ligne vide

Si le nombre d'espaces à remplacer est "___":

sed 's/^   $/remplacement/' fichier.txt

[modifier] Isoler les éléments séparés par une virgule sur une ligne

cat "element1,element2,element3" |  tr ',' '\n'

[modifier] Extraire adresses courriel

perl -wne'while(/[\w\.]+@[\w\.]+/g){print "$&\n"}' fichier.txt

[modifier] Extraire URL

lynx -dump -listonly my.html

[modifier] Imprimer une ligne

Pour imprimer la 30e ligne d'un fichier:

sed -n 30p fichier.txt

Une autre façon d'imprimer la 30e ligne du fichier asdf.txt, mais beaucoup plus rapide sur les gros fichiers:

sed '30q;d' fichier.txt

[modifier] Imprimer des lignes

Pour imprimer de la 10e à la 40e ligne d'un fichier:

sed -n '10,40p' fichier.txt

Note: ne pas oublier l'option -n

Pour imprimer de la 10e à la fin du fichier:

 sed -n '10,$p' fichier.txt


[modifier] Ajouter une ligne dans un fichier

Comment ajouter une ligne à un endroit particulier dans un fichier.

awk '{print}/caracteres_de_la_ligne_ou_on_veut_ecrire_apres/{if(didit!=1) \
{ print "ligne1_a_ajouter\nligne2_a_ajouter"; didit=1;}}' input.txt > output.txt 

[modifier] Effacer une ligne dans un fichier

sed "/caracteres_de_la_ligne_a_effacer/d" input.txt

[modifier] Effacer plusieurs lignes dans un fichier

Enlever l'interval entre les lignes 7 et 9:

sed '7,9d' filename.txt

[modifier] Effacer les lignes vides dans un fichier

sed '/^\s*$/d' FICHIER

[modifier] Compter le nombre de nombres dans un texte

Ma solution implémente l'idée suivante : les nombres sont séparés par deux caractères consécutifs ou davantage qui ne se trouvant pas dans l'ensemble [0-9]. On remplace donc tous ces caractères par des newline :

sed -r 's/[^0-9]{2,}/\n/g' FICHIER

Une fois ceci passé, il ne reste que des chiffres, des newline et des séparateurs inter-chiffres (espace, virgule, tiret). Comme le tiret sépare deux nombres (par exemple 2009-2010), on replace le tiret lui aussi par un newline :

sed -r 's/([^0-9]{2,}|-)/\n/g' FICHIER

Les nombres se trouvant tous maintenant sur leur propre ligne, il ne reste plus qu'a retirer les newline :

sed -r 's/([^0-9]{2,}|-)/\n/g' FICHIER  | sed '/^$/d'

Et on peut par la suite compter le total de lignes :

sed -r 's/([^0-9]{2,}|-)/\n/g' FICHIER  | sed '/^$/d' | wc -l

[modifier] Imprimer chaque champ sur une ligne séparée

Si les colonnes sont séparées par des espaces:

cat file | awk '{print $0}' RS=' '

Si c'est un autre caractère qui sépare les colonnes, utiliser celui-ci au lieu de l'espace dans l'argument entre guillemets de RS. Source.

[modifier] Caractères

[modifier] Mettre à jour un URL

sed supports any character as separator, so if the pattern you are trying to replace contains /, use a different separator. Most commonly used are # and |

sed  's|http://old.url/|http://new.url/|g' input

[modifier] Remplacer la dernière occurence d'un caractère

Remplacer du tiret par un espace: (Source):

echo "swp-RedHat-Linux-OS-5.5.0.0-03" | sed 's/\(.*\)-/\1 /'

[modifier] Ajouter un caractère à la fin de chaque ligne

sed 's/$/CHARACTERE/' filename

[modifier] Ajouter un caractère au début de chaque ligne

sed 's/^/CHARACTERE/' filename

[modifier] Extraire du texte entre 2 mots dans un fichier texte

sed -n '/MOT1/,/MOT2/p' fichier.txt

Provient de Sed Find and Display Text Between Two Strings or Words.

[modifier] Pour enlever le dernier caractère d'une chaîne

echo "1234+" | sed '$s/.$//'

[modifier] Pour remplacer un caractère par un saut de ligne

tr est votre ami:

tr "caractere_a_remplacer" "\n" < fichier.txt

Voir aussi la man page de tr pour les autres caractères spéciaux.

[modifier] Pour enlever les ^M (ctrl-M) à la fin des lignes

Pour retirer les sauts de lignes de Windows dans un fichier UNIX:

tr -d '\r' <old.file >new.file

[modifier] Pour retirer le saut de ligne

echo "ligne_avec_linefeed" | tr -d "\n"

[modifier] Pour changer le saut de ligne pour un caractère

echo "ligne_avec_linefeed" | tr "\n" "caractère"

[modifier] Effacer les caractères vides au début des lignes

sed -e 's/^[ \t]*//' fichier.txt

[modifier] Pour enlever les espaces vides et les tabs à la fin des lignes

sed 's/[ \t]*$//' fichier.txt

[modifier] Convertir les lettres majuscules en minuscules

 tr '[:upper:]' '[:lower:]' < input.txt > output.txt

[modifier] Imprimer la dernière colonne

 awk '{print $NF}' fichier.txt

[modifier] Imprimer la 3e colonne jusqu'à la fin de la ligne

awk '{ print substr($0, index($0,$3)) }'

[modifier] Imprimer un guillemet simple

awk '{print "\x27" $2 "\x27"}'


[modifier] Avoir un minimum de N chiffres pour représenter un nombre

Si on veut avoir un nombre de chiffres déterminer pour afficher un nombre (dans cet exemple, les nombres de la cinquième colonne ont 3 chiffres):

awk '{$5 = sprintf("%03d", $5); print}' fichier.txt

Source

[modifier] Extraire la liste des caractères d'un fichier texte

Liste des charactères:

cat fichier.txt | od -cvAnone -w1 

Liste des charactères uniques:

cat fichier.txt | od -cvAnone -w1 | sort -bu

[modifier] Référence

On peut faire référence aux occurences qui ont fonctionné en mettant les chaînes identifiées entre parenthèses, et en y faisant référence par la suite avec \1\2:

echo "James Bond" | sed -E 's/(.*) (.*)/The name is \2, \1 \2./'

[modifier] Opérations logiques

[modifier] Plus grand/petit que

Calculer le nombre de fois qu'un nombre est inférieur à -30 dans un fichier texte qui ne contient qu'un nombre par ligne:

awk '$1 < -30.0 {s+=1}; END{print s}' fichier.txt

Pour que le compte soit de zéro lorsqu'il n'y a pas d'occurence:

awk 'BEGIN{s=0};$1 < -30.0 {s+=1}; END{print s}' fichier.txt

[modifier] Égalité

Si la septième colonne soit égale à 1, imprimer la ligne complète

awk '$7 == 1 {print ;}' fichier.txt

[modifier] Utilisation de variable dans awk

Il faut utiliser les guillemets français et anglais de cette façon:

"'"$variable"'"

Par exemple, une comparaison devrait avoir la forme suivante:

awk '$7 == "'"$variable"'" {print ;}' fichier.txt

Commentaire de Gérard: une méthode un peu plus simple pour éviter la coordination des apostrophes et guillemets consiste à définir la variable en argument. Exemple:

awk '$7 == VAR {print }' VAR=$variable fichier.txt
Outils personnels