Как считать количество частичных случаев строки в файле

У меня есть файл, которого я должен считать все частичные соответствия для входной строки в файле.
Я покажу Вам легкий пример того, в чем я нуждаюсь:

В файле с этим содержанием:

Good-Black-Cat
Bad-Red-Cat
Bad-Gray-Dog
Good-Golden-Dog
Bad-White-Dog
Good-Tabby-Cat
Bad-Siamese-Cat

Я должен рассчитать, сколько раз делает частичную строку, "Хорошую - *-CAT" (Где * могло быть что-либо, это не имеет значения), появляется. Ожидаемое выходное количество равняется 2.

Любая справка будет цениться.

5
задан 26 May 2018 в 14:47

3 ответа

Не представьте себе sed/grep версию

sed 's/\(Good-[^ ]*-Cat\)/XXXX\n/g' input.txt | grep -c XXXX

, В то время как XXXX может быть любой шаблон, который не появляется иначе в Вашем файле. Этот подход заменяет все соответствия XXXX шаблон и новая строка, так для создания этого легко исчисляемым основным выражением GREP.

Между прочим, если Вы берете, "Где * могло быть что-либо" буквально, по крайней мере, к моему пониманию, вывод любой такой программы всегда будет 0 или 1, таким образом, я предположу, что это не должно содержать пространство, по крайней мере.

3
ответ дан 23 November 2019 в 08:39

Данный

$ cat file
Good-Black-Cat
Bad-Red-Cat
Bad-Gray-Dog
Good-Golden-Dog
Bad-White-Dog
Good-Tabby-Cat
Bad-Siamese-Cat

затем

$ grep -c 'Good-.*-Cat' file
2

Обратите внимание, что это - количество согласующих отрезков длинной линии - так, например, оно не будет работать на несколько случаев на строку, или на случаи тот промежуток строки.

С другой стороны, с awk

awk '/Good-.*-Cat/ {n++} END {print n}' file

Если бы необходимо соответствовать нескольким возможным случаям на строку, то я предложил бы perl:

perl -lne '$c += () = /Good-.*?-Cat/g }{ print $c' file

где /Good-.*?-Cat/g соответствия многократно (g) и нежадно* (.*?) и () = присвоение вынуждает соответствия быть оцененными в скалярном контексте, таким образом, мы можем добавить их к количеству.

С другой стороны, Вы могли использовать grep в режиме регулярного выражения perl-comparible (PCRE) (чтобы включить нежадный модификатор), с -o для вывода только частей соответствия - затем считают тех, которые имеют wc:

grep -Po 'Good-.*?-Cat' file | wc -l

Если также необходимо соответствовать случаям, которые могут охватить границу строки, то можно сделать так в perl путем сбрасывания разделителя записей (примечание: это означает, что это целый файл хлебают в память), и добавление s модификатор regex, например.

perl -0777 -nE '$c += () = /Good-.*?-Cat/gs }{ say $c' file
12
ответ дан 23 November 2019 в 08:39

awk, несколько происшествий, разделенных пробелом

$ awk '{for(i=1;i<=NF;i++ ) count+=match($i,/Good-.*-Cat/)};END{print count}' input.txt
4
$ cat input.txt
Good-Black-Cat
Bad-Red-Cat
Bad-Gray-Dog
Good-Golden-Dog Good-Whatever-Cat Good-Something-Cat
Bad-White-Dog
Good-Tabby-Cat
Bad-Siamese-Cat

sed + туалет, ненесколько происшествий

Это использует отрицательное сопоставление с образцом //! с d для удаляют, оставляя только строки интереса.

$ sed '/Good-.*-Cat/!d' input.txt
Good-Black-Cat
Good-Golden-Dog Good-Whatever-Cat
Good-Tabby-Cat
$ sed '/Good-.*-Cat/!d' input.txt | wc -l
3

Решение Shell, ненесколько происшествий

Вот является оболочка путем, который объединяется case...esac и читающий файл цикл:

$ n=0; while IFS= read -r line || [ -n "$line" ]; do case "$line" in "Good-"*"-Cat") n=$((n+1));; esac; done < input.txt; echo "$n"
2

Или с indientation

n=0
while IFS= read -r line || [ -n "$line" ]; do 
    case "$line" in 
        "Good-"*"-Cat") n=$((n+1));; 
    esac
done < input.txt
echo "$n"

Объяснение:

  • n=0 инициализирует n переменная счетчика
  • while IFS= read -r line || [ -n "$line" ]; do...done < input.txt стандартный читающий файл цикл, используемый в сценариях оболочки, с || [ -n "$line" ] защита для составления возможных файлов, которые не заканчиваются в новой строке
  • case "$line" in "Good-"*"-Cat") n=$((n+1));; esac сопоставление с образцом для желаемой строки с $((...)) арифметическое расширение для постепенного увеличения переменной счетчика.
4
ответ дан 23 November 2019 в 08:39

Другие вопросы по тегам:

Похожие вопросы: