menghitung baris dalam file


65

Saya yakin ada banyak cara untuk melakukan ini: bagaimana saya bisa menghitung jumlah baris dalam file teks?

$ <cmd> file.txt
1020 lines

Jawaban:


99

Cara standarnya adalah dengan wc, yang membutuhkan argumen untuk menentukan apa yang harus dihitung (byte, karakter, kata-kata, dll.); -luntuk garis:

$ wc -l file.txt
1020 file.txt

Bagaimana cara menghitung baris dalam file jika saya ingin mengabaikan komentar? Secara khusus, saya ingin tidak menghitung baris yang dimulai dengan tanda +, beberapa spasi putih (bisa jadi bukan spasi putih) dan kemudian%, yang merupakan cara baris komentar muncul dalam git diff dari file MATLAB. Saya mencoba melakukan ini dengan grep, tetapi tidak dapat menemukan ekspresi reguler yang benar.
Gdalya

@Gdalya Saya berharap pipa berikut akan melakukan hal ini (tidak ada tes sedian): cat matlab.git.diff | sed -e '/^\+[ ]*.*\%$/d' | wc -l. /regexp/dmenghapus baris jika cocok regexp, dan -emengaktifkan sintaks (IMNSHO) yang memadai untuk regexp.
dbanet

2
Kenapa tidak sederhana saja grep -v '^+ *%' matlab.git.diff | wc -l?
celtschk

@celtschk, selama ini biasa di baris komentar: apakah mungkin untuk memodifikasi grepperintah Anda untuk mempertimbangkan sebagai kasus komentar seperti " + Hello"(perhatikan spasi sebelum +)?
Sopalajo de Arrierez

1
@SopalajodeArrierez: Tentu saja itu mungkin: grep -v '^ *+' matlab.git.diff | wc -l(Saya berasumsi tanda kutip sebenarnya tidak dimaksudkan untuk menjadi bagian dari garis; Saya juga berasumsi bahwa kedua garis dengan dan tanpa spasi di depan +dimaksudkan untuk menjadi komentar; jika pada paling tidak satu ruang wajib, ganti bintang *dengan \+, atau cukup tambahkan ruang lain di depan bintang). Mungkin alih-alih hanya mencocokkan spasi, Anda ingin mencocokkan spasi putih sewenang-wenang; untuk ini ganti spasi dengan [[:space:]]. Perhatikan bahwa saya juga menghapus pencocokan %karena tidak ada dalam contoh Anda.
celtschk

15

Seperti kata Michael, wc -ladalah jalan yang harus ditempuh. Tapi, hanya dalam kasus Anda bisa dijelaskan memiliki bash, perlatau awktapi tidak wc, berikut adalah beberapa solusi yang lebih:

Khusus bash

$ LINECT=0; while read -r LINE; do (( LINECT++ )); done < file.txt; echo $LINECT

Solusi Perl

$ perl -lne 'END { print $. }' file.txt

dan yang jauh lebih mudah dibaca:

$ perl -lne '}{ print $.' file.txt

Solusi Awk

$  awk 'END {print NR}' file.txt

15

Steven D lupa GNU sed:

sed -n '$=' file.txt

Juga, jika Anda ingin menghitung tanpa mengeluarkan nama file dan Anda menggunakan wc:

wc -l < file.txt

Hanya untuk itu:

cat -n file.txt | tail -n 1 | cut -f1

2
Atau grep -c '', atau tr -dc '\n' | wc -c, atau nl -ba -nln | tail -n 1 |sed -e 's/[^0-9].*//'... Apakah semua ini berguna dalam dirinya sendiri (sebagai lawan dari hal-hal yang dibangun untuk membuat program yang lebih dari menghitung garis), selain wc -ldan murni (ba) sh?
Gilles 'SO- stop being evil'

1
@Gilles: Saya pikir ungkapan "banyak cara" dalam pertanyaan itu memicu tantangan yang saya dan Steve hadapi.
Dennis Williamson

1
@Gilles:sed 's/.*//' file.txt | uniq -c
Dennis Williamson

2
@Gilles: Oh, maksudmu yang pertama . uniq -c -w 0 file.txtdan Anda hanya bisa cut -c -7menyimpan nomornya saja. Atau, lebih POSIXly: uniq -c file.txt | awk '{c+=$1}END{print c}'. Bagaimana dc(walaupun itu bukan POSIX)? uniq -c file.txt | cut -c -7 | sed '$alax' | dc -e '[pq]sb[+z1=blax]sa' -. bcadalah POSIX: uniq -c file.txt | cut -c -7 | sed -n ':a;${s/\n/ + /gp;b};N;ba' | bc. Mudah jawaban jika Anda menganggap panjang garis yang terbatas: uniq -c -f 100000 file.txt.
Dennis Williamson

1
@JosipRodin: Kutipan ditambahkan
Dennis Williamson

11

Kata peringatan saat menggunakan

wc -l

karena wc -l berfungsi dengan menghitung \ n, jika baris terakhir dalam file Anda tidak berakhir di baris baru secara efektif, jumlah baris akan dimatikan oleh 1. (maka konvensi lama meninggalkan baris baru di akhir file Anda)

Karena saya tidak pernah bisa memastikan apakah ada file yang diberikan mengikuti konvensi untuk mengakhiri baris terakhir dengan baris baru atau tidak, saya sarankan menggunakan salah satu dari perintah alternatif ini yang akan menyertakan baris terakhir dalam hitungan terlepas dari baris baru atau tidak.

sed -n $= filename
perl -lne 'END { print $. }' filename
awk 'END {print NR}' filename
grep -c '' filename

ringkasan yang bagus. Dan selamat datang di unix & linux
Sebastian

Hm adalah bagian terakhir benar-benar baris?
gena2x

1
Saya yakin itu tergantung pada usecase semua orang; untuk 'bagian terakhir' biasanya satu baris teks yang seseorang tidak akhiri dengan baris baru. Penggunaan kata kunci yang paling sering saya temui adalah file dengan string teks tunggal yang tidak berakhir pada baris baru. wc-l akan menghitung ini sebagai "0", ketika saya sebaliknya mengharapkan hitungan "1".
pretzels1337

3

Jika Anda hanya memiliki bash dan sama sekali tidak ada alat eksternal yang tersedia, Anda juga dapat melakukan hal berikut:

count=0
while read
do
  ((count=$count+1))
done <file.txt
echo $count

Penjelasan: loop membaca input standar baris demi baris ( read; karena kita tidak melakukan apa-apa dengan input read, tidak ada variabel yang disediakan untuk menyimpannya), dan meningkatkan variabel countsetiap kali. Karena pengalihan ( <file.txtsetelah done), input standar untuk loop adalah dari file.txt.


2

Anda selalu dapat menggunakan perintah grepsebagai berikut:

grep -c "^" file.txt

Ini akan menghitung semua baris aktual file.txt, apakah baris terakhirnya mengandung karakter LF di akhir.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.