Jestem pewien, że jest na to wiele sposobów: jak policzyć liczbę linii w pliku tekstowym?
$ <cmd> file.txt
1020 lines
Jestem pewien, że jest na to wiele sposobów: jak policzyć liczbę linii w pliku tekstowym?
$ <cmd> file.txt
1020 lines
Odpowiedzi:
Standardowy sposób polega na tym wc
, że argumenty określają, co powinien liczyć (bajty, znaki, słowa itp.); -l
jest dla linii:
$ wc -l file.txt
1020 file.txt
cat matlab.git.diff | sed -e '/^\+[ ]*.*\%$/d' | wc -l
. /regexp/d
usuwa linię, jeśli pasuje regexp
, i -e
włącza odpowiednią składnię (IMNSHO) dla regexp
.
grep -v '^+ *%' matlab.git.diff | wc -l
?
grep
polecenie, aby traktować je jako przypadki komentarza, takie jak " + Hello"
(zwróć uwagę na spacje przed +
)?
grep -v '^ *+' matlab.git.diff | wc -l
(Zakładam, że znaki cudzysłowu nie miały być częścią wiersza; zakładam również, że obie linie ze spacjami i bez przed nimi +
mają być komentarzami; jeśli w najmniej jedno pole jest obowiązkowe, albo zastąpić gwiazdę *
z \+
, lub po prostu dodać kolejne miejsca przed gwiazdą). Prawdopodobnie zamiast dopasowywać tylko spacje, chciałbyś dopasować dowolne białe znaki; w tym celu zastąp spację znakiem [[:space:]]
. Zauważ, że usunąłem również dopasowanie, %
ponieważ nie ma go w twoim przykładzie.
Jak powiedział Michael, wc -l
jest to najlepsza droga. Ale tylko w przypadku, gdy w niewytłumaczalny sposób mieć bash
, perl
czy awk
jednak nie wc
, oto jeszcze kilka rozwiązań:
$ LINECT=0; while read -r LINE; do (( LINECT++ )); done < file.txt; echo $LINECT
$ perl -lne 'END { print $. }' file.txt
i znacznie mniej czytelny:
$ perl -lne '}{ print $.' file.txt
$ awk 'END {print NR}' file.txt
Steven D zapomniał o GNU sed
:
sed -n '$=' file.txt
Ponadto, jeśli chcesz zliczać bez wypisywania nazwy pliku i używasz wc
:
wc -l < file.txt
Tylko do cholery:
cat -n file.txt | tail -n 1 | cut -f1
grep -c ''
, lub tr -dc '\n' | wc -c
, lub nl -ba -nln | tail -n 1 |sed -e 's/[^0-9].*//'
... Czy którykolwiek z nich jest przydatny sam w sobie (w przeciwieństwie do rzeczy, na których można budować program, który robi więcej niż zliczanie linii), innych niż wc -l
czysty (ba) sh?
sed 's/.*//' file.txt | uniq -c
uniq -c -w 0 file.txt
i możesz cut -c -7
zachować tylko numer. Albo, bardziej POSIXly: uniq -c file.txt | awk '{c+=$1}END{print c}'
. Co powiesz na to dc
(chociaż nie jest to POSIX)? uniq -c file.txt | cut -c -7 | sed '$alax' | dc -e '[pq]sb[+z1=blax]sa' -
. bc
jest POSIX: uniq -c file.txt | cut -c -7 | sed -n ':a;${s/\n/ + /gp;b};N;ba' | bc
. Prosta odpowiedź, jeśli przyjąć ograniczoną długość linii: uniq -c -f 100000 file.txt
.
Słowo ostrzeżenia podczas korzystania
wc -l
ponieważ wc -l działa poprzez zliczanie \ n, jeśli ostatni wiersz w pliku nie kończy się skutecznie nową linią, licznik linii zostanie wyłączony o 1. (stąd stara konwencja pozostawiająca nową linię na końcu pliku)
Ponieważ nigdy nie mogę mieć pewności, czy dany plik jest zgodny z konwencją kończenia ostatniego wiersza znakiem nowej linii, czy nie, zalecam użycie któregokolwiek z tych alternatywnych poleceń, które będą zawierać ostatni wiersz w liczeniu, niezależnie od znaku nowego wiersza, czy nie.
sed -n $= filename
perl -lne 'END { print $. }' filename
awk 'END {print NR}' filename
grep -c '' filename
Jeśli masz tylko bash i absolutnie żadne zewnętrzne narzędzia nie są dostępne, możesz również wykonać następujące czynności:
count=0
while read
do
((count=$count+1))
done <file.txt
echo $count
Objaśnienie: pętla odczytuje standardową linię wejściową linia po linii ( read
; ponieważ i tak nic nie robimy z danymi wejściowymi do odczytu, nie podano żadnej zmiennej do ich zapisania) i za count
każdym razem zwiększa zmienną . Z powodu przekierowania ( <file.txt
po done
) standardowe wejście dla pętli pochodzi z file.txt
.