Le texte suivant imprime la ligne correspondante TERMINATE
jusqu'à la fin du fichier :
sed -n -e '/TERMINATE/,$p'
Expliqué : -n
désactive le comportement par défaut de sed
d'imprimer chaque ligne après avoir exécuté son script sur celle-ci, -e
a indiqué un script pour sed
, /TERMINATE/,$
est une sélection de plage d'adresses (lignes), ce qui signifie que la première ligne correspondant à l'adresse TERMINATE
(comme grep) à la fin du fichier ( $
), et p
est la commande print qui imprime la ligne en cours.
L'impression se fera à partir de la ligne qui suit la ligne correspondante. TERMINATE
jusqu'à la fin du fichier : (depuis APRÈS la ligne correspondante jusqu'à EOF, sans inclure la ligne correspondante)
sed -e '1,/TERMINATE/d'
Expliqué : 1,/TERMINATE/
est une sélection de plage d'adresses (lignes), c'est-à-dire de la première ligne pour l'entrée à la première ligne correspondant à l'adresse TERMINATE
expression régulière, et d
est la commande delete qui supprime la ligne en cours et passe à la ligne suivante. En tant que sed
Le comportement par défaut est d'imprimer les lignes, il imprimera les lignes après TERMINATE
jusqu'à la fin de l'entrée.
Si vous souhaitez que les lignes précédant TERMINATE
:
sed -e '/TERMINATE/,$d'
Et si vous voulez les deux lignes avant et après TERMINATE
dans deux fichiers différents en un seul passage :
sed -e '1,/TERMINATE/w before
/TERMINATE/,$w after' file
Les fichiers avant et après contiendront la ligne avec terminate, donc pour traiter chacun d'entre eux vous devez utiliser :
head -n -1 before
tail -n +2 after
SI vous ne voulez pas coder en dur les noms de fichiers dans le sed script, vous pouvez le faire :
before=before.txt
after=after.txt
sed -e "1,/TERMINATE/w $before
/TERMINATE/,\$w $after" file
Mais il faut ensuite s'échapper de la $
ce qui signifie la dernière ligne pour que l'interpréteur de commandes n'essaie pas d'étendre le fichier $w
(notez que nous utilisons maintenant des guillemets doubles autour du script au lieu de guillemets simples).
J'ai oublié de préciser que la nouvelle ligne est importante après les noms de fichiers dans le script pour que sed sache que les noms de fichiers se terminent.
Comment remplacer le code TERMINATE
par une variable ?
Vous devez créer une variable pour le texte correspondant et procéder de la même manière que dans l'exemple précédent :
matchtext=TERMINATE
before=before.txt
after=after.txt
sed -e "1,/$matchtext/w $before
/$matchtext/,\$w $after" file
pour utiliser une variable pour le texte correspondant dans les exemples précédents :
## Print the line containing the matching text, till the end of the file:
## (from the matching line to EOF, including the matching line)
matchtext=TERMINATE
sed -n -e "/$matchtext/,\$p"
## Print from the line that follows the line containing the
## matching text, till the end of the file:
## (from AFTER the matching line to EOF, NOT including the matching line)
matchtext=TERMINATE
sed -e "1,/$matchtext/d"
## Print all the lines before the line containing the matching text:
## (from line-1 to BEFORE the matching line, NOT including the matching line)
matchtext=TERMINATE
sed -e "/$matchtext/,\$d"
Les points importants concernant le remplacement du texte par des variables dans ces cas sont les suivants :
- Variables (
$variablename
) inclus dans single quotes
[ '
ne se développera pas, mais les variables à l'intérieur de double quotes
[ "
Le [ ] sera. Vous devez donc modifier tous les single quotes
a double quotes
s'ils contiennent du texte que vous souhaitez remplacer par une variable.
- En
sed
contiennent également un $
et sont immédiatement suivis d'une lettre comme : $p
, $d
, $w
. Ils ressembleront également à des variables à développer, vous devez donc les échapper $
avec une barre oblique inverse [ \
] comme : \$p
, \$d
, \$w
.
37 votes
UUOC (Useless Use of cat) :
grep 'TERMINATE' file
44 votes
Je le sais, c'est comme ça que je l'utilise. Revenons à la question.
4 votes
Il s'agit d'une question de programmation tout à fait pertinente, qui convient parfaitement à stackoverflow.
16 votes
@Jacob Ce n'est pas du tout une utilisation inutile du chat. Son utilisation est d'imprimer un fichier sur la sortie standard, ce qui signifie que nous pouvons utiliser
grep
pour lire les données, plutôt que d'avoir à apprendre quel commutateur appliquer à l'interface d'entrée standard dugrep
ysed
yawk
ypandoc
yffmpeg
etc. lorsque nous voulons lire un fichier. Cela permet de gagner du temps car il n'est pas nécessaire d'apprendre un nouveau commutateur chaque fois que l'on veut faire la même chose : lire un fichier.0 votes
@runeks Je suis d'accord avec votre sentiment - mais vous pouvez y parvenir sans chat :
grep 'TERMINATE' < file
. Peut-être que cela rend la lecture un peu plus difficile - mais il s'agit d'un script shell, donc ce sera toujours un problème :)0 votes
Véase cette réponse d'Ed Morton