GNU/Linux >> Tutoriels Linux >  >> Linux

Remplacer Sed multi-lignes

Réponse AWK

Avec votre exemple de texte dans un fichier nommé sql , le modèle suivant (avec des sauts de ligne et une indentation pour plus de clarté) :

awk -v skip=1 '{
    if (skip) { skip=0 }
    else {
        if (/FULLTEXT KEY/) { skip=1; sub(/,$/, "", prevline) }
        print prevline
    }
    prevline=$0
}
END { print prevline }' sql

produit :

CREATE TABLE `table` (
  `id` int(10) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL default '',
  `description` text NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

Explication :

  • Nous implémentons "l'anticipation" en n'imprimant que le précédemment ligne rencontrée à chaque itération, après avoir inspecté la ligne courante.
  • Si la ligne courante contient le FULLTEXT KEY marqueur, nous définissons un indicateur pour ignorer l'impression de cette ligne lors de la prochaine itération. Nous supprimons également la virgule de fin sur la ligne précédente qui est sur le point d'être imprimée.
  • Nous sautons l'impression d'une ligne initiale vide (avant prevline a été défini) en définissant initialement skip à 1 ("vrai").
  • Nous nous assurons d'imprimer la dernière ligne en terminant le script avec un prevline supplémentaire imprimer. Notez que l'implémentation actuelle suppose que cette dernière ligne n'est pas une ligne risquant d'être sautée, c'est-à-dire qu'elle ne contient pas le FULLTEXT KEY marqueur.

Original (incomplet) sed répondre

Cette réponse est incomplète et certainement incorrecte dans la plupart des cas, puisque sed consommera le flux d'entrée trop rapidement pour le résultat escompté lors de la correspondance multiligne - comme indiqué dans les commentaires, cela ne fonctionnera que pour les correspondances sur les lignes paires ! sed n'a pas de "véritable" fonctionnalité d'anticipation, nous ferions donc mieux d'utiliser Python/Perl/etc., ou bien AWK comme ci-dessus.

Avec votre exemple de texte dans un fichier nommé sql , le modèle suivant :

$ sed 'N; s/,\n  FULLTEXT.*//' sql

produit :

CREATE TABLE `table` (
  `id` int(10) NOT NULL auto_increment,
  `name` varchar(100) NOT NULL default '',
  `description` text NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40101 SET character_set_client = @saved_cs_client */;

Explication :

  • N permet la correspondance multiligne.
  • \n représente un saut de ligne.
  • s/pattern/replacement/ est la syntaxe de remplacement standard.
  • .* correspondra à n'importe quoi jusqu'à la fin de la ligne courante.

Linux
  1. Remplacer la plage de lignes par la plage de lignes (sed ou autres) ?

  2. Supprimer les chaînes multilignes ?

  3. Convertir une chaîne en hexadécimal sur la ligne de commande

  4. Comment remplacer une chaîne dans plusieurs fichiers en ligne de commande Linux

  5. trouver le texte correspondant et remplacer la ligne suivante

Top 20 des commandes sed à utiliser

Tutoriel Unix Sed :ajouter, insérer, remplacer et compter les lignes de fichiers

Tutoriel Unix Sed :Opération de fichiers multilignes avec 6 exemples pratiques

remplacer la nième occurrence de chaîne dans chaque ligne d'un fichier texte

sed :comment remplacer la ligne si elle est trouvée ou ajouter à la fin du fichier si elle n'est pas trouvée ?

remplacer les lignes d'un fichier par les lignes d'un autre par numéro de ligne