Je prépare une présentation pour un public non technique. J'ai un programme fonctionnant en bash qui produit un flux continu de valeurs, dont certaines sont importantes. Je voudrais souligner les résultats importants tels qu'ils sont affichés afin que le public puisse se faire une idée de leur fréquence. Le problème est que je ne peux pas sed
opérer sur un flux en cours d'exécution. Cela fonctionne bien si je mets les résultats dans un fichier, comme dans:
cat output.txt | sed "s/some text/some text bolded/"
Mais si j'essaye la même chose sur la sortie en cours d'exécution, comme ceci:
command | sed "s/some text/some text bolded/"
sed
ne fait rien. Des pensées?
Comme Lambert a été assez utile pour le souligner, mon affirmation selon laquelle sed
cela ne fait rien était vague. Ce qui se passe, c'est que le programme génère stdout
(je suis sûr qu'il n'écrit pas stderr
) comme il le ferait normalement, même s'il est acheminé sed
.
Le problème semble être que la commande appelle un deuxième programme, qui sort ensuite vers stdout. Il y a quelques lignes imprimées par le premier programme; je peux les modifier. Ensuite, il y a un flux de valeurs imprimées par le deuxième programme; je ne peux pas les modifier.
Les méthodes Perl et awk ne fonctionnent pas non plus.
la source
stdbuf -o0 command | sed "s/some text/some text bolded/"
marche?command|egrep 'some text|$'
g
substitution "globale", sinon seule la première occurrence sur une ligne sera remplacée:sed "s/old/new/g"
Réponses:
Il est probable que la sortie de la commande soit mise en mémoire tampon. Lorsque la commande écrit sur un terminal, le tampon est vidé sur chaque nouvelle ligne, vous le voyez donc apparaître au taux attendu. Lorsque la commande écrit dans un canal, le tampon n'est vidé que lorsqu'il atteint quelques kilo-octets, il est donc très en retard. Ainsi est le comportement par défaut de la bibliothèque d'entrée / sortie standard.
Pour forcer la commande à ne pas mettre en buffet sa sortie, vous pouvez utiliser
unbuffer
(à partir de l'attente) oustdbuf
(à partir de GNU coreutils).la source
stdbuf
n'a pas fonctionné (il a été mentionné précédemment, BTW), maisunbuffer
a fonctionné !! Tu n'as aucune idée de ton bonheur.sed
lui-même utilise un tel tampon, (cf ChennyStar post) donc les exemples ici peuvent ne pas fonctionner carsed
c'est lecommand
to unbuffer:cat /etc/passwd | unbuffer sed
maissed
lui-même a une-u
option, doncgrep
pourrait être plus approprié dans ces exemples. Merci beaucoup pour vos informations de base! Très bonne réponse!sed
a une option pour cela:Ce qui charge des quantités minimales de données à partir des fichiers d'entrée et vide les tampons de sortie plus souvent. Voir
man sed
pour plus de détails.la source
sed
uniquement (pas BSDsed
), et je pense que cela n'empêchera toujours pas la mise en mémoire tampon de la commande au début du canal. Mais bon de le mentionner. :)J'utiliserais awk
où
/some important stuff/
sélectionner une ligne importante, comme dans sedprintf "%c[31m%s%c[0m\n",27,$0,27 ;
impression en rougele point clé est que cela
command
devrait vider les lignes, mais cela devrait être le cas si vous avez beaucoup de sortie.la source
awk
(en utilisantsub()
ougsub()
), dans le cas de cette substitution primitive,sed
c'est certainement l'outil approprié.La façon Perl:
ou avec une sortie continue:
Un script bash pour la sortie
cont
:Testez avec:
\x1b[1m
- intensité audacieuse ou augmentée${1}
- le backreferenze\x1b[0m
- réinitialiser tous les attributsProduction:
Plus de codes d'échappement ici .
la source