2016-03-22 37 views
4

Sortable bir zaman dilimi ile öntanımlı iki günlük dosyasına sahibim. Sırasıyla, günlük dosyalarını oluşturan işlemler çalışırken, onları görmek istiyorum. Bu durumun oldukça sadık simülasyon olduğunu:, en az arabelleğe alma ile sıralanmış dosyaları birleştirir

slow() { 
    # print stdout at 30bps 
    exec pv -qL 30 
} 
timestamp() { 
    # prefix stdin with a sortable timestamp 
    exec tai64n 
} 

# Simulate two slowly-running batch jobs: 
seq 000 099 | slow | timestamp > seq.1 & 
seq1=$! 
seq 100 199 | slow | timestamp > seq.2 & 
seq2=$! 

# I'd like to see the combined output of those two logs, in timestamp-sorted order 
try1() { 
    # this shows me the output as soon as it's available, 
    # but it's badly interleaved and not necessarily in order 
    tail -f seq.1 --pid=$seq1 & 
    tail -f seq.2 --pid=$seq2 & 
} 
try2() { 
    # this gives the correct output, 
    # but outputs nothing till both jobs have stopped 
    sort -sm <(tail -f seq.1 --pid=$seq1) <(tail -f seq.2 --pid=$seq2) 
} 


try2 
wait 
+0

Ah, zaten her iki iş duruncaya kadar hiçbir şey söylemediniz. Eğer y, x, w, a, b, c, z' gibi verileriniz varsa, doğru siparişi almak için hepsini okumalısınız. Çok yakın veriler için, zaman damgalarınız olduğu için, bir arabellek sistemi oluşturabilirsin, ama yikes! Bu arada harika Q! İyi şanslar! – shellter

+2

"Şunlar" içinde arabelleklenmesi kesinlikle mümkün olmalıdır, böylece gerçek zamanlı olarak sıralanmış günlük çıktıları elde edebilirsiniz (çıktılar bir dakika veya bir kez kaydedilir) ama bunun için bir pencere seçmeniz gerekecek ve günlükleriniz dökülecektir. toplu olarak. –

+0

İki akış zaten sıralanmıştır, bu nedenle bir sistem her bir akıştan yalnızca bir satır arabelleğe gereksinim duyar. Bu noktada, ikisinin daha azını basabilir ve yine de iyi sıralanmış çıktıyı garanti edebilir. Bunu python'da yazabilirim, ama zaten icat edilmiş bir yardımcı programı umuyorum. Ben aslında 'sort -m' bu şekilde çalışması gerektiğini düşünüyorum ... – bukzor

cevap

0

solution using tee (standart çıktı hala konsola gider böylece dosyaları yazmak için) tee istenmeyen gecikme tanıtır ve çözmez çünkü işe yaramaz sorun. Benzer şekilde, tail -f -s 0.01'u kullanarak (100/s için yoklamayı değiştiren) ve/veya küçük gruplar halinde sıralamak için split --filter='sort -sm' gibi bir çağrı yapamadım.

benim test kodu aslında bu işlevsel özdeş perl kodu kullanılan bu yüzden de, tai64n yok :

: sh ve bash ile bu çözmek için başarısız olduktan sonra

tai64n() { 
    perl -MTime::HiRes=time -pe ' 
    printf "\@4%015x%x%n", split(/\./,time), $c; print 0 x(25-$c) . " "' 
} 

, benim standart yük devretmeyi perl icra

slow() { 
    # print stdout at 30bps 
    pv -qL 30 
} 

tai64n_and_tee() { 
    # prefix stdin with a sortable timestamp and copy to given file 
    perl -MTime::HiRes=time -e ' 
    $_ = shift; 
    open(TEE, "> $_") or die $!; 
    while (<>) { 
     $_ = sprintf("\@4%015x%x%n", split(/\./,time), $c) . 0 x(25-$c) . " $_"; 
     print TEE $_; 
     print $_; 
    } 
    ' "$1" 
} 

# Simulate two slowly-running batch jobs: 
seq 000 099 | slow | tai64n_and_tee seq.1 & 
seq 100 199 | slow | tai64n_and_tee seq.2 & 
wait 

Bu benim için uygun çünkü zaman damgası için zaten perl kullanıyordum. Bunu, tai64n olarak hareket eden perl ve tee olarak hareket etmek için ayrı bir perl çağrısı ile başarısız oldu, ancak gerçek tai64n ile çalışabilir.

+0

Eğer 'tai64n' için perl'unu kullanırsam, işlemler bitene kadar çıktı almaz ve çıktı sıralanmaz. – bukzor

+0

Bunun yerine, yukarıdaki bash betiğinizle 'tai64n' kullanacaksam, çıktı hatalı şekilde serpiştirilmiş; bazı satırlarda iki zaman damgası bulunur, bazılarında hiç yoktur. – bukzor

+0

Tamam, aslında yayınlamadan önce testlerimde 'tee 'demedim. Sorununu görüyorum ve cevabı tekrar yazdım. Aynı döngüde, bu perl kodu, her bir günlük dosyasına _and_ kopyalarını ekler. Ben 'tee' gerçek bir 'tai64n' ile çalışacak bir perl yaklaşımı (muhtemelen aynı neden gerçek 'tee 'burada işe yaramaz, ben anlıyorum ...) –