Ma question concerne le sed
-solution spécifique donnée dans cette réponse pour cette question de grepping inverse. Le sed
/grep
solution que je n'arrive pas à déchiffrer est la suivante :
sed '1!G;h;$!d' file
Quelqu'un peut-il déchiffrer cette commande ?
Je sais d'après VI(M) que G désigne la dernière ligne du fichier et que dans sed un bang(!) suivi d'une adresse fonctionne un peu comme grep -v
c'est-à-dire qu'il ne correspondra pas à cette ligne. Mais dans l'ensemble, le script sed en ligne ci-dessus me dépasse.
Réponse acceptée :
Cela inverse le fichier ligne par ligne.
sed '1!G;h;$!d' file
Tout d'abord, sed
a un espace de conservation et un espace de motif . Nous devons les distinguer avant de nous concentrer sur cette commande spécifique.
Quand sed
lit une nouvelle ligne, elle est chargée dans l'espace du motif. Par conséquent, cet espace est écrasé chaque fois qu'une nouvelle ligne est traitée. D'autre part, l'espace de maintien est cohérent sur l'ensemble du traitement et les valeurs peuvent y être stockées pour une utilisation ultérieure.
À la commande :
Il y a 3 commandes dans cette instruction :1!G
, h
et $!d
-
1!G
signifie que leG
La commande est exécutée sur chaque ligne sauf la première (le!
nie le1
).G
signifie ajouter ce qui est dans l'espace de maintien dans l'espace de motif. -
h
s'applique à chaque ligne. Il copie l'espace du motif à l'espace de maintien (et l'écrase). -
$!d
s'applique à toutes les lignes sauf la dernière ($
représente la dernière ligne,!
le nie).d
est la commande pour supprimer la ligne (espace de motif).
- Maintenant, lorsque la première ligne est lue,
sed
exécute leh
commande. La première ligne est copiée dans l'espace réservé. Ensuite, il est supprimé, car il correspond au$!
état.sed
continue avec la deuxième ligne. - La deuxième ligne correspond à la condition
1!
(ce n'est pas la première ligne), et donc l'espace de maintien (qui a la première ligne) est ajouté à l'espace de motif (qui a la deuxième ligne). Après cela, dans l'espace du motif, il y a maintenant la deuxième ligne suivie de la première ligne, délimitée par une nouvelle ligne. Maintenant, leh
commande s'applique (comme dans chaque ligne); tout ce qui se trouve dans l'espace pattern est copié dans l'espace hold. La troisième instruction ($!d
) s'applique :la ligne est supprimée de l'espace du motif. - L'étape 2 est maintenant terminée avec toutes les lignes. Nous sautons à la dernière ligne.
- Dans la dernière ligne (
$
) presque toute l'étape 2 est terminée, mais pas la partie de suppression (d
).sed
, lorsqu'il est invoqué sans-n
, imprime automatiquement l'espace du motif à la fin du traitement pour chaque ligne d'entrée. Ainsi, lorsqu'il n'est pas supprimé, l'espace du motif est imprimé. Il contient maintenant toutes les lignes en ordre inversé .