Как посчитать вхождение конкретной строки в определенную строку в файле?

Я знаю, что могу использовать wc, чтобы вернуть общее количество слов (и строк) в файле, используя:

wc <filename>

Есть ли способ вернуть количество для определенной строки в определенной строке файла?

Что-то вроде следующего:

wc -<flag> <line number> -<flag> <string> <filename>

5 ответов

Решение

Это нужно сделать в три этапа:

  1. Выберите номер строки N (пример использует строку 42):

    sed '42!d'
    
  2. Поиск строки для всех вхождений определенного шаблона (здесь строка / регулярное выражение hello) и распечатайте их отдельно:

    grep -o 'hello'
    
  3. Подсчитать совпадения:

    wc -l
    

Или поместить его в один командный канал, читая из file.txt:

sed '42!d' file.txt | grep -o 'hello' | wc -l

Это хороший пример использования инструментов Unix в конвейере.

line=5
str="ipsum"
sed -n "${line}p" filename | grep -o -- "$str" | wc -l

Сед p Команда выводит заданную строку файла и передает ее в grep. Grep-х -o опция говорит ему выводить все совпадения для данной строки, и каждое совпадение выводится в отдельной строке. Вывод Grep подается на wc, который считает количество строк.

питон

Вот один из способов сделать это в Python через понимание списка (см. Ниже альтернативную более короткую версию).

$ python -c 'import sys;print([ l for i,l in enumerate(sys.stdin,1) if i==2][0].count("word"))' < input.txt                                          
3
$ cat input.txt
nothing here
word and another word, and one more word
last line

Как это работает:

  • мы запускаем интерпретатор Python с -c флаг, где команды содержатся в одинарных кавычках;
  • входной файл input.txt перенаправлен в stdin поток интерпретатора Python через < оператор оболочки. Следовательно, нам нужно sys модуль.
  • Использование структуры понимания списка [something for item in something]мы читаем строки текста из sys.stdin,
  • enumerate(sys.stdin,1) позволяет нам подсчитать, перечислить строки, т.е. с каждой итерацией понимания списка, мы получим строку текста в l переменная и индекс в i переменная, начиная отсчет с 1.
  • i==2 отфильтрует только строку, индекс которой равен 2. Вот так мы узнаем, какую строку извлечь.
  • Таким образом, в результате наш список будет содержать только один элемент, а в списке его индекс 0, Итак, мы ссылаемся на этот пункт как [<list comprehension stuff here>][0], -The .count("word") это то, что на самом деле делает счет. По определению он возвращает количество непересекающихся вхождений подстроки в строке.
  • наконец, все это содержалось в print() заявление. Так что какой бы номер .count() возврат метода будет отображаться на экране.

Более короткая версия

Более короткий способ сделать то же самое в Python будет использовать readlines() метод вместо понимания списка, и обратитесь к конкретному элементу в списке, который readlines() производит. Обратите внимание, что readlines() создает список, а списки в Python индексируются 0, что означает, что если вы хотите прочитать строку x, вы должны ссылаться на элемент списка x-1. Например,

$ python -c 'import sys;print(sys.stdin.readlines()[1].count("word"))' < input.txt       
3

СЕПГ + Grep

Конечно, нам не нужно придерживаться только языков сценариев. sed а также grep предоставить достаточно инструментов, которые мы можем использовать для удовлетворения наших потребностей. С grep -c мы можем подсчитать вхождение совпадающих строк, поэтому все, что нам нужно сделать, - это выделить нужную нам строку и разбить все слова в этой строке на отдельные строки. Вот так:

$ sed -n  '2{s/ /\n/g;p}' input.txt | grep -c 'word'
3

awk решение:

awk 'NR==X { print gsub("word",""); }' file
  • изменить X с вашим конкретным номером строки.
  • измените "слово" с вашим желаемым словом.
  • gsub возвращает номер замены "слова", похоже, мы его считаем.

Exampe:

$ cat file:
a b c a a d
d e f f f 1

давайте посмотрим, сколько 'f' мы получили в строке "2":

$ awk 'NR==2 { print gsub("f",""); }' file
3

Один из способов сделать это, в perl:

perl -lne '
  BEGIN{($lineno, $str) = splice @ARGV,0,2} 
  print $c = () = /$str/g if $. == $lineno
' <lineno> <string> <filename>
Другие вопросы по тегам