İki farklı komuttan tek komuta nasıl birleştirme ve borulama yapılır?


34

İki farklı komuttan birleştirme (birleştirme) çıktısı almak ve bunları tek bir komuta göndermek istiyorum.

Aptal bir örnek:

Komutlar Çıktıyı birleştirmek istiyorum:

cat wordlist.txt
ls ~/folder/*

içine:

wc -l

Bu örnekte, wordlist.txt 5 satır ve 3 dosya içeriyorsa, wc -l8 döndürmek istiyorum .

$cat wordlist.txt *[magical union thing]* ls ~/folder/* | wc -l
8

Bunu nasıl yaparım?

Yanıtlar:


55

Sizin büyülü sendika şey noktalı virgül ... ve küme parantezleri geçerli:

    { cat wordlist.txt ; ls ~/folder/* ; } | wc -l

Kıvrımlı parantezler sadece komutları birlikte gruplandırır, böylece boru işareti |kombine çıktıyı etkiler.

Ayrıca ()komutları bir alt kabukta yürüten komut grubu etrafındaki parantezleri de kullanabilirsiniz . Bu kıvrık parantez ile ince bir farklar kümesi vardır, örneğin aşağıdakileri deneyin:

    cd $HOME/Desktop ; (cd $HOME ; pwd) ; pwd
    cd $HOME/Desktop ; { cd $HOME ; pwd ; } ; pwd

Geçerli çalışma dizini de dahil olmak üzere tüm ortam değişkenlerinin parantez grubundan çıktıktan sonra sıfırlandığını göreceksiniz, ancak küme parantez grubundan çıktıktan sonra değil.

Noktalı virgül gelince, alternatifler arasında ikinci komutu yalnızca sırasıyla ilk başarılı olduğunda veya değilse, koşullu olarak uygulayacak olan &&ve ||işaretleri bulunur;

    cd $HOME/project && make
    ls $HOME/project || echo "Directory not found."

1
Bu işe yarıyor! Öğrenmeme yardım et - kıvırcık ayraçlar burada tam olarak ne yapıyor? Başka hangi sihirli güçlere sahipler?
David Oneill

@DavidOneill { list; }bir bileşik komuttur . Kimden bash(1): list sadece geçerli kabuk ortamında yürütülür. liste bir yeni satır veya noktalı virgül ile sonlandırılmalıdır. [..] Dönüş durumu listenin çıkış durumudur.
Lekensteyn

Cevabına biraz daha bilgi ekledim. Bash ile kabuk komut dosyası için kesin kılavuz, bash manpage, man bashkomut satırından yazıp taramak.
pablomme

gerekirse ; Bu komutlarda & & quot; wordlist.txt dosyası bulunmuyorsa diye & değil mi?
Rinzwind

Eğer wordlist.txtyoksa bir hata catstandart hatada görünecek, ancak standart çıktıda görünmeyecek, wc -londan hiçbir satır saymayacak. Aynısı ~/foldermevcut değil için de geçerli. Biri 2> /dev/nullstandart komutta gürültüyü önlemek için bu komutların her biri ile noktalı virgül arasına ekleyebilir , ancak çirkin olmaktan başka, hata mesajları satırları saymak amacıyla zararsızdır.
pablomme

8

Yana wcgirdi olarak bir dosya yolu kabul, ayrıca süreç ikame kullanabilirsiniz:

wc -l <(cat wordlist.txt; ls ~/folder/*)

Bu kabaca eşdeğerdir:

echo wordlist.txt > temp
ls ~/folder/* >> temp
wc -l temp

Akıl ls ~/folder/*ayrıca alt dizinleri içeriğini gönderir (nedeniyle Glob esneme) alınırlar. Sadece içeriğini listelemek istiyorsanız ~/folder, sadece kullanın ls ~/folder.


Bu wc -lsadece hazır bir örnekti, aslında bu seçeneği olmayan daha karmaşık bir şeye boru yapıyorum.
David Oneill

2
@DavidOneill Eh, catbir dosya argümanını kabul ettiği gibi , cat <(cat wordlist.txt; ls wordlist.txt) | wc -lhatta kullanabilirsiniz cat wordlist.txt <(ls wordlist.txt) | wc -l. Bu elbette çok çirkin, ama komut satırı araçlarıyla bitmeyen olasılıkları gösteriyor.
Lekensteyn

1
@DavidOneill Doğru, şimdi düzelttim, teşekkürler.
Lekensteyn

1
Sen istemek ls ~/folder/eğer ki ~/folderbir sembolik bağlantı lshedefine içeriğini yerine bağlantının kendisini listeler. Bu arada, tüm lskomutları takip etmelisiniz -1ki satır başına tek bir dosya yazdırılmalı ve wc -ldosyaları saymak için geçerli bir yol olmalı .
pablomme

@pablomme Sembolik bağlantı konusunda haklısın ama -1çıktı bir terminal değil, bir boru olduğu için ima edildi.
Lekensteyn

2

Aynı soruyu kendime soruyordum ve kısa bir senaryo yazdım.

magicalUnionThing(Ben derim append):

#!/bin/sh
cat /dev/stdin
$*

Bu betiği çalıştırılabilir yap

chmod +x ./magicalUnionThing

Şimdi yapabilirsin

cat wordlist.txt |./magicalUnionThing ls ~/folder/* | wc -l

Bu ne yapar:

  • Standart girdiyi standart çıktıya gönder
  • Argümanı yürütün. $*tüm argümanları dizge olarak döndürür. Bu komutun çıktısı varsayılan olarak standart çıktı komut dosyasına gider.

Bu nedenle, magicalUnionThing öğesinin stdout işlevi, argüman olarak iletilen komutun stdin + stdout değeri olacaktır.

Elbette diğer cevaplara göre daha basit yollar var.
Belki bu alternatif bazı durumlarda faydalı olabilir.

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.