Bash aynı ikilik iki ayrı komuttan tüketebilir mi?


5

Bazı greps kullanarak filtrelemek büyük bir veri kaynağım var .

İşte temelde şu anda ne yapıyorum:

#!/bin/bash
param1='something'
param2='another'
param3='yep'
echo $(avro-read /log/huge_data | grep $param1 | grep "$param2-" | grep $param3 | wc -l) / $(avro-read /log/ap/huge_data | grep $param1 | grep -v "$param2-" | grep $param3 | wc -l) | bc -l

Çoğunlukla aynı filtrelemeyi (ikinci seferde tek bir fark) yaptığımı, her birinin sayımını ve nihai sonucu böldüğüme dikkat edin. Bu kesinlikle yapmak çok zor bir şey ama biraz denemek ve hızlandırmak ve geçici bir dosya kullanmadan sadece ilk filtrelemeyi yapmak istiyorum.

Bir beşlik kullanmayı denedim, ancak bir komut dosyasında iki işlemin ondan okuma yapmasının mümkün olup olmadığından emin değilim ve her ikisi de nihai sonucu hesaplamak için yapılana kadar üçüncü bir "bekle" işlemine sahip oldum. Ayrıca kullanmaya başladım tee, ancak yine de ortaya çıkan alt işlemlerin nasıl senkronize edileceğinden emin değilim.

EDIT: https://superuser.com/a/561248/43649 adresini kullanarak bunu kendim çözdüm , ancak cevap olarak başka bir öneri olarak işaretledim.


Hayır; Bir işlem bir işlemden önce verileri okuduğunda, bu veriler gider ve diğer işlem tarafından görülmez.
chepner

Yanıtlar:


2

Eğer sadece geçici dosyalar oluşturmaktan kaçınmak istiyorsanız (veya grep çıktısını bir değişkende saklamak istiyorsanız), aşağıdaki gibi bir for döngüsüne besleyebilirsiniz:

#!/bin/bash

IFS=$'\n'
yay=0
nay=0

for line in `avro-read /log/huge_data | grep $param1 | grep $param3`; do
    [[ $line =~ $param2- ]] && yay=$(($yay + 1)) || nay=$(($nay + 1))
done

echo $yay / $nay \* 100 | bc -l

unset IFS

Yaklaşımın değiştirilmiş bir versiyonunu kendi cevabınızda , geçici dosyalar gerektirmeyen değiştirdim:

#!/bin/bash

(avro-read /log/huge_data | grep $param1 | grep $param3 | tee \
     >(echo yay=`grep -c "$param2-"`) \
     >(echo nay=`grep -vc "$param2-"`) \
     >/dev/null | cat ; echo 'echo $yay / $nay \* 100 | bc -l') | sh

Bireysel grep -ckomutların çıktısı ve echokomut şu şekilde yazdırılır:

yay=123
nay=456
echo $yay / $nay \* 100 | bc -l

yarış koşullarından kaçınmak için 1 . shYazdırılan komutları çalıştırmak için borulama .

1 Hangi grep -ckomut ilk önce biterse , ilk çıktı satırını yazdıracaktır.


Veriler arasında dolaşmanın süper harika yolu.
Andrew

Harika - bu, süreç değişimlerinin değerlerini elde etmek için bir "hatırlama ihtiyacı" hilesi :)
mpy

Vaov! Bunu yapmanın süper serin yolu. Cevabımı uyarladığın için teşekkürler! Bundan öğrenilecek kesinlikle çok şey var.
Andrew,

1

Bu şekilde çözmeyi bitirdim:

#!/bin/bash
param1='something'
param2='another'
param3='yep'

avro-read /log/huge_data | grep $param1 | grep $param3 \
| tee \
>(grep "$param2-" | wc -l | tr -d '\n' > has_count) \
>(grep -v "$param2-" | wc -l | tr -d '\n' > not_count) \
> /dev/null

echo $(cat has_count | tr -d '\n') '/' $(cat not_count | tr -d 'n') '* 100' | bc -l

Bu yüzden, bir beşlik veya geçici dosyaya dayanmak yerine tee, akımı yalnızca bir sayı veren iki ayrı işleme ayırırdım! Bu şekilde, sayıları bölmeye çalışmadan önce iki işlemi senkronize etmeye çalışmam gerekmiyor.


İki geçici dosya kullanıyorsunuz ...
mpy

Çok ilginç! Cevabınıza, geçici dosyalar gerektirmeyen yaklaşımınızda bir değişiklik yaptım.
Dennis

Bu durumda "geçici bir dosyaya güvenmemek" derken, gerçek verilerle dolu bir geçici dosya demek istedim. Bu durumda, sadece bir numara saklıyor.
Andrew,

0

Hm, zshMULTIOS adlı bir özelliğe sahiptir. Böylece bir işlemi iki el ile bağlamak mümkündür. Buradaki bir seçenek küçük bir demo ise:

#!/bin/zsh -f

setopt multios

mkfifo f1 f2 2> /dev/null

param1='something'
param2='another'
param3='yep'

{ avro-read /log/huge_data | grep $param1 | grep $param3 } > f1 > f2 &

( cat f1 | grep $param2 | wc -l > value1 ) &!
value2=$(cat f2 | grep -v $param2 | wc -l)

print $(( 1. * $( cat value1 ) / $value2 ))

rm value1

Bununla birlikte, value1Dennis'in belirttiği gibi muhtemelen kaçınılması gereken geçici dosyanın oluşturulmasında dolaşmanın bir yolunu bulamadım . Ama yine de bu çözümü seveceksiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.