GNU/Linux >> Tutoriels Linux >  >> Linux

Comment la commande Sed '1!g;h;$!d' inverse-t-elle le contenu d'un fichier ?

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 le G La commande est exécutée sur chaque ligne sauf la première (le ! nie le 1 ). 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).

  1. Maintenant, lorsque la première ligne est lue, sed exécute le h 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.
  2. 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, le h 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.
  3. L'étape 2 est maintenant terminée avec toutes les lignes. Nous sautons à la dernière ligne.
  4. 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é .
En relation :Patcher un binaire avec dd ?
Linux
  1. Comment extraire le fichier tar.gz sous Linux à l'aide de la ligne de commande

  2. Comment la commande Xdg-open sait-elle quelle application utiliser pour ouvrir un fichier ?

  3. Comment monter à partir de la ligne de commande comme le fait le Nautilus ?

  4. Comment la commande stat calcule-t-elle les blocs d'un fichier ?

  5. Comment ajouter la sortie à un fichier ?

Afficher le contenu d'un fichier dans la ligne de commande Linux

Comment supprimer des lignes d'un fichier à l'aide de la commande Sed

Comment lire l'avant-dernière ligne d'un fichier avec Bash ?

La commande Linux sed ne modifie pas le fichier cible

Comment obtenir l'URL du fichier Dropbox à partir de la ligne de commande ?

Comment fonctionne la commande ps ?