Bir komutun çıktısını birden fazla komuta nasıl iletirim?


20

Proses ikame kullanımı veya gruplama ve borulama yöntemiyle, biri çıktı ( stdout ) komutunu başka bir komutun girişi olarak geçirebilir .

Örnek :

wc < <(echo hi;echo bye)
(echo hi; bye) | wc

Ama tam tersi var mı?

Diğer bir deyişle, bir komutun çıktısını, diğer birçok komutun girişi için tek bir satırda göndermenin bir yolu var mı ?

Gibi bir şey :

cat testfile | wc | tail -n 5

( Kelimenin tam anlamıyla boru hatları almayın ). Burada cat testfileikisinin de çıktısını almaya çalışıyorum wcvetail -n 5

Başka bir örnek şöyle olabilir:

( bir cümlenin son sözünü almak için )

echo "some random words"| wc -c | cut -f(out put of wc -c) (output of first echo)

Yanıtlar:


21

Hızlı cevap. Yapmak tee >(what_to_do) >(another_thing_to_do)istediğiniz birçok farklı şey için emrinize devam etmek için kullanabilirsiniz .

Örnek:

Orijinal test dosyası çıktısı:

:~$ cat testfile.txt 
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616

teeEklenen komutlarla çıktı :

:~$ cat testfile.txt | tee >(tail -1) >(wc) >(awk '{print $3,$1,$2}')
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616
LITEONIT Device Model:
TW0XFJWX550854187616 Serial Number:
      2      10      91
Serial Number:    TW0XFJWX550854187616

Tee'daki her komut, komut satırında kullanacağınız normal komutlardır, tıpkı eklentilerde olduğu >(head -1 | wc)gibi.

:~$ cat testfile.txt | tee >(tail -1) >(head -1 | wc)  >(awk '{print $3,$1,$2}')
Device Model:     LITEONIT LCS-256M6S 2.5 7mm 256GB
Serial Number:    TW0XFJWX550854187616
      1       7      52
LITEONIT Device Model:
TW0XFJWX550854187616 Serial Number:
Serial Number:    TW0XFJWX550854187616

Ya da kullanarak son satırı söylemek son kelimeyi yakala awkile $NFbir ile wcde böyle:

:~$ cat testfile.txt | tail -1 | tee >(wc) >(awk '{print $NF}')
Serial Number:    TW0XFJWX550854187616
TW0XFJWX550854187616
      1       3      39

NOT:| Sonuna bir boru komutu eklemek , komuttaki çoklu komutları kullanarak geçersiz kılabilir tee. Burada test ettiğim bazı örnekler var:

Örnek 1 (Tüm son kelimeleri çeken boru komutu):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) | awk '{print $NF}'
words
24
5
1

Örnek 2 (wc komutlarının çıktısını göstermez. 3. kelimeyi kaplayan boru komutu.):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) | awk '{print $3}'
just

Örnek 3 (Echo satırının 3. kelimesini kapma. Tee komutu.):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) >(awk '{print $3}')
This is just five words
just
24
5
1

Örnek 4 (Yankı çizgisinin son sözcüğünü kapma. Tee komutu.):

:~$ echo "This is just five words" | tee >(wc -l) >(wc -w) >(wc -c) >(awk '{print $NF}')
This is just five words
words
24
5
1

Bu yardımcı olur umarım!


3
Çay ve kahve severim! '-)
Elder Geek

1
Çeşitli tüketiciler arasında çıktının sıralanması ile ilgili açıklama teeyanlıştır. Genellikle doğru siparişi almanızın nedeni, düşük yük makinelerinde ilk tüketici işleminin önce başlamasıdır. Daha yoğun bir makinede, ilk tüketici herhangi bir şeyi basmadan önce uykuya dalmış olabilir.
Matei David,

@MateiDavid Aksini ispat edemem, bu yüzden ifadeyi kaldırdım. Hayır biggie.
Terrance

2
Cevabımı gör. Fakat daha da ciddisi, teetüketiciler hakkında hiçbir fikre sahip değiller - bashçizgiyi işleyen tarafından yaratılıyorlar . Bütün bunlar bashaçık dosya tanımlayıcılarını kopyalamak. Bunun ötesinde, aynı dosyada açılmış olan dosya tanımlayıcılarına yazan birkaç tüketiciniz var. Çekirdek bununla ilgilenir, ancak kesinlikle bashkomut satırında göründüğü sıra, bir faktör olmayacaktır.
Matei David,

17

teeAkışı parçalara bölmeniz gerekir . Deneyin:

cat testfile | tee >(wc -l) >(wc -w) >(wc -c) | tail -n 5

Notlar:

  • Birden fazla işlem ( wc, tail) hepsi stdout'a yazıyorsa:

    • Bozuk çıktı alabilirsiniz.

    • Çıkışlarının görüneceği sipariş hakkında hiçbir garanti yoktur. Bunu görmek sleep 1; wc -wiçin ikinci tüketici olarak deneyin .

  • teeHedeflerinden herhangi biri akımı yeterince hızlı tüketmediğinde engeller. Yani, varış yerleri kabaca benzer hızda girdi beslenecek (sabit boyutlu tamponlama modulo). Bunun için kolay bir düzeltme yoktur, tek alternatif akışı bir dosyaya kaydetmek ve bunları tüketicilere ayrı ayrı beslemektir. İçin wcve tailbu bir sorun değildir.

Son söz için, yapmak daha kolaydır:

echo "some random words" | awk '{print $NF}'

5

moreutilsPaket komutları sağlayan peetam olarak bunu yapıyor (siz düşündünüz neyi boru ve tişörtü birleştirme,?).

İlk örneğiniz için kullanacaksınız:

cat testfile | pee wc "tail -n 5"

İkinci örnek daha karmaşıktır, çünkü iki girdiyi son komuta geçirmek istiyorsunuz. Muhtemelen awkdiğer cevaplar olarak kullanırdım .

Bağlantı: https://joeyh.name/code/moreutils/

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.