Sed and awk

De Octet.ca
(Redirigé depuis Sed)

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

Sommaire

Classes pour sed[modifier]

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

Variables dans awk[modifier]

Quand c'est avec un pipe, il faut définir les variables à la fin:

for i in `seq 2 31`;do 
   echo $jour | awk -F ";" '{print $k}' k="$i"; 
done

Lignes[modifier]

Mettre chaque colonne sur une ligne[modifier]

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

datamash transpose -t, < fichier

Remplacer un ligne vide[modifier]

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

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

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

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

Extraire adresses courriel[modifier]

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

Extraire URL[modifier]

lynx -dump -listonly my.html

Imprimer une ligne[modifier]

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

Imprimer des lignes[modifier]

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 la 10e et la 40e ligne d'un fichier:

 sed -n -e 10p -e 40p fichier.txt

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

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

Ajouter une ligne dans un fichier[modifier]

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 

Effacer une ligne dans un fichier[modifier]

sed "/caracteres_de_la_ligne_a_effacer/d" input.txt

Effacer plusieurs lignes dans un fichier[modifier]

Enlever l'interval entre les lignes 7 et 9:

sed '7,9d' filename.txt

Effacer les lignes vides dans un fichier[modifier]

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

Compter le nombre de nombres dans un texte[modifier]

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

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

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.

Colonnes[modifier]

Choisir N colonnes d'un fichier[modifier]

awk -v b=2 -v e=7 'BEGIN{FS=OFS=","} {for (i=b;i<=e;i++) printf "%s%s", $i, (i<e ? OFS : ORS)}' file

b=beginning field number, e=end field number.

Caractères[modifier]

Mettre à jour un URL[modifier]

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

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

Remplacer du tiret par un espace: (Source):

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

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

sed 's/$/CHARACTERE/' filename

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

sed 's/^/CHARACTERE/' filename

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

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

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

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

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

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

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.

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

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

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

Pour retirer le saut de ligne[modifier]

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

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

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

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

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

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

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

Convertir les lettres majuscules en minuscules[modifier]

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

Imprimer la dernière colonne[modifier]

 awk '{print $NF}' fichier.txt

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

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

Imprimer un guillemet simple[modifier]

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


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

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

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

Liste des charactères:

cat fichier.txt | od -cvAnone -w1 

Liste des charactères uniques:

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

Référence[modifier]

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./'

Opérations logiques[modifier]

Plus grand/petit que[modifier]

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

Égalité[modifier]

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

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

Utilisation de variable dans awk[modifier]

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