it-swarm-eu.dev

Commande pour ajouter une chaîne à chaque ligne?

Vous cherchez quelque chose comme ça? Des idées?

cmd | prepend "[ERRORS] "

[ERROR] line1 text
[ERROR] line2 text
[ERROR] line3 text
... etc
37
user14645
cmd | while read line; do echo "[ERROR] $line"; done

a l'avantage d'utiliser uniquement les commandes bash, donc moins de processus seront créés/détruits, ce qui devrait être un peu plus rapide que awk ou sed.

@tzrik souligne qu'il pourrait également faire une fonction Nice bash. Le définir comme:

function prepend() { while read line; do echo "${1}${line}"; done; }

permettrait de l'utiliser comme:

cmd | prepend "[ERROR] "
40
pjz

Essaye ça:

cmd | awk '{print "[ERROR] " $0}'

À votre santé

46
Ilya Zakreuski

Avec tout le crédit dû à @grawity, je soumets son commentaire comme réponse, car il me semble que la meilleure réponse ici.

sed 's/^/[ERROR] /' cmd
13
Eric Wilson

J'ai créé un référentiel GitHub pour faire des tests de vitesse.

Le résultat est:

  • Dans le cas général, awk est le plus rapide. sed est un peu plus lent et Perl n'est pas beaucoup plus lent que sed. Apparemment, toutes ces langues sont hautement optimisées pour le traitement de texte.
  • Dans des situations très spéciales, où les fourches dominent, l'exécution de votre script en tant que script ksh compilé (shcomp) peut économiser encore plus de temps de traitement. En revanche, bash est très lent par rapport aux scripts ksh compilés.
  • Créer un binaire lié statiquement pour battre awk ne vaut pas la peine.

En revanche, python 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 d'un de mes outils (il n'est cependant pas optimisé pour la vitesse):

./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,'
8
Tino
cmd | sed 's/.*/[ERROR] &/'

Je voulais une solution qui gère stdout et stderr, j'ai donc écrit prepend.sh et le mettre sur mon chemin:

#!/bin/bash

prepend_lines(){
  local prepended=$1
  while read line; do
    echo "$prepended" "$line"
  done
}

tag=$1

shift

"[email protected]" > >(prepend_lines "$tag") 2> >(prepend_lines "$tag" 1>&2)

Maintenant, je peux simplement exécuter prepend.sh "[ERROR]" cmd ..., pour ajouter "[ERREUR]" à la sortie de cmd, et avoir toujours stderr et stdout séparés.

4
Aprotim
cmd | xargs -l 1 -i echo "prefix{}"

ou encore plus facile dans le cas où prefix est délimité par des espaces à partir de la ligne elle-même

cmd | xargs -l 1 echo prefix

Ce n'est pas très efficace en termes de performances, mais court à écrire.

Cela fonctionne en exécutant echo une fois par ligne d'entrée. xargs vous permet également de traiter \0- lignes délimitées.

0
scorpp