Saya memiliki file dengan garis kosong di akhir file. Dapatkah saya menggunakan grep
untuk menghitung jumlah baris kosong di akhir file dengan nama file yang diteruskan sebagai variabel dalam skrip?
text-processing
grep
wc
Raghunath Choudhary
sumber
sumber
grep
@MichaelJohn menang untuk kemurnian di buku saya.Jawaban:
Jika garis kosong hanya di bagian akhir
atau:
sumber
grep -cv . myFile
adalah cara lain untuk menulisnya (untuk pegolf kode). Tapi saya menemukan solusi dengangrep
jika ada baris kosong di mana saja dalam file.grep -cv .
juga akan menghitung garis yang hanya berisi byte yang tidak membentuk karakter yang valid.Hanya untuk bersenang-senang, beberapa seram
sed
:Penjelasan:
/./
alamat baris dengan karakter apa pun, jadi/./!
alamat baris non-kosong; untuk itu,H
perintah menambahkannya ke ruang tunggu. Jadi, jika untuk setiap baris kosong kami telah menambahkan satu baris ke ruang penahanan, selalu ada satu baris lebih banyak daripada jumlah baris kosong. Kami akan merawatnya nanti.//h
pola kosong cocok dengan ekspresi reguler terakhir, yang merupakan karakter apa pun, sehingga setiap baris non-kosong dialamatkan dan dipindahkan ke ruang penahanan olehh
perintah untuk "mengatur ulang" baris yang dikumpulkan ke 1. Ketika baris kosong berikutnya akan ditambahkan, akan ada dua lagi, seperti yang diharapkan.$!d
menghentikan skrip tanpa output untuk setiap kecuali baris terakhir, jadi perintah selanjutnya hanya dijalankan setelah baris terakhir. Jadi, apa pun baris kosong yang kami kumpulkan di ruang penyimpanan ada di akhir file. Baik.//d
:d
Perintah sekali lagi dieksekusi untuk baris yang tidak kosong. Jadi jika baris terakhir tidak kosong,sed
akan keluar tanpa output apa pun. Garis nol. Baik.x
pertukaran memegang ruang dan ruang pola, sehingga garis yang dikumpulkan berada dalam ruang pola sekarang untuk diproses.s/\n//
.wc -l
.sumber
Beberapa GNU
tac
/tail -r
opsi lain:Atau:
Perhatikan bahwa pada output:
Yaitu, di mana ada ruang tambahan setelah baris penuh terakhir (yang beberapa orang dapat anggap sebagai baris kosong tambahan, tetapi menurut definisi POSIX teks, bukan teks yang valid), mereka akan memberikan 0.
POSIXly:
tetapi itu berarti membaca file secara penuh (
tail -r
/tac
akan membaca file mundur dari akhir pada file yang bisa dicari). Itu memberi1
pada output dariprintf 'x\n '
.sumber
Ketika Anda benar-benar meminta
grep
solusi, saya menambahkan ini hanya mengandalkan GNUgrep
(oke, juga menggunakan sintaks shell danecho
...):Apa yang saya lakukan disini?
$(grep -c ".*" "$1")
menghitung semua baris dalam file, lalu kita kurangi file tersebut tanpa mengeklik baris kosong.Dan bagaimana cara mendapatkannya?
$(grep -B42 . "$1"
akan menangkap semua baris yang tidak kosong dan 42 baris sebelum mereka, sehingga akan mencetak semuanya hingga baris yang tidak kosong yang terakhir, selama tidak ada lebih dari 42 baris kosong berturut-turut sebelum baris yang tidak kosong. Untuk menghindari batas itu, saya ambil$(grep -cv . "$1")
sebagai parameter untuk-B
opsi, yang merupakan jumlah total baris kosong, jadi selalu cukup besar. Dengan cara ini saya telah menghapus garis kosong yang tertinggal dan dapat digunakan|grep -c ".*"
untuk menghitung garis.Cemerlang, bukan? (-;
sumber
tac | grep
ke yang pertama kali tidak kosong dengan-m -A 42
, kemudian minus satu. Saya tidak yakin mana yang lebih efisien, tetapi Anda juga bisawc -l | cut -d' ' -f1
bukannya mengambil garis kosong?tac
,wc
dancut
, tetapi di sini saya mencoba membatasi dirigrep
. Anda bisa menyebutnya kesesatan, saya menyebutnya olahraga. (-;awk
Solusi lain . Variasi ini me-reset penghitungk
setiap kali ada garis yang tidak kosong. Lalu, setiap baris menambah penghitung. (Jadi, setelah garis panjang non-kosong pertamak==0
.) Pada akhirnya kami menampilkan jumlah garis yang telah kami hitung.Siapkan file data
Hitung garis kosong yang tertinggal dalam sampel
Dalam definisi ini, baris kosong mungkin berisi spasi atau karakter kosong lainnya; masih kosong. Jika Anda benar-benar ingin menghitung garis kosong daripada garis kosong, ubah
NF
untuk$0 != ""
.sumber
$0 > ""
? Itu menggunakanstrcoll()
yang akan kurang efisien daripada$0 != ""
yang menggunakanmemcmp()
dalam banyak implementasi (POSIX digunakan untuk mengharuskannya untuk digunakanstrcoll()
).$0 > ""
mungkin berbeda$0 != ""
. Saya cenderung memperlakukanawk
sebagai operator "lambat" (sehingga jika saya tahu saya punya dataset besar sebagai input dan prosesnya sangat penting, saya akan melihat apa yang bisa saya lakukan untuk mengurangi jumlah yangawk
harus diproses - saya telah menggunakangrep | awk
konstruksi dalam situasi seperti itu). Namun, setelah melihat sekilas apa yang saya asumsikan adalah definisi POSIX saya tidak dapat melihat referensi untuk salah satustrcoll()
ataumemcmp()
. Apa yang saya lewatkan?strcoll()
== string harus dibandingkan menggunakan urutan pemeriksaan spesifik lokal . Bandingkan dengan edisi sebelumnya . Saya yang membawanya. Lihat juga austingroupbugs.net/view.php?id=963a <= b && a >= b
yang belum tentu sama dengana == b
. Aduh!awk
ataubash
(untuk yang[[ a < b ]]
operator) di en_US.UTF-8 lokal pada sistem GNU misalnya untuk①
vs②
misalnya (untukbash
, tidak ada<
,>
,=
kembali berlaku bagi mereka). Boleh dibilang itu adalah bug dalam definisi lokasi-lokasi itu lebih daripada di bash / awkSolusi padat
awk
+tac
:Sampel
input.txt
:Tindakan:
!NF
- memastikan garis saat ini kosong (tidak memiliki bidang)NR==++c
- memastikan urutan baris kosong berturut-turut. (NR
- nomor catatan,++c
- penghitung tambahan yang ditambahkan secara merata)cnt++
- Penghitung garis kosongHasil:
sumber
IIUC, skrip berikut disebut
count-blank-at-the-end.sh
akan melakukan pekerjaan:Contoh penggunaan:
Saya mengujinya di
GNU bash
,Android mksh
dan diksh
.sumber
Python
Solusi alternatif :Contoh input.txt:
Tindakan:
Hasil:
https://docs.python.org/3/library/itertools.html?highlight=itertools#itertools.takewhile
sumber