Jak policzyłbyś każde wystąpienie terminu we wszystkich plikach w bieżącym katalogu? - i podkatalogi (?)
Przeczytałem o tym, że użyłbyś tego grep
; jakie jest dokładne polecenie?
Czy jest to również możliwe przy użyciu innego polecenia?
Jak policzyłbyś każde wystąpienie terminu we wszystkich plikach w bieżącym katalogu? - i podkatalogi (?)
Przeczytałem o tym, że użyłbyś tego grep
; jakie jest dokładne polecenie?
Czy jest to również możliwe przy użyciu innego polecenia?
Odpowiedzi:
Używanie grep
+ wc
(pozwoli to na wielokrotne użycie terminu w tym samym wierszu):
grep -rFo foo | wc -l
-r
in grep
: wyszukuje rekurencyjnie w bieżącej hierarchii katalogów;-F
in grep
: dopasowuje do ustalonego ciągu zamiast do wzorca;-o
w grep
: drukuje tylko dopasowania;-l
in wc
: drukuje liczbę linii;% tree
.
├── dir
│ └── file2
└── file1
1 directory, 2 files
% cat file1
line1 foo foo
line2 foo
line3 foo
% cat dir/file2
line1 foo foo
line2 foo
line3 foo
% grep -rFo foo | wc -l
8
PCREs
nie należy go stosować, ponieważ są eksperymentalne
-F
będzie prawdopodobnie szybciej.
-F
zamiast -P
. Dzięki za świetną sugestię, aktualizację za pomocą -F
, która rzeczywiście pasuje tutaj lepiej.
grep -Rc [term] *
zrobi to. -R
Flaga oznacza, że chcesz rekurencyjnie przeszukać bieżącym katalogu i wszystkich jego podkatalogów. Jest *
to selektor plików, który oznacza: wszystkie pliki. -c
Flag sprawia grep
tylko wyjście liczbę wystąpień. Jeśli jednak słowo występuje wiele razy w jednym wierszu, jest liczone tylko raz.
Od man grep
:
-r, --recursive
Read all files under each directory, recursively, following symbolic links only if they are on the command line.
This is equivalent to the -d recurse option.
-R, --dereference-recursive
Read all files under each directory, recursively. Follow all symbolic links, unlike -r.
Jeśli w katalogu nie ma dowiązań symbolicznych, nie ma różnicy.
-c
flagę do grep
. Wtedy grep się liczy i nie potrzebujeszwc
--
wcześniej*
*
Wzrośnie tylko do osób niebędących dotfiles, więc pominięcia wszystkich tych. Bardziej sensowne jest po prostu użycie „”. ponieważ i tak będziesz przetwarzał argumenty rekurencyjnie - i to dostanie pliki kropkowe. Większy problem polega na tym, że może to oznaczać liczbę wierszy, a nie liczbę wystąpień słowa. Jeśli termin pojawia się wiele razy w jednym wierszu, zostanie policzony tylko raz przez „grep -c”
W małym skrypcie python:
#!/usr/bin/env python3
import os
import sys
s = sys.argv[1]
n = 0
for root, dirs, files in os.walk(os.getcwd()):
for f in files:
f = root+"/"+f
try:
n = n + open(f).read().count(s)
except:
pass
print(n)
count_string.py
.Uruchom go z katalogu za pomocą polecenia:
python3 /path/to/count_string.py <term>
# get the current working directory
currdir = os.getcwd()
# get the term as argument
s = sys.argv[1]
# count occurrences, set start to 0
n = 0
# use os.walk() to read recursively
for root, dirs, files in os.walk(currdir):
for f in files:
# join the path(s) above the file and the file itself
f = root+"/"+f
# try to read the file (will fail if the file is unreadable for some reason)
try:
# add the number of found occurrences of <term> in the file
n = n + open(f).read().count(s)
except:
pass
print(n)
root
i f
do?
root
to ścieżka do pliku, w tym „powyżej” bieżącego katalogu, f
to plik. Alternatywnie, os.path.join()
można użyć, ale jest bardziej szczegółowy.
n = n + open(f).read().count(s)
?