Sebebi ise
tac file | grep foo | head -n 1
İlk maçta durmuyor tamponlama yüzünden.
Normalde, head -n 1bir satırı okuduktan sonra çıkar. Öyleyse grepbir SIGPIPE almalı ve ikinci satırını yazdığı anda çıkmalıdır.
Ancak olan şu ki, çıktı bir terminale gitmiyor çünkü greponu tamponlar. Yani, yeterince birikene kadar yazmıyor (GNU grep testimde 4096 bayt).
Bunun anlamı, grep8192 bayt veri yazmadan önce çıkamayacağı, yani muhtemelen birkaç satır.
GNU ile grep, --line-bufferedbir 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 grepbulduğu ikinci hatta çıkacaktır.
Ancak grepyine de GNU ile , -m 1@terdon'un gösterdiği gibi kullanabilirsiniz , bu ilk maçta çıktıkça daha iyidir.
Sizin grepGNU'nuz değilse, grepkullanabilirsiniz sedveya awkyerine. Ama tac bir GNU komutuyla olmak, sana bir sistem bulacaksınız şüphe tacnerede grepGNU değildir grep.
tac file | sed "/$pattern/!d;q" # BRE
tac file | P=$pattern awk '$0 ~ ENVIRON["P"] {print; exit}' # ERE
Bazı sistemler tail -rGNU ile aynı şeyi yapmak zorundadır tac.
Düzenli (aranabilir) dosyalar için tacve tail -rverimli 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 tacnormal olmayan dosyalarda olduğu gibi) .
Kullanılamadığı tacveya bulunmadığı sistemlerde tail -r, tek seçenek geriye dönük okumayı aşağıdaki gibi programlama dilleri ile elle perluygulamaktı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.