Sebebi ise
tac file | grep foo | head -n 1
İlk maçta durmuyor tamponlama yüzünden.
Normalde, head -n 1
bir satırı okuduktan sonra çıkar. Öyleyse grep
bir SIGPIPE almalı ve ikinci satırını yazdığı anda çıkmalıdır.
Ancak olan şu ki, çıktı bir terminale gitmiyor çünkü grep
onu tamponlar. Yani, yeterince birikene kadar yazmıyor (GNU grep testimde 4096 bayt).
Bunun anlamı, grep
8192 bayt veri yazmadan önce çıkamayacağı, yani muhtemelen birkaç satır.
GNU ile grep
, --line-buffered
bir terminale gidip gitmediğine bakılmaksızın, bulunup bulunmadıkça satır yazmasını söyleyen kullanarak daha erken çıkmasını sağlayabilirsiniz . Öyleyse grep
bulduğu ikinci hatta çıkacaktır.
Ancak grep
yine de GNU ile , -m 1
@terdon'un gösterdiği gibi kullanabilirsiniz , bu ilk maçta çıktıkça daha iyidir.
Sizin grep
GNU'nuz değilse, grep
kullanabilirsiniz sed
veya awk
yerine. Ama tac
bir GNU komutuyla olmak, sana bir sistem bulacaksınız şüphe tac
nerede grep
GNU değildir grep
.
tac file | sed "/$pattern/!d;q" # BRE
tac file | P=$pattern awk '$0 ~ ENVIRON["P"] {print; exit}' # ERE
Bazı sistemler tail -r
GNU ile aynı şeyi yapmak zorundadır tac
.
Düzenli (aranabilir) dosyalar için tac
ve tail -r
verimli olduklarını ve dosyaları geriye doğru okudukları için verimli olduklarını unutmayın, yalnızca geriye doğru yazdırmadan önce dosyayı tam olarak okuyamazlar ( @ slm'nin sed yaklaşımı veya tac
normal olmayan dosyalarda olduğu gibi) .
Kullanılamadığı tac
veya bulunmadığı sistemlerde tail -r
, tek seçenek geriye dönük okumayı aşağıdaki gibi programlama dilleri ile elle perl
uygulamaktır:
grep -e "$pattern" file | tail -n1
Veya:
sed "/$pattern/h;$!d;g" file
Ancak bu, tüm eşleşmeleri bulmak ve yalnızca sonuncuyu yazdırmak anlamına geliyor.