Как бы вы посчитали каждое вхождение термина во всех файлах в текущем каталоге? - и подкаталоги (?)
Я читал, что для этого вы бы использовали grep
; какая точная команда?
Кроме того, возможно ли это с какой-то другой командой?
Как бы вы посчитали каждое вхождение термина во всех файлах в текущем каталоге? - и подкаталоги (?)
Я читал, что для этого вы бы использовали grep
; какая точная команда?
Кроме того, возможно ли это с какой-то другой командой?
Ответы:
Использование grep
+ wc
(это будет обслуживать несколько вхождений термина в одной строке):
grep -rFo foo | wc -l
-r
in grep
: рекурсивный поиск в текущей иерархии каталогов;-F
in grep
: сопоставляется с фиксированной строкой, а не с шаблоном;-o
в grep
: печатает только совпадения;-l
in wc
: печатает количество строк;% 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
не следует использовать, так как они являются экспериментальными
-F
что, вероятно, будет быстрее.
-F
вместо -P
. Спасибо за отличное предложение, обновление с использованием -F
, которое действительно подходит лучше здесь.
grep -Rc [term] *
сделаю это. -R
Флаг означает , что вы хотите рекурсивно искать в текущем каталоге и всех его подкаталогах. Это *
селектор файлов, означающий: все файлы. -c
Флага делает grep
выводить только число вхождений. Однако, если слово встречается в одной строке несколько раз, оно считается только один раз.
От 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.
Если у вас нет символических ссылок в вашем каталоге, нет никакой разницы.
-c
флаг к grep
. Тогда grep считает себя, и вам не нужноwc
--
раньше*
*
Будет расширяться только для не составляют скрытые, так что вы пропустите все те. Имеет больше смысла просто использовать "." так как вы все равно будете рекурсивно обрабатывать аргументы - и это получит точечные файлы. Большая проблема здесь заключается в том, что это может быть количество строк, а не количество вхождений слова. Если термин появляется несколько раз в одной строке, он будет учитываться только один раз как "grep -c"
В небольшом скрипте 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
.Запустите его из каталога с помощью команды:
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
и f
для чего?
root
путь к файлу, включая «над» текущим каталогом, f
это файл. В качестве альтернативы os.path.join()
можно использовать, но более многословно.
n = n + open(f).read().count(s)
?