Vous cherchez quelque chose comme ça? Des idées?
cmd | prepend "[ERRORS] "
[ERROR] line1 text
[ERROR] line2 text
[ERROR] line3 text
... etc
Vous cherchez quelque chose comme ça? Des idées?
cmd | prepend "[ERRORS] "
[ERROR] line1 text
[ERROR] line2 text
[ERROR] line3 text
... etc
Réponses:
cmd | while read line; do echo "[ERROR] $line"; done
a l'avantage d'utiliser uniquement les commandes intégrées bash, de sorte que moins de processus seront créés / détruits, ce qui devrait être plus rapide que awk ou sed.
@tzrik fait remarquer que cela pourrait aussi faire une belle fonction bash. Définir comme:
function prepend() { while read line; do echo "${1}${line}"; done; }
lui permettrait d'être utilisé comme:
cmd | prepend "[ERROR] "
sed) ni même stringitting ( awk) n'est utilisé.)
function prepend() { while read line; do echo "${1}${line}"; done; }
Essaye ça:
cmd | awk '{print "[ERROR] " $0}'
À votre santé
awk -vT="[ERROR] " '{ print T $0 }'ouawk -vT="[ERROR]" '{ print T " " $0 }'
T="[ERROR] " awk '{ print ENVIRON["T"] $0 }'ouT="[ERROR]" awk '{ print ENVIRON["T"] " " $0 }'
cmd | awk '{print "['$V]' " $0}'- elle doit être évaluée une fois au début, donc pas de surcharge de performances.
Avec tout le mérite de @grawity, je soumets son commentaire comme réponse, car il me semble que cette réponse est la meilleure.
sed 's/^/[ERROR] /' cmd
awkone-liner est assez sympa, mais je pense que plus de gens connaissent sedque awk. Le script bash est bon pour ce qu'il fait, mais il semble qu'il réponde à une question qui n'a pas été posée.
sed X cmdlit cmdet ne l'exécute pas. Ou cmd | sed 's/^/[ERROR] /'ou sed 's/^/[ERROR] /' <(cmd)ou cmd > >(sed 's/^/[ERROR] /'). Mais méfiez-vous de ce dernier. Même que cela vous permet d'accéder à la valeur de retour de cmdla sedfonctionne en arrière - plan, il est donc probable que vous voyez la sortie après cmd terminé. Bon pour vous connecter à un fichier, cependant. Et notez que c'est awkprobablement plus rapide que sed.
alias lpad="sed 's/^/ /'". au lieu d'ERREUR, j'insère 4 espaces de début. Maintenant, pour le tour de magie: la ls | lpad | pbcopysortie ls sera préfixée de 4 espaces, ce qui le marque en tant que Markdown pour le code , ce qui signifie que vous collez le presse-papiers ( pbcopy le saisit, sur macs) directement dans StackOverflow ou tout autre contexte de démarquage. Impossible de aliasla awk réponse (le 1er essai) si celui - ci gagne. La while read solution est également alias-mesure, mais je trouve cela sed plus expressif.
J'ai créé un référentiel GitHub pour faire des tests de vitesse.
Le résultat est:
awkc'est le plus rapide. sedest un peu plus lent et perln'est pas beaucoup plus lent que sed. Apparemment, toutes ces langues sont hautement optimisées pour le traitement de texte.kshscript compilé ( shcomp) permet de gagner encore plus de temps de traitement. En revanche, il bashest extrêmement lent comparé aux kshscripts compilés .awkne semble pas en valoir la peine.En revanche, pythonc'est très lent, mais je n'ai pas testé de cas compilé, car ce n'est généralement pas ce que vous feriez dans un tel cas de script.
Les variantes suivantes sont testées:
while read line; do echo "[TEST] $line"; done
while read -r line; do echo "[TEST] $line"; done
while read -r line; do echo "[TEST]" $line; done
while read -r line; do echo "[TEST]" "$line"; done
sed 's/^/[TEST] /'
awk '{ print "[TEST] " $0 }'
awk -vT="[TEST] " '{ print T $0 }'
awk -vT="[TEST]" '{ print T " " $0 }'
awk -vT="[TEST]" 'BEGIN { T=T " "; } { print T $0 }'
T="[TEST] " awk '{ print ENVIRON["T"] $0 }'
T="[TEST]" awk '{ print ENVIRON["T"] " " $0 }'
T="[TEST]" awk 'BEGIN { T=ENVIRON["T"] " " } { print T $0 }'
perl -ne 'print "[TEST] $_"'
Deux variantes binaires de l'un de mes outils (la vitesse n'est toutefois pas optimisée):
./unbuffered.dynamic -cp'[TEST] ' -q ''
./unbuffered.static -cp'[TEST] ' -q ''
Python tamponné:
python -uSc 'import sys
for line in sys.stdin: print "[TEST]",line,'
Et Python sans tampon:
python -uSc 'import sys
while 1:
line = sys.stdin.readline()
if not line: break
print "[TEST]",line,'
awk -v T="[TEST %Y%m%d-%H%M%S] " '{ print strftime(T) $0 }'pour émettre un horodatage
Je voulais une solution qui gère stdout et stderr, alors je l'ai écrite prepend.shet mise sur mon chemin:
#!/bin/bash
prepend_lines(){
local prepended=$1
while read line; do
echo "$prepended" "$line"
done
}
tag=$1
shift
"$@" > >(prepend_lines "$tag") 2> >(prepend_lines "$tag" 1>&2)
Maintenant, je peux juste exécuter prepend.sh "[ERROR]" cmd ..., pour ajouter "[ERREUR]" à la sortie de cmd, et toujours avoir stderr et stdout séparés.
>(sous-coques que je ne pouvais pas tout à fait résoudre. Il semblait que le script se terminait et que la sortie arrivait au terminal après le retour de l'invite, ce qui était un peu brouillon. J'ai finalement trouvé la réponse ici stackoverflow.com/a/25948606/409638