Yanıtlar:
cmd | while read line; do echo "[ERROR] $line"; done
yalnızca bash yerleşiklerini kullanma avantajına sahiptir, bu yüzden daha az işlem yaratılır / yok edilir, bu nedenle awk veya sed'den daha hızlı bir dokunuş olmalıdır .
@tzrik, aynı zamanda hoş bir bash işlevi yaratabileceğinin altını çiziyor. Gibi tanımlanması:
function prepend() { while read line; do echo "${1}${line}"; done; }
gibi kullanılmasına izin verirdi:
cmd | prepend "[ERROR] "
sed
) veya string awk
function prepend() { while read line; do echo "${1}${line}"; done; }
Bunu dene:
cmd | awk '{print "[ERROR] " $0}'
Şerefe
awk -vT="[ERROR] " '{ print T $0 }'
veyaawk -vT="[ERROR]" '{ print T " " $0 }'
T="[ERROR] " awk '{ print ENVIRON["T"] $0 }'
veyaT="[ERROR]" awk '{ print ENVIRON["T"] " " $0 }'
cmd | awk '{print "['$V]' " $0}'
serbest bırakmak için tırnak işaretlerinin kapsamından çıkabilirsiniz: - bu başlangıçta bir kez değerlendirilmelidir, bu nedenle performans ek yükü yoktur.
@Grawity'ye verdiğim tüm krediyle, yorumunu burada bana en iyi cevap olarak göründüğü gibi, bir cevap olarak gönderiyorum.
sed 's/^/[ERROR] /' cmd
awk
astar yeterince güzel, ama bence daha çok insanın aşina sed
olduğu awk
. Bash betiği ne yaptığı için iyidir, ancak sorulmamış bir soruyu cevaplıyor gibi görünüyor.
sed X cmd
okur cmd
ve yürütmez. Ya cmd | sed 's/^/[ERROR] /'
da sed 's/^/[ERROR] /' <(cmd)
ya da cmd > >(sed 's/^/[ERROR] /')
. Ancak ikincisine dikkat edin. Bu dönüş değerini erişmeye olanak Hatta bu büyük olasılıkla size çıktı görmeleri için, arka planda çalışır sonra bitmiş cmd. Yine de bir dosyaya giriş yapmak için iyi. Ve muhtemelen daha hızlı olduğunu unutmayın . cmd
sed
awk
sed
alias lpad="sed 's/^/ /'"
. ERROR yerine 4 tane öncü boşluk ekliyorum. Şimdi, sihir numarası için: ls | lpad | pbcopy
ls çıktısını kod için Markdown olarak işaretleyen 4 boşlukla hazırlayacak , yani panoyu ( pbcopy mac'lardan tutuyor) doğrudan StackOverflow veya başka bir markdown bağlamına yapıştıracağınız anlamına gelecek . Olabilir değil awk bu bir galibiyet böylece (1 denemede) cevap. İse okuma çözüm ayrıca takma-yapabiliyor, ama bunu buldum sed daha etkileyici. alias
Bazı hız testleri yapmak için bir GitHub deposu oluşturdum .
Sonuç:
awk
en hızlıdır. sed
biraz daha yavaş ve biraz daha perl
yavaş değil sed
. Görünüşe göre, hepsi bu metin işleme için son derece optimize edilmiş dillerdir.ksh
komut dosyası ( shcomp
) olarak çalıştırmak daha fazla işlem süresi kazandırabilir. Buna karşılık, bash
derlenmiş ksh
komut dosyalarına göre daha yavaş .awk
çabaya değmez gibi görünüyor.Aksine python
, yavaş yavaş, ama derlenmiş bir olayı test etmedim, çünkü genellikle böyle bir senaryo durumunda yapabileceğin bir şey değil.
Aşağıdaki değişkenler test edilmiştir:
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] $_"'
Araçlarımdan birinin iki ikili varyantı (hıza rağmen iyimser değil):
./unbuffered.dynamic -cp'[TEST] ' -q ''
./unbuffered.static -cp'[TEST] ' -q ''
Tamponlu Python:
python -uSc 'import sys
for line in sys.stdin: print "[TEST]",line,'
Ve Python arabelleksiz:
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 }'
bir zaman damgası
Stdout ve stderr'ı kullanan bir çözüm istedim, bu yüzden yazıp prepend.sh
yoluma koydum:
#!/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)
Artık prepend.sh "[ERROR]" cmd ...
"[ERROR]" ifadesini çıktıya hazırlamak için koşabilirim cmd
, ve hala stderr ve stdout'u ayrı tuttum.
>(
deniz kabukları üzerinde tam olarak çözemediğim bir şey oldu. Senaryo tamamlanmış gibi gözüküyordu ve komut istemi geri döndükten sonra terminale geliyordu ki bu biraz karışıktı. Sonunda burada cevap geldi stackoverflow.com/a/25948606/409638