Eu tenho um arquivo algo como:
helsoidfiejoih
heye heye hey
me is hi
O arquivo pode conter qualquer número de linhas ou caracteres, a questão é que é algum tipo de arquivo de texto. Agora preciso usar o grep para fazer alguma operação para que o primeiro parâmetro passado para o grep seja o nome do arquivo e o segundo parâmetro seja o padrão. Mas o grep faz uma correspondência gananciosa para corresponder a toda a linha, em vez de uma correspondência não gananciosa, que é o que eu quero (correspondência não gananciosa). Agora eu tentei:
grep -Ec -Po "$2" $1
Isso me dá expressões conflitantes. E o usuário pode inserir qualquer padrão também conhecido como RE, portanto -E é uma opção necessária. Existe uma maneira de tornar o grep não ganancioso? Disseram-me que a opção -P torna o comando grep não ganancioso, mas depois de experimentar:
grep -c -Po "$2" $1
Não parece tornar a expressão grep não gananciosa?
Editar: as pessoas disseram que não estou mostrando os padrões com os quais estou trabalhando, então para esclarecer os padrões será um RE, por exemplo, se o usuário inserir
./thisfile.sh h file1.txt
Ele encontrará o número de vezes que h aparece no arquivo1.txt Se o usuário inserir
./thisfile.sh io file1.txt
Ele encontrará o número de vezes que io aparece no arquivo1.txt. Existe uma maneira de fazer isso?
Responder1
Para contar quantas vezes uma substring ocorre em um arquivo:
#!/bin/sh
grep -F -o -e "$1" | wc -l
Você usaria este script assim:
$ ./script e <script
2
$ ./script ' -' <script
4
$ ./script hey <file1
3
$ ./script he <file1
4
$ df | ./script %
7
Aqui estou contando o número de e
caracteres no próprio script e, em seguida, o número de vezes que a substring que consiste em um espaço e um travessão ocorre no script. Então conto algumas substrings no arquivo apresentado na pergunta. O último exemplo conta o número de sinais de porcentagem na saída do df
meu sistema.
Os dados de entrada são lidos pela entrada padrão e o único argumento do script é a substring que queremos procurar e contar.
O script consiste em um único pipeline grep
+ wc
. Ele usa a opção não padrão (mas comumente implementada) -o
para retornar uma lista de correspondências não sobrepostas em linhas separadas. Essas linhas são então contadas com wc -l
.
A chamada para grep
fazer -F
com que o padrão seja interpretado como uma string e não como uma expressão regular. Isto torna possível contar o número de vezes que por exemplo *
ocorre em um arquivo, sem ter que escapar do *
(você ainda teria quecitarthe *
para impedir que o shell o use como um padrão globbing). Deixe -F
de fora se quiser usar o padrão como uma expressão regular.
A -e
opção é usada para dizer grep
que esse $1
é o padrão. Se -e
não for usado, um padrão como --version
seria interpretado como uma opção para grep
.
Responder2
Algumas versões grep
(por exemplo, GNU) permitem que você forneça REs compatíveis com Perl (confiraPCRE), eles são muito mais flexíveis que as expressões regulares POSIX padrão.