Sed - Introduction à SED - Part III
baissaoui
Messages postés
498
Date d'inscription
jeudi 2 septembre 2021
Statut
Webmaster
Dernière intervention
21 août 2024
-
21 juin 2022 à 14:25
Document initial créé par Jipicy
Partie I
Partie II
2ème occurrence :
3ème occurrence :
Toutes les occurrences :
En n'affichant que la ligne concernée sur la sortie standard :
Le même avec des lettres :
Indentation du script avec "sedsed" et explications sommaires :
Il va de soit que ces 2 exemples ne sont là que pour une simple démonstration et ne sont pas du tout optimisés ni adaptés en ce qui concerne les substitutions, qui auraient pu (du) être faites en ciblant directement la ligne concernée.
Sur une ligne :
Sur une seule ligne :
Sur une seule ligne :
Sur une seule ligne :
Sur une seule ligne :
Commande "x"
Sur une seule ligne :
Sur une seule ligne :
Regrouper sur une seule et même ligne, la ligne contenant "motif" et les lignes suivantes ne comportant pas ce motif.
Sur une seule ligne :
Le fichier de référence : plop
La commande :
Le thread en rapport dans le forum
Sur une seule ligne :
Sur une seule ligne :
Sur une seule ligne :
Centrer du texte sur 20 colonnes en ajoutant un espace avant et après
# Sur une seule ligne :
#
On serait tenté d'utiliser un simple :
Mais le problème c'est que cette syntaxe rajoute aussi un ":" en fin de ligne :
La solution consiste donc à faire une boucle en utilisant la syntaxe des expressions régulières et notamment les limites de caractère ou de mot (word boundary) :
Éliminer un intervale de lignes dont le début est représenté par un motif (C) et la fin étant le 3ème "Y".
Sur une seule ligne :
Pour la portabilité utiliser plutôt :
Sur une seule ligne :
# Voir aussi cette discussion dans le forum :
http://www.commentcamarche.net/forum/affich 4856842 sed substitution
Sur une seule ligne :
Comment décommenter un jeu d'instructions qui commence par une ligne commentée (contenant un mot-clé) suivie par les directives commentées elles aussi.
Sur une seule ligne :
à partir de la 6ème virgule, supprimer chaque guillemet encadrant chaque champ, exepté le dernier
Le texte de référence :
Sur une seule ligne :
Sur une seule ligne :
2 méthodes là encore, une avec boucle et une utilisant les mémoires tampons.
Fichier de référence :
Sur une seule ligne :
Sur une seule ligne :
Post en référence
SED - The Stream EDitor - Part III
Ce document est une introduction à la pratique et à l'utilisation de l'éditeur de flux "SED", qui essaie de couvrir certaines fonctionnalités assez méconnues, pour ne pas dire "quasi inconnues", qui font de "SED" un outil indispensable dans la boîte à outils de tout Linuxien désireux de se rompre aux maniements et aux arcanes du traitement de fichiers via une console et un shell.Sommaire part III
- Les exemples
- Substitutions
- Afficher un intervalle entre 2 motifs sans les motifs
- Gourmandise des expressions régulières
- La commande "n"
- Inverser 2 lignes
- Effacement d'une ligne et insertion plus loin
- Dissocier les commentaires des commandes
- Affichage conditionné
- Émulation de grep
- Étiquettes, boucles et mémoires tampons
- Supprimer deux lignes précédents un motif donné
- Effacer les n dernières lignes
- Émulation de "tac" (inverser les lignes d'un fichier)
- Exemple de branchement inconditionnel
- Exemple de branchement conditionnel (t)
- Autre exemple de branchement conditionnel
- Exemple de branchement conditionnel (T)
- Substitution avec tampons
- Décommenter les directives d'un fichier
- Conversion de caractères
- Mise en forme de texte 1
- Mise en forme de texte 2
- La commande "c"
- Les fichiers de références pour les exemples
- Discussions en rapport sur le forum
Partie I
Partie II
Les exemples
Substitutions
nième occurence
1ère occurrence :$ echo "azerty azerty azerty" | sed 's/az/qw/'
qwerty azerty azerty
2ème occurrence :
$ echo "azerty azerty azerty" | sed 's/az/qw/2'
azerty qwerty azerty
3ème occurrence :
$ echo "azerty azerty azerty" | sed 's/az/qw/3'
azerty azerty qwerty
Toutes les occurrences :
$ echo "azerty azerty azerty" | sed 's/az/qw/g'
qwerty qwerty qwerty
Substituer les fins de lignes par un espace
sed 'Sur une ligne :
:s # étiquette
N # on ajoute la ligne suivante
s/\n/ / # on substitue les fins de lignes par un espace
b s # on se branche à l'étiquette
'
sed ':s;N;s/\n/ /;bs'
Afficher un intervalle entre 2 motifs sans les motifs
sed -n '/foo/,/bar/{//d;p}' fichier
sed -n '/Mandriva/,/RedHat/{//d;p}' adresses.txt
Gourmandise des expressions régulières
$ echo "azerty azerty azerty" | sed 's/a.*z/qw/'
qwerty
$ echo "azerty azerty azerty" | sed 's/a[^a]*z/qw/'
qwerty azerty azerty
La commande "n"
Localiser une ligne par un motif (/222/), charger la ligne suivante dans l'espace de travail et substituer la 2ème occurrence du chiffre "3" par un "4" :$ echo -e "111\n222\n333\n444" | sed '/222/{n; s/3/4/2}'
111
222
343
444
En n'affichant que la ligne concernée sur la sortie standard :
$ echo -e "111\n222\n333\n444" | sed -n '/222/{n; s/3/4/2p}'
343
Le même avec des lettres :
$ echo -e "AAA\nBBB\nCCC\nDDD" | sed '/BBB/ {n;s/C/Z/2}'
AAA
BBB
CZC
DDD
Indentation du script avec "sedsed" et explications sommaires :
$ echo -e "AAA\nBBB\nCCC\nDDD" | sedsed -i '/BBB/ {n;s/C/Z/2}'
/BBB/ { # On sélectionne la ligne avec ce motif
n # On place la ligne suivante dans l'espace de travail
s/C/Z/2 # On remplace le 2nd C par un Z
}
Il va de soit que ces 2 exemples ne sont là que pour une simple démonstration et ne sont pas du tout optimisés ni adaptés en ce qui concerne les substitutions, qui auraient pu (du) être faites en ciblant directement la ligne concernée.
Inverser 2 lignes
sed '
6 { # sélection de la ligne
h # copie dans la mémoire annexe
N # ajout dans la mémoire principale de la ligne suivante
G # ajout du contenu de la mémoire annexe à la mémoire principale
#+ la mémoire principale contenant à ce moment là :
#++ Ligne n° 6\nLigne n°7\nLigne n° 6\n
D # effacement jusqu'au 1er caractère de fin de ligne (\n)
}
'
Sur une ligne :
sed '6 {h;N;G;D}'
Effacement d'une ligne et insertion plus loin
#! /bin/sed -f
1 h # chargement 1ère ligne mémoire secondaire
1 d # effacement 1ère ligne
5 { # sélectionner sur la ligne 5
G # ajouter le contenu de la mémoire secondaire à la mémoire principale
N # ajouter la ligne suivante (la 6)
s/\n/ /g # substituer tous les sauts de ligne (\n) par un espace
}
Sur une seule ligne :
sed -n '1 h; 1 d; 5 { G; N; s/\n/ /g};P' fich.txt
Dissocier les commentaires des commandes
Passer toutes les lignes de commentaires se trouvant sur la même ligne que la commande associée, sur une ligne seule au-dessus de la commande :sed '
/^#\|^$/! { # Exclure les lignes débutant par un dièse et les lignes vides
/#/ { # Si la ligne contient un dièse
h # La copier dans l'espace annexe. L'original est encore dans l'espace de travail
s/.*\(#.*\)/\1/ # Ne conserver que ce qui se trouve après le dièse (dièse compris)
x # Échanger l'espace de travail avec l'espace annexe
s/\(.*\)#.*/\1/ # Ne conserver que ce qui se trouve avant le dièse
x # Échanger l'espace de travail avec l'espace annexe
G # Ajouter le contenu de l'espace annexe à l'espace de travail
}
}
' prog.sed
Sur une seule ligne :
sed '/^#\|^$/!{/#/{h; s/.*\(#.*\)/\1/;x;s/\(.*\)#.*/\1/;x;G;}};' prog.sed
Affichage conditionné
Afficher une ligne de commentaire uniquement si la ligne précédente est videsed -n '
/^$/ {
n
/^#/p
}
' fich2.txt
Sur une seule ligne :
sed -n '/^$/{n;/^#/p}' fich2.txt
Émulation de grep
Exemple 1
Émulation de : grep -A3 -B5 "motif" fichier#!/bin/sh
# Émulation de grep -A3 -B5 "motif" fichier
# Largement inspiré du script https://www.grymoire.com/Unix/Scripts/grep4.sh
# sur le site : https://www.grymoire.com/Unix/Sed.html#uh-56
case "$#" in
1) ;;
- ) echo "Usage: $0 \motif\" < fichier";exit;;esac;sed -n ''/$1/' !{ # Motif non satisfait - ajouter la ligne dans la mémoire annexe H # Remettez-le dans la mémoire principale (espace de travail) x # Ne conserver que 3 lignes dans le tampon # 2 lignes correspondent à .*\n.* # 3 lignes à .*\n.*\n.* # On efface les lignes excédentaires s/^.*\n\(.*\n.*\n.*\)$/\1/ # Mettre les 3 lignes (au plus) dans la mémoire annexe à nouveau x}'/$1/' { # Le motif est satisfait - Ajouter le contenu de la mémoire principale # à la mémoire secondaire H # Prendre la ligne suivante (n) et ajouter les 4 autres (N) n;N;N;N;N # Ajouter le tout à la mémoire annexe H # Échanger le tout avec la mémoire principale x # Afficher les lignes p}'
Sur une seule ligne :
sed -n '/ERROR/! {H;x;s/^.*\n\(.*\n.*\n.*\)$/\1/;x;}; /ERROR/ {H;n;N;N;N;N;H;x;p}'
Exemple 2 - Commande "x"
Voici 2 manières de faire pour émuler "grep -A1 -B1" (juste afficher la ligne précédente et la ligne suivante d'une ligne contenant un motif), en utilisant dans un 1er temps juste un échange entre les 2 mémoires tampons avec la commande "x" et dans un 2nd temps l'emploi de copie et d'ajout avec les commandes "h" et "H" combinées à la commande "x".Commande "x"
#! /bin/bash
sed -n ' # affichage sur demande uniquement
/indice7/! { # motif absent
x # on place la ligne dans la mémoire annexe (en fait on échange le contenu)
d # on efface l'espace de travail
}
/indice7/ { # motif présent
x # on l'échange avec le contenu de la mémoire annexe qui contient la ligne précédente
p # on l'affiche
x # on échange à nouveau la contenu des 2 mémoires
p # on affiche la ligne contenant le motif
n # on charge la ligne suivante
p # on l'affiche
x # on la replace dans la mémoire annexe
}
' fich3.txt
Sur une seule ligne :
sed -n '/indice7/! {x;d;}; /indice7/{x;p;x;p;n;p;x;}' fich3.txt
Exemple 3 - Commandes "h" "H" "x"
#! /bin/bash
sed -n ' # affichage sur demande uniquement
/indice7/! { # motif absent
h # on garde la ligne dans la mémoire annexe
}
/indice7/{ # motif présent
H # on l'ajoute au contenu de la mémoire annexe
n # on charge la ligne suivante
H # on l'ajoute au contenu de la mémoire annexe
x # on échange le contenu des 2 mémoires
p # on l'affiche
}
' fich3.txt
Sur une seule ligne :
sed -n '/indice7/! {h;}; /indice7/{H;n;H;x;p;}' fich3.txt
Étiquettes, boucles et mémoires tampons
Soit le fichier suivant (fich3.txt) :Regrouper sur une seule et même ligne, la ligne contenant "motif" et les lignes suivantes ne comportant pas ce motif.
#! /bin/sed -f
:notag # étiquette "pas de motif"
/tag/!{ # si la ligne ne contient pas le motif
1!H # ajouter le contenu à la mémoire annexe, sauf la 1ère ligne
1h # copie la 1ère ligne dans la mémoire annexe
x # échanger le contenu des 2 mémoires tampons
s/\n/ /g # supprimer tous les caractères de nouvelle ligne (\n)
x # échanger à nouveau le contenu des 2 mémoires tampons
$b lastline # se brancher à l'étiquette "dernière ligne"
d # effacer le contenu de l'espace de travail
}
/tag/{ # si la ligne contient le motif
x # échanger le contenu des 2 mémoires tampons
/^$/!p # si la ligne n'est pas vide, l'afficher
$b lastline # se brancher à l'étiquette "dernière ligne"
d # effacer le contenu de l'espace de travail
b notag # se brancher à l'étiquette "pas de motif"
}
:lastline # étiquette "dernière ligne"
x # échanger le contenu des 2 mémoires tampons
p # afficher le contenu de l'espace de travail
Sur une seule ligne :
sed -n ':notag;/tag/!{1!H;1h;x;s/\n/ /g;x;$b lastline;d;};/tag/{x;/^$/!p;$b lastline;d;b notag;};:lastline;x;p;'
Supprimer deux lignes précédents un motif donné
Supprimer les deux lignes précédents un motif donné.Le fichier de référence : plop
Pattern
blablabla
blablabla
blu
ToDelete << Ligne à effacer
ToDelete << Ligne à effacer
Pattern
blablabla
blablabla
blo
ToDelete << Ligne à effacer
ToDelete << Ligne à effacer
Pattern
blablabla
blablabla
bly
ToDelete << Ligne à effacer
ToDelete << Ligne à effacer
Pattern
blablabla
blablabla
La commande :
sed '
/Pattern/ !{ # La ligne ne contient pas le motif
:z # Étiquette
h # On copie l'espace de travail dans la
#+ dans la mémoire annexe
N # On ajoute la ligne suivante
/Pattern$/ !b z # L'espace de travail ne se termine pas par
#+ le motif recherché
#++ alors on se branche à l'étiquette
s/.*\n// # La ligne se termine par le motif, on
#+ supprime tout jusqu'au dernier caractère
#++ représentant un saut de ligne
x # On échange le contenu des 2 mémoires
s/\(.*\)\n.*\n.*$/\1/ # On efface les 2 dernières lignes
G # On ajoute le contenu de la mémoire annexe
#+ à l'espace de travail
}' plop
Le thread en rapport dans le forum
Effacer les n dernières lignes
Éliminer les n dernières lignes sans connaitre le nombre de lignes (ici les 4 dernières)
seq 10 | # on génère 10 lignes à partir de la commande "seq"
sed -n ' # affichage sur demande uniquement
:s # étiquette
1,3 { # tant qu'on n'a pas 3 lignes dans l'espace de travail
N # on ajoute la ligne suivante
b s # on se branche à l'étiquette jusqu'à remplir la condition
}
4,$ { # tant qu'on n'a pas atteint la dernière ligne
N # on ajoute la ligne suivante
P # on affiche la ligne contenue dans l'espace de travail jusqu'au 1er caractère
#+ symbolisant une fin de ligne (\n)
D # puis on l'efface de l'espace de travail
}
'
Sur une seule ligne :
seq 10 | sed -n ':s;1,3{N;bs};4,${N;P;D}'
Émulation de "tac" (inverser les lignes d'un fichier)
#!/bin/sed -nf
# Hormis la 1ère ligne
1!G # A jouter le contenu de la mémoire annexe à l'espace de travail
# Si la dernière ligne est atteinte
$p # Afficher le résultat
# Copier le contenu de l'espace de travail dans la mémoire annexe
h
Sur une seule ligne :
sed -n '1! G;$ p;h'
Exemple de branchement inconditionnel
Remplacer toutes les fins de ligne par des tirets
sed -e '
:boucle # étiquette
N # on ajoute la ligne suivante
$! b boucle # tant que la dernière ligne n'est pas atteinte
#+ on se branche à l'étiquette
s/\n/--/g # on substitue toutes les fins de ligne par 2 tirets (--)
' fich.txt
Sur une seule ligne :
sed -e ':boucle;N;$! b boucle; s/\n/--/g'
Exemple de branchement conditionnel (t)
(si une substitution a été opérée, alors on boucle)Centrer du texte sur 20 colonnes en ajoutant un espace avant et après
sed -e '
:boucle # étiquette
s/^.\{1,20\}$/ & / # on substitue le contenu de la ligne par lui même (&) en ajoutant
#+ un espace avant et après
t boucle # tant qu'une substitution a eu lieu, se brancher à l'étiquette
' fich.txt
# Sur une seule ligne :
#
sed -e ':boucle;s/^.\{1,20\}$/ & /; t boucle'
Autre exemple de branchement conditionnel
Transformer "AABBCCDDEEFF" en "AA:BB:CC:DD:EE:FF"On serait tenté d'utiliser un simple :
echo "AABBCCDDEEFF" | sed 's/../&:/g'
Mais le problème c'est que cette syntaxe rajoute aussi un ":" en fin de ligne :
AA:BB:CC:DD:EE:FF:
La solution consiste donc à faire une boucle en utilisant la syntaxe des expressions régulières et notamment les limites de caractère ou de mot (word boundary) :
echo "AABBCCDDEEFF" | sed ':z;s/\<..\B/&:/;tz'
Exemple de branchement conditionnel (T)
(si une substitution n'a pas été opérée, alors on boucle)Éliminer un intervale de lignes dont le début est représenté par un motif (C) et la fin étant le 3ème "Y".
$ var="A\nY\nB\nY\nC\nY\nD\nY\nE\nY\nF\nG"
echo -e "$var" |\
sed '
/C/ {
:boucle
N
s/.*Y.*Y.*Y//
T boucle
}
'
Sur une seule ligne :
sed '/C/{:boucle;N;s/.*Y.*Y.*Y//;T boucle};'
Pour la portabilité utiliser plutôt :
sed '
/C/ {
:boucle
N
s/.*Y.*Y.*Y//
t
b boucle
}
'
Sur une seule ligne :
sed -e '/C/{:boucle' -e 'N;s/.*Y.*Y.*Y//;t' -e 'b boucle' -e '}'
# Voir aussi cette discussion dans le forum :
http://www.commentcamarche.net/forum/affich 4856842 sed substitution
sed ' # recherche le motif /* ... */
s!/\*.*\*/!! # sur une ligne
/;[ ]*\/\*/ { # sur plusieurs lignes mais ne commençant pas en début de ligne (après
#+ un point virgule suivi éventuellement d'un (ou plusieurs) espace(s)
:z # étiquette pour boucler
N # on ajoute la ligne suivante
s!/\*.*\*/!! # on suprime tout entre /* et */
T z # on teste si une substitution a eu lieu. Dans le cas contraire on boucle
}
/\/\*/,/\*\// d # sur plusieurs lignes
'
Substitution avec tampons
Substitution des 2 premières occurrences d'une expression en employant les tampons
echo $A
2007:10:07 16:34:05
echo $A |
sed -e '
h # on copie l'espace de travail dans la mémoire annexe
s/\(.*\) .*/\1/ # on ne garde que la 1ère partie de l'expression (la date)
s/:/-/g # on substitue tous les deux points par des tirets
x # on échange le contenu des 2 mémoires
s/.*\( .*\)/\1/ # on ne garde que la 2nd partie de l'expression (l'heure)
H # on l'ajoute au contenu de la mémoire annexe
g # on copie le contenu de la mémoire annexe dans l'espace de travail
s/\n// # on supprime le caractère fin de ligne
'
Sur une seule ligne :
echo $A |sed -e 'h;s/\(.*\) .*/\1/;s/:/-/g;x;s/.*\( .*\)/\1/;H;g;s/\n//'
Décommenter les directives d'un fichier
Soit un fichier de configuration avec ses directives, ses lignes de commentaires et ses instructions commentées. Chaque paragraphe étant séparé du suivant par une ligne vide.Comment décommenter un jeu d'instructions qui commence par une ligne commentée (contenant un mot-clé) suivie par les directives commentées elles aussi.
sed '
/# mot-clé/ { # motif recherché
:label # étiquette
/^$/q # si la ligne est vide on quitte
n # on charge dans l'espace de travail la ligne suivante
s/^#// # on supprime le dièse en début de ligne
t label # si une substitution a eu lieu, on se branche à l'étiquette
}
' fichier
Sur une seule ligne :
sed '/# mot-clé/{:label;/^$/q;n;s/^#//;t label;}'
Conversion de caractères
Convertir seulement les 12 premiers caractères accentués de chaque ligne :
$ cat plop
àaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïié
ÀaéeÈeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïié
àaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïié
àaéeèeÔoùuïiàaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïié
àaÉeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïiàaéeèeôoùuïié
sed '
h # on copie l'espace de travail dans la mémoire annexe
s/\(^.\{12\}\).*/\1/ # on récupère les 12 premiers caractères de l'espace de travail
y/àâéèêëîïôöùûü/aaeeeeiioouuu/ # on convertit les minuscules
y/ÀÂÉÈÊËÎÏÔÖÙÛÜ/AAEEEEIIOOUUU/ # on convertit les majuscules
x # on échange le contenu des 2 mémoires
s/^.\{12\}\(.*\)/\1/ # on récupère tous les caractères après le 12 ème
x # on échange le contenu des 2 mémoires
G # on ajoute le contenu de la mémoire annexe
s/\n// # on supprime les caractères fin de ligne
' plop
Mise en forme de texte 1
Voici un exemple illustrant avec 2 méthodes bien différentes, la mise en forme d'un texte selon les critères suivants :à partir de la 6ème virgule, supprimer chaque guillemet encadrant chaque champ, exepté le dernier
Le texte de référence :
$ cat plop
{"88","6","Trademark2","Model6","6OD","7","false","null","null","1","30","1","40","1","60","1","65","1","65","1","70","1","70","1","70"},
{"89","6","Trademark2","Model6","6PD","7","false","null","null","10","30","10","50","10","70","15","75","25","75","25","80","25","80","25","80"},
Avec boucle conditionnée
Méthode avec une boucle conditionnée :
sed '
s/,/,\n/5 # On substitue la 5 ème virgule par elle même
#+ suivie d'un saut de ligne
:s # étiquette
s/\(\n.*\)"/\1/ # là on joue sur la gourmandise des regex, la
#+ sous-expression englobant tout ce qui se trouve
#++ avant le dernier guillemet que l'on remplace donc
#+++ par elle même à l'exception du guillemet
t s # tant qu'une substitution a eu lieu, on boucle
s/\n\(.*\)}/"\1"}/ # et pour finir on remplace tout ce qui se trouve
#+ après le saut de ligne jusqu'à l'accolade fermante
#++ par ce contenu plus un guillemet et une accolade
#+++ la virgule finale n'étant pas dans la LHS est
#++++ reportée naturellement
'
plop
Sur une seule ligne :
sed 's/,/,\n/5;:s;s/\(\n.*\)"/\1/;ts;s/\n\(.*\)}/"\1"}/'
Avec mémoire tampon
Méthode avec mémoire tampon :
sed '
s/\"/§/12 # on substitue le 12 ème guillemet par un caractère quelconque
h # on copie la mémoire principale dans la mémoire annexe
s/§.*// # on efface ce caractère et tout qui se trouve après
x # on échange le contenu des 2 mémoires
s/.*§,// # on efface la partie correspondante à la mémoire annexe
s/\"//g # on supprime tous les guillemets
x # on échange à nouveau le contenu des 2 mémoires
G # on ajoute le contenu de la mémoire annexe à la principale
s/\n/,/ # on remplace le saut de ligne séparant les 2 mémoires par
#+ une virgule
s/}/\"}/ # on rajoute le dernier guillemet
'
plop
Sur une seule ligne :
sed -e 'h;s/"/§/12;s/§.*//;x;s/"/§/12;s/.*§,//;s/"//g;x;G;s/\n/,/;s/}/"}/' plop
Mise en forme de texte 2
Dans le même esprit que précédemment, mais ici il faut remplacer les espaces vides contenus au début du 1er champ (et uniquement dans celui-ci) par des 0 (zéros).2 méthodes là encore, une avec boucle et une utilisant les mémoires tampons.
Fichier de référence :
$ cat plop
1023 LOGS blabla
12333 LOGS blabla
44 LOGS blabla
2580 LOGS blabla
1458 LOGS blabla
5 LOGS blabla
Méthode avec boucle
sed '
/^ / { # seules les lignes commençant par un espace
:boucle # étiquette
s/^ [^[:alnum:]]*/&\n/ # on ajoute un saut de ligne après le dernier espace du 1er champ
s/\([ ]\?\) \{1\}\n/\10/ # on substitue un espace par lui même suivi d'un 0 (zéro)
t boucle # tant qu'une substitution a eu lieu, on boucle
}
'
Sur une seule ligne :
sed '/^ / {:boucle; s/^ [^[:alnum:]]*/&\n/; s/\([ ]\?\) \{1\}\n/\10/; t boucle}' plop
Méthode avec mémoires tampons
sed '
/^ / { # seules les lignes commençant par un espace
s/^ [^[:alnum:]]*/&\n/ # on ajoute un saut de ligne après le dernier espace du 1er champ
h # on copie la mémoire principale dans la mémoire annexe
s/\n.*$// # on efface de la mémoire principale tout ce qui suit le saut de
#+ ligne (saut de ligne compris)
s/ /0/g # on substitue tous les espaces par des 0 (zéros)
x # on échange le contenu des 2 mémoires
s/.*\n// # on efface cette fois ci tout ce qui précède le saut de ligne
#+ (saut de ligne compris)
x # on échange à nouveau le contenu des 2 mémoires
G # on copie le contenu de la mémoire annexe à la suite de la
#+ mémoire principale
s/\n// # et on supprime le saut de ligne
}
'
Sur une seule ligne :
sed '/^ / {s/^ [^[:alnum:]]*/&\n/;h;s/\n.*$//;s/ /0/g;x;s/.*\n//;x;G;s/\n//}' plop
Post en référence
La commande "c"
echo -e "A\nB\nC\nD\nE\nF\nG" | sed '/B/,/F/ c\DELETED'
Les fichiers de références pour les exemples
Vous trouverez ci-dessous la plupart des fichiers utilsés tout au long de ce document pour illustrer les différents exemples vus, afin de vous permettre de mieux cerner certaines commandes.fich.txt
Ligne n° 1
Ligne n° 2
Ligne n° 3
Ligne n° 4
Ligne n° 5
Ligne n° 6
Ligne n° 7
Ligne n° 8
Ligne n° 9
Ligne n° 10
fich2.txt
Ligne n° 1
Ligne n° 2
# commentaire1 # Ligne n° 3
Ligne n° 4
Ligne n° 5 # La prochaine ligne est vide (6)
# commentaire2 # Ligne n° 7, la ligne précédente est vide (6)
Ligne n° 8
Ligne n° 9 # La prochaine ligne est vide (11)
Ligne n° 11 # La ligne précédente est vide (10)
Ligne n° 12
Ligne n° 13
Ligne n° 14
fich3.txt
Ligne n° 1 tag :
indice1 indice2
indice3
Ligne n° 2 tag :
Ligne n° 3 tag :
Ligne n° 4 tag :
indice4 indice5
Ligne n° 5 tag :
Ligne n° 6 tag:
indice6
Ligne n° 7 tag :
Ligne n° 8 tag :
indice7
indice8 indice9
indice10
Ligne n° 9 tag :
Ligne n° 10 tag :
adresses.txt
Ubuntu 31000 Toulouse
Mandriva 34000 Montpellier
SuSE 66000 Perpignan
Debian 31130 Balma
Gentoo 34500 Béziers
Slackware 66100 Collioure
Fedora 31400 Muret
RedHat 34200 Agde
Kaella 66500 Elne
signature.txt
--
Pour toutes correspondances, veuillez vous adressez à :
(substituez "<moderateur>" par le nom du modérateur adéquat)
<moderateur>@commentcamarche.com
Merci de votre attention.
L'équipe CCM
prog.sed
#! /bin/sed -f
1 h # chargement 1ère ligne mémoire secondaire
1 d # effacement 1ère ligne
5 { # sélectionner sur la ligne 5
G # ajouter le contenu de la mémoire secondaire à la mémoire principale
N # ajouter la ligne suivante (la 6)
s/\n/ /g # substituer tous les sauts de ligne (\n) par un espace
}
# Sur une seule ligne :
# sed -n '1 h; 1 d; 5 { G; N; s/\n/ /g};P' fich.txt
Discussions en rapport sur le forum
- Insertion ligne avec ksh
- Comparaison ligne à ligne dans fichier unix
- Remplacement d 1 ligne dans un fichier
- Shell : sed et anti-quotes
- Lecture sur un fichier xsd
- Remplacement de caractères (tr)
- Substitution de chaines de caractères
- Probléme d'extraction des données
- Concaténer chaines d'un texte
- Extraire une chaine de caractères
- Extraire une chaine de caractères (2)
- Remplacer des lignes par d'autres avec sed
- Remplacer 100 lignes
- Copier 100 lignes d un fichier
- Remplacer le séparateur dans une commande sed
- Remplacement avec sed
- Remplacer et protéger des quotes simples
- Récupérer première et dernière ligne de plusieurs fichiers
- Supprimer une partie d'un fichier shell
- Supprimer la ligne précédent une regex