đếm số dòng trong một tập tin


64

Tôi chắc chắn có nhiều cách để làm điều này: làm thế nào tôi có thể đếm số dòng trong một tệp văn bản?

$ <cmd> file.txt
1020 lines

Câu trả lời:


98

Cách tiêu chuẩn là với wc, lấy các đối số để chỉ định những gì cần đếm (byte, ký tự, từ, v.v.); -ldành cho dòng:

$ wc -l file.txt
1020 file.txt

Làm cách nào để đếm số dòng trong tệp nếu tôi muốn bỏ qua nhận xét? Cụ thể, tôi muốn không tính các dòng bắt đầu bằng dấu +, một số khoảng trắng (có thể không có khoảng trắng) và sau đó là%, đó là cách các dòng nhận xét xuất hiện trong một git diff của tệp MATLAB. Tôi đã thử làm điều này với grep, nhưng không thể tìm ra biểu thức chính xác.
Gdalya

@Gdalya Tôi hy vọng các đường ống sau sẽ làm điều này (không có thử nghiệm nào được thực hiện) : cat matlab.git.diff | sed -e '/^\+[ ]*.*\%$/d' | wc -l. /regexp/dxóa một dòng nếu nó khớp regexp-ebật một cú pháp (IMNSHO) đầy đủ cho regexp.
dbanet

2
Tại sao không đơn giản grep -v '^+ *%' matlab.git.diff | wc -l?
celtschk

@celtschk, miễn là điều này là bình thường trong các dòng bình luận: có thể sửa đổi greplệnh của bạn để xem xét như các trường hợp nhận xét như " + Hello"(lưu ý khoảng trắng trước +) không?
Sopalajo de Arrierez

1
@SopalajodeArrierez: Tất nhiên là có thể: grep -v '^ *+' matlab.git.diff | wc -l(Tôi cho rằng các dấu hiệu trích dẫn không thực sự là một phần của dòng; Tôi cũng cho rằng cả hai dòng có và không có khoảng trắng ở phía trước +đều có nghĩa là bình luận; ít nhất một không gian là bắt buộc, hoặc thay thế ngôi sao *bằng \+hoặc chỉ thêm một không gian khác ở phía trước ngôi sao). Có lẽ thay vì chỉ khớp các khoảng trắng, bạn muốn khớp các khoảng trắng tùy ý; cho điều này thay thế không gian với [[:space:]]. Lưu ý rằng tôi cũng đã xóa khớp với %vì nó không có trong ví dụ của bạn.
celtschk 14/2/2015

15

Như Michael đã nói, wc -llà con đường để đi. Nhưng, chỉ trong trường hợp bạn không thể giải thích có bash, perlhoặc awknhưng không wc, đây là một vài giải pháp hơn:

Chỉ Bash

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

Giải pháp Perl

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

và rất ít đọc được:

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

Giải pháp Awk

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

15

Steven D quên GNU sed:

sed -n '$=' file.txt

Ngoài ra, nếu bạn muốn đếm mà không xuất tên tệp và bạn đang sử dụng wc:

wc -l < file.txt

Chỉ vì cái quái quỷ của nó:

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

2
Hoặc grep -c '', hoặc tr -dc '\n' | wc -c, hoặc nl -ba -nln | tail -n 1 |sed -e 's/[^0-9].*//'có bất kỳ thứ nào trong số này hữu ích trong chính nó (trái ngược với những thứ được xây dựng để tạo ra một chương trình không chỉ là đếm dòng), ngoài wc -lvà thuần (ba) sh?
Gilles 'SO- ngừng trở nên xấu xa'

1
@Gilles: Tôi nghĩ rằng cụm từ "nhiều cách" trong câu hỏi đã kích hoạt một thách thức mà Steve và tôi đã đặt ra.
Dennis Williamson

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

2
@Gilles: Ồ, ý bạn là đầu tiên . uniq -c -w 0 file.txtvà bạn có thể cut -c -7chỉ giữ số. Hoặc, POSIXly hơn : uniq -c file.txt | awk '{c+=$1}END{print c}'. Còn về dc(mặc dù nó không phải là POSIX)? uniq -c file.txt | cut -c -7 | sed '$alax' | dc -e '[pq]sb[+z1=blax]sa' -. bclà POSIX : uniq -c file.txt | cut -c -7 | sed -n ':a;${s/\n/ + /gp;b};N;ba' | bc. Câu trả lời dễ dàng nếu bạn giả sử độ dài dòng giới hạn : uniq -c -f 100000 file.txt.
Dennis Williamson

1
@JosipRodin: Báo giá được thêm vào
Dennis Williamson

11

Lời cảnh báo khi sử dụng

wc -l

bởi vì wc -l hoạt động bằng cách đếm \ n, nếu dòng cuối cùng trong tệp của bạn không kết thúc ở dòng mới một cách hiệu quả thì số dòng sẽ bị tắt bởi 1. (do đó, quy ước cũ sẽ bỏ dòng mới ở cuối tệp của bạn)

Vì tôi không bao giờ có thể chắc chắn liệu có bất kỳ tệp đã cho nào tuân theo quy ước kết thúc dòng cuối cùng với một dòng mới hay không, tôi khuyên bạn nên sử dụng bất kỳ lệnh thay thế nào sẽ bao gồm dòng cuối cùng trong số bất kể dòng mới hay không.

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

tóm tắt tốt đẹp. Và chào mừng bạn đến với unix & linux
Sebastian

Hừm là mảnh cuối cùng thực sự?
gena2x

1
Tôi chắc chắn rằng nó phụ thuộc vào usecase của mọi người; cho 'mảnh cuối cùng' thường là một dòng văn bản mà ai đó đã không giới thiệu với một dòng mới. Usecase tôi thường gặp nhất là một tệp có một chuỗi văn bản không kết thúc trong một dòng mới. wc -l sẽ tính đây là "0", khi tôi sẽ mong đợi số "1".
Pretzels1337

3

Trong trường hợp bạn chỉ có bash và hoàn toàn không có công cụ bên ngoài nào, bạn cũng có thể làm như sau:

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

Giải thích: vòng lặp đọc từng dòng đầu vào tiêu chuẩn ( readvì chúng ta không làm gì với đầu vào đọc dù sao, không có biến nào được cung cấp để lưu trữ nó) và tăng biến countmỗi lần. Do chuyển hướng ( <file.txtsau done), đầu vào tiêu chuẩn cho vòng lặp là từ file.txt.


2

Bạn luôn có thể sử dụng lệnh grepnhư sau:

grep -c "^" file.txt

Nó sẽ đếm tất cả các hàng thực tế file.txt, cho dù hàng cuối cùng của nó có chứa ký tự LF ở cuối hay không.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.