Birden çok unix komutunu tek bir çıktıda birleştirin


9

Posta günlüklerimizde belirli bir e-posta adresini aramam gerekiyor. Maillog adlı geçerli bir dosyayı ve bir haftalık .bz2 dosyalarını aynı klasörde tutuyoruz . Şu anda, dosyayı aramak için aşağıdaki komutları çalıştırıyorum:

grep person@domain.com maillog
bzgrep person@domain.com *.bz2

grepVe bzgrepkomutlarını tek bir çıktıda birleştirmenin bir yolu var mı ? Bu şekilde, birleştirilmiş sonuçları tek bir e-postaya veya tek bir dosyaya bağlayabilirim.

Yanıtlar:


24

Başka bir yol

{ grep ...; bzgrep ...;} >file

&&başarısız bzgrepolursa çalıştırılmayacak güçlüğü vardır grep.

Son komuttan sonra açılan küme ayracı ve noktalı virgülden sonra zorunlu boşluğa dikkat edin. Alternatif olarak, seçici olmayan alt kabuk sözdizimini (kıvırcık parantez yerine parantez) kullanabilirsiniz:

(grep ...; bzgrep ...) >file

Bu konuya en iyi genel amaçlı kabuk yaklaşımı için +1. Kabuk gruplaması genellikle az kullanılan bir özelliktir.
Phil Hollenback

2
Bunun ()yerine demek istemedin {}mi?
Ehtesh Choudhury

Arch linux üzerinde bu ile çalıştı ()ama değil {}, her iki şekilde +1 olarak bu ihtiyacım olan şey!
Chris Magnuson

11

Bir dosya bzip sıkıştırılmadığında bzgrep otomatik olarak normal grep değerini alır. Bu nedenle aşağıdakiler yeterli olmalıdır:

bzgrep person@domain.com maillog *bz2 | mail -s "logs yay" someuser@blah

oh ayrıca tabii ki benim de zorunlu GNU Paralel çözümüm:

parallel -m bzgrep person@domain.com ::: maillog* *bz2 | mail -s "logs yay" someuser@blah

çok fazla dosya kontrol ediyorsanız çok daha hızlı olabilir.


2

İşte bunu yapmanın başka bir yolu (muhtemelen bash çalıştırdığınız varsayılarak):

cat <(bzgrep ...) <(grep ...)

Burada bash, bzgrep ve grep komutlarının çıktısını, sanki dosyaymış gibi kediye besliyor (ve bir tür başlık altında, altta url'deki ayrıntılar).

Özel durumunuzda Phil'in çözümünü öneriyorum, ancak yukarıdaki çantanızda tutmak için iyi bir numara.

İlgileniyorsanız, buradan daha fazla bilgi edinebilirsiniz: http://www.tldp.org/LDP/abs/html/process-sub.html


Ah evet, 'iki sürecin çıktısını nasıl farklılaştırıyorsunuz? Bilmek iyi bir numara.
Phil Hollenback

1

Bunu yazarken, kabul edilen yanıtın sözdizimi, hepsi olmasa da, Bourne'den türetilen mermiler de dahil olmak üzere çoğu için yanlıştı bash. En üste bir düzenleme önerdim ve bunu düzeltmek için cevabı kabul ettim, ancak diğer tüm bilgileri de eklemeye meyilli oldum ve bu daha çok bir düzenleme yerine bir yeniden yazma olurdu.

Bileşik komutları kullanabilirsiniz:

{ grep ...; bzgrep ...; } >file

..veya alt kabuklar (süslü parantez yerine parantezlere dikkat edin):

(grep ...; bzgrep ...) >file

.. komutları gruplandırmak için. Alt kabuk yolu daha güzel bir sözdizimine sahiptir (beyaz boşluk eksikliğini daha affedicidir ve son noktalı virgülü atlamanızı sağlar), ancak ya yeni bir işlem ister ya da komutların temizlenmiş bir ortamda çalışmasını "taklit eder". Her ikisinin de ne yapmak istediğinize bağlı olarak avantajları var, bu da burada önemli değil, ancak kabukta daha fazla yeterlilik istiyorsanız, aramaya değer.

Not: Boru hattını bu hilelerle de kullanabilirsiniz, böylece böyle bir şey yapabilirsiniz:

{ grep ...; bzgrep ...; } | less

Eğer kombine çıktıda maçların sipariş umurumda değil eğer PS, tek kullanabilirsiniz &şöyle iki komut arasındaki: { grep ... & bzgrep ...; }. Sonra iki komut aynı anda çalışır: grepBaşlatılır ve kabuk onu arka plana koyar, sonra kabuk çalışacaktır bzgrep. (Ancak, dosya yönlendirmesi ve dosya akışı arabelleğe almayı içeren küçük bir uyarı var, potansiyel olarak çıktı dosyasındaki satırların çok küçük bir bölümünün bölünmesine / yönetilmesine neden oluyor: bunun grep, bzgrepve libc stdio.hfonksiyonları uygulanmaktadır. en uygulamalarda, sana yapabileceğini, böylece sorunu önlemek olacaktır bir dosyaya yeniden yönlendirmeden önce komutunu boru inanmak { foo & bar; } | cat - >filegeçici bir çözüm olarak.)


0

Komutları && ile birleştirerek her komutu çalıştırmanıza izin verebilirsiniz.

ayrıca her komutun sonuna >> textfile.txt ekleyebilir ve çıktının bir dosyaya çarpıp sonra bu dosyayı postalamasını sağlayabilirsiniz.


2
Geekosaur'un belirttiği gibi, && burada kullanılmamalıdır çünkü grep'in dönüş değeri bir şey bulup bulmamasına bağlıdır. Eğer yaptıysanız grep ... && bzgrep ..., grep'in isabeti yoksa, başarısızlık döndürür ve komut durur. >>iyi bir fikir olsa da, >mevcut dosyanın sonuna çıktı ekleyecektir.
DerfK

sağdaki ikinci komutu engelleyen çıkış koşulunu unutmuştum.
Mike
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.