Daniel Caillibaud a écrit, mardi 23 décembre 2008, à 17:05 : > Jacques L'helgoualc'h a écrit : >> Daniel Caillibaud a écrit, mardi 23 décembre 2008, à 10:15 : >>> njko a écrit : >> [...] >>>> Comment dire à sed de remplacer les n dernieres lignes de différents >>>> fichiers par un mot? >>> Directement, tu ne peux pas. >> >> Mécréant ! Sed est Turing-complet, il /peut/ le faire : >> >> ~ $ echo {1..12} | sed 's/ /\n/g' | \ >> sed -nre 'H;${g;s/(\n[^\n]*){0,25}$/\nIN MEMORIAM MAXI 25 LIGNES, >> AMEN/;s/^\n//p}' >> IN MEMORIAM MAXI 25 LIGNES, AMEN > > Évidemment, mais là tu charge tout dans le holdspace et tu appliques une > regex dessus, ça sort du concept "stream editor" (mais c'est possible), > dans la mesure où tu dois attendre d'avoir atteint la fin du fichier (en > ayant tout chargé en attendant) pour commencer à travailler. Sur un petit > fichier ça va, sur un log de qq centaines de Mo c'est moins top ;-)
Oui, c'est un peu goret de tout lire avant de commencer à bosser (c'est pour ça que je suggérais de chercher l'émulation de tail). Il me semble que dans les trésors de http://sed.sf.net on peut trouver une méthode de fenêtre glissante FIFO qui permet, appliquée ici, - de stocker les 25 premières lignes ; - puis écrire la première, l'effacer et ajouter la nouvelle en queue ; - et faire la substitution demandée, une fois avalée la dernière ligne... > Bref, je pense que wc + head reste le plus adapté à ce cas de figure. C'est sans doute plus simple, en effet --- même si on peut aussi l'écrire avec Sed :) --- mais tu lis deux fois tout le fichier, ce qui n'est pas indiqué avec un ruban, des cartes perforées, une bande magnétique ou un pipe :P > PS: pour ceux qui veulent comprendre, un peu d'explications sur > l'expression sed de Jacques (un script sed s'applique sur chaque ligne > en entrée) > <script sed> > H; # ajouter la ligne courante au holdspace (mémoire tampon) > ${ # si on est sur la dernière ligne, on exécute ce bloc > # récupérer le contenu du holdspace > g; > # remplacer la plus grande séquence constituée de 0 à 25 lignes se > terminant par la fin de fichier > # par le texte IN MEMORIAM... (1re expression s/pattern/replace/ > s/(\n[^\n]*){0,25}$/\nIN MEMORIAM MAXI 25 LIGNES, AMEN/ # supprimer le tout premier retour chariot en début de fichier # (cf. plus bas, à cause de 1H), et imprimer le résultat s/^\n//p > } > </script sed> > > les options sed sont > -n : n'imprimer les lignes reçues en entrée que si on le demande > explicitement (avec p) > -r : il s'agit de regex étendues ... sinon il faudrait taper s/\(\n[^\n]*\)\{0,25\}$/... et quatre contre-obliques séparées, c'est moins agréable que « -r espace » sur un clavier azerty. > -e : appliquer l'expression qui suit (entre apostrophes, pour que le shell > n'interprête pas les $) > > Je comprend d'ailleurs pas trop ce s/^\n//p, un > sed -nre 'H;${g;s/(\n[^\n]*){0,25}$/\nIN MEMORIAM MAXI 25 LIGNES, AMEN/p;}' > revient au même non ? Non, le H introduit un \n parasite devant la première ligne --- je ne le nettoie qu'ensuite, car il m'épargne un (^|\n) au début des lignes à remplacer... Pour ne stocker que le fichier dans le holdspace, il faudrait un 1h;1!H -- Jacques L'helgoualc'h -- Lisez la FAQ de la liste avant de poser une question : http://wiki.debian.org/DebFrFrenchLists Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et "Reply-To:" To UNSUBSCRIBE, email to debian-user-french-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org