Alasan mengapa
tac file | grep foo | head -n 1
tidak berhenti pada pertandingan pertama adalah karena buffering.
Biasanya, head -n 1keluar setelah membaca satu baris. Jadi grepharus mendapatkan SIGPIPE dan keluar juga segera setelah ia menulis baris kedua.
Tetapi yang terjadi adalah karena outputnya tidak ke terminal, grepbuffer itu. Yaitu, ini tidak menulisnya sampai cukup terakumulasi (4.096 byte dalam pengujian saya dengan GNU grep).
Apa artinya itu adalah bahwa greptidak akan keluar sebelum ia menulis data 8192 byte, jadi mungkin beberapa baris.
Dengan GNU grep, Anda dapat membuatnya keluar lebih cepat dengan menggunakan --line-bufferedyang memerintahkannya untuk menulis baris segera setelah ditemukan terlepas dari apakah pergi ke terminal atau tidak. Maka grepakan keluar pada baris kedua yang ditemukannya.
Tetapi dengan GNU grep, Anda dapat menggunakan -m 1sebagai gantinya @terdon telah menunjukkan, yang lebih baik karena keluar pada pertandingan pertama.
Jika Anda grepbukan GNU grep, maka Anda bisa menggunakan sedatau awksebaliknya. Tetapi tac sebagai perintah GNU, saya ragu Anda akan menemukan sistem dengan tacmana grepbukan GNU grep.
tac file | sed "/$pattern/!d;q" # BRE
tac file | P=$pattern awk '$0 ~ ENVIRON["P"] {print; exit}' # ERE
Beberapa sistem harus tail -rmelakukan hal yang sama seperti yang tacdilakukan GNU .
Perhatikan bahwa, untuk file biasa (yang dapat dicari), tacdan tail -refisien karena mereka membaca file ke belakang, mereka tidak hanya membaca file sepenuhnya dalam memori sebelum mencetaknya ke belakang (seperti yang dilakukan pendekatan @ slm atau tacpada file non-reguler) .
Pada sistem di mana tidak ada tacatau tail -rtersedia, satu-satunya pilihan adalah untuk menerapkan membaca mundur dengan tangan dengan bahasa pemrograman suka perlatau gunakan:
grep -e "$pattern" file | tail -n1
Atau:
sed "/$pattern/h;$!d;g" file
Tapi itu berarti menemukan semua kecocokan dan hanya mencetak yang terakhir.