У меня есть файл, что-то вроде:
helsoidfiejoih
heye heye hey
me is hi
Файл может содержать любое количество строк или символов, суть в том, что это текстовый файл какого-то рода. Теперь мне нужно использовать grep для выполнения некоторой операции, чтобы первый параметр, переданный grep, был именем файла, а второй параметр — шаблоном. Но grep выполняет жадное сопоставление, поэтому оно соответствует всей строке вместо нежадного сопоставления, которое мне нужно (нежадное сопоставление). Теперь я попробовал:
grep -Ec -Po "$2" $1
Это дает мне противоречивые выражения. И пользователь может ввести любой шаблон AKA RE, поэтому -E является необходимой опцией. Есть ли способ сделать grep нежадным? Мне сказали, что опция -P делает команду grep нежадной, но после попытки:
grep -c -Po "$2" $1
Кажется, это не делает выражение grep нежадным?
Редактировать: Люди говорили, что я не показываю шаблоны, с которыми работаю, поэтому поясню, что шаблоны будут RE, например, если пользователь вводит
./thisfile.sh h file1.txt
Он найдет количество появлений h в file1.txt. Если пользователь введет
./thisfile.sh io file1.txt
Он найдет количество раз, когда io появляется в file1.txt. Есть ли способ сделать это?
решение1
Чтобы подсчитать, сколько раз подстрока встречается в файле:
#!/bin/sh
grep -F -o -e "$1" | wc -l
Этот скрипт можно использовать так:
$ ./script e <script
2
$ ./script ' -' <script
4
$ ./script hey <file1
3
$ ./script he <file1
4
$ df | ./script %
7
Здесь я подсчитываю количество e
символов в самом скрипте, а затем количество раз, когда в скрипте встречается подстрока, состоящая из пробела и тире. Затем я подсчитываю несколько подстрок в файле, представленном в вопросе. Последний пример подсчитывает количество знаков процента в выводе на df
моей системе.
Входные данные считываются через стандартный ввод, и единственным аргументом скрипта является подстрока, которую мы хотим найти и подсчитать.
Скрипт состоит из одного конвейера grep
+ wc
. Он использует нестандартную (но обычно реализуемую) -o
опцию для возврата списка неперекрывающихся совпадений на отдельных строках. Затем эти строки подсчитываются с помощью wc -l
.
Вызов grep
использует -F
для интерпретирования шаблона как строки, а не как регулярного выражения. Это позволяет подсчитать количество раз, когда eg *
встречается в файле, без необходимости экранирования *
(вам все равно придетсяцитировать, чтобы *
оболочка не использовала его в качестве шаблона подстановки). Оставьте этот параметр -F
пустым, если хотите использовать шаблон в качестве регулярного выражения.
Параметр -e
используется для указания grep
того, что $1
это шаблон. Если -e
не используется, шаблон типа --version
будет интерпретироваться как параметр для grep
.
решение2
Некоторые версии grep
(например, GNU) позволяют вам предоставлять Perl-совместимые RE (см.ПКРЕ), они гораздо более гибкие, чем стандартные регулярные выражения POSIX.