Szukam polecenia zliczającego liczbę wszystkich słów w pliku. Na przykład jeśli plik jest taki,
today is a
good day
to powinno się wydrukować 5
, ponieważ są 5
tam słowa.
Szukam polecenia zliczającego liczbę wszystkich słów w pliku. Na przykład jeśli plik jest taki,
today is a
good day
to powinno się wydrukować 5
, ponieważ są 5
tam słowa.
Odpowiedzi:
Polecenie wc
aka. liczba słów może to zrobić:
$ wc -w <file>
$ cat sample.txt
today is a
good day
$ wc -w sample.txt
5 sample.txt
# just the number (thanks to Stephane Chazelas' comment)
$ wc -w < sample.txt
5
wc -w
nie mają takiej samej definicji jak dla GNU grep -w
. Dla wc
słowa jest sekwencją jednego lub więcej znaków niż kosmiczne ( [:space:]
klasa znaków w bieżącej lokalizacji). Na przykład, foo,bar
i foo bar
(o nierozdzielającą przestrzeni) każdy jeden wyraz.
Wymyśliłem to po prostu numer:
wc -w [file] | cut -d' ' -f1
5
Podoba mi się również wc -w < [file]
podejście
Wreszcie, do przechowywania tylko liczby słów w zmiennej, możesz użyć:
myVar=($(wc -w /path/to/file))
Pozwala to elegancko pominąć nazwę pliku.
wc -w < "$file"
po prostu numer.
Lepszym rozwiązaniem jest użycie Perla:
perl -nle '$word += scalar(split(/\s+/, $_)); END{print $word}' filename
@Bernhard
Możesz sprawdzić kod źródłowy wc
polecenia z coreutils, testuję na moim komputerze, z plikiem subst.c
w źródle bash 4.2.
time wc -w subst.c
real 0m0.025s
user 0m0.016s
sys 0m0.000s
I
time perl -nle '$word += scalar(split(" ", $_)); END{print $word}' subst.c
real 0m0.021s
user 0m0.016s
sys 0m0.004s
Im większy plik, tym bardziej wydajny jest Perl w stosunku do wc
.
wc
zabrało ~ 14 sekund, podczas gdy Perl zajął ~ 5 sekund!
split
/\s+/
split(' ')
(split(" ", $_))
echo -e "unix\n linux" > testfile
wc
będzie znacznie szybszy, podobnie jak z PERLIO=:utf8
, perl
będzie znacznie wolniejszy.
$ function wordfrequency() { awk 'BEGIN { FS="[^a-zA-Z]+" } { for (i=1; i<=NF; i++) { word = tolower($i) words[word]++ } } END { for (w in words) printf("%3d %s\n", words[w], w) } ' | sort -rn }
$ cat your_file.txt | wordfrequency
Podaje częstotliwość każdego słowa występującego w dostarczonym pliku. Wiem, że nie o to prosiłeś, ale lepiej! Jeśli chcesz zobaczyć wystąpienia swojego słowa, możesz po prostu to zrobić:
$ cat your_file.txt | wordfrequency | grep yourword
Dodałem nawet tę funkcję do moich plików .dotfiles
Źródło: AWK-ward Ruby
W wc
programie liczy „Słowa”, ale nie są to na przykład „słowa”, że wiele osób będzie zobaczyć, kiedy zbadać plik. Na vi
przykład program używa innej miary „słów”, ograniczając je w oparciu o ich klasy znaków, a wc
po prostu liczy rzeczy oddzielone spacjami . Te dwa środki mogą się radykalnie różnić. Rozważ ten przykład:
first,second
vi
widzi trzy słowa ( pierwszy i drugi oraz przecinek oddzielający je), a wc
widzi jedno (w tym wierszu nie ma białych znaków). Istnieje wiele sposobów liczenia słów, niektóre są mniej przydatne niż inne.
Chociaż Perl byłyby lepiej przystosowane do pisania licznik za słowa vi stylu, oto krótki przykład przy użyciu sed
, tr
i wc
(umiarkowanie przenośny za pomocą dosłownych powrotu karetki ^M
):
#!/bin/sh
in_words="[[:alnum:]_]"
in_punct="[][{}\\|:\"';<>,./?\`~!@#$%^&*()+=-]"
sed -e "s/\($in_words\)\($in_punct\)/\1^M\2/g" \
-e "s/\($in_punct\)\($in_words\)/\1^M\2/g" \
-e "s/[[:space:]]/^M/g" \
"$@" |
tr '\r' '\n' |
sed -e '/^$/d' |
wc -l
Porównywanie liczby:
wc
daje 28.W celach informacyjnych POSIX vi mówi:
W ustawieniach regionalnych POSIX, vi rozpoznaje pięć rodzajów słów:
Maksymalna sekwencja liter, cyfr i znaków podkreślenia na obu końcach:
Znaki inne niż litery, cyfry lub podkreślenia
Początek lub koniec linii
Początek lub koniec bufora edycji
Maksymalna sekwencja znaków innych niż litery, cyfry, podkreślenia lub znaki, ograniczone na obu końcach przez:
- Litera, cyfra, podkreślenie
<blank>
postacie- Początek lub koniec linii
- Początek lub koniec bufora edycji
Jedna lub więcej kolejnych pustych linii
Pierwszy znak w buforze edycji
Ostatni nie
<newline>
w buforze edycji
wc -w $FILE
?