Uma dúvida sobre o grep (fgrep)

Fala, pessoal!
Então… Eu estou construindo um código em Shell Script, até que me deparei com a necessidade de fazer uma busca em um arquivo de texto e mandar a saída para uma variável. Eu usei o grep para fazer a busca, mas tem um detalhe, o grep me devolve todas as linhas que contenham a string da minha busca… e eu queria que ele me devolve-se apenas a linha correspondente à string exata que eu passei… Após algumas pesquisas, consegui fazer com que o grep me devolve-se a linha contendo a string exata que passei. O trecho ficou assim:

linhaexata=$(grep -n -F -x “$StringQueOUserVaiPassar” [caminho])

Beleza, deu certo, eu consigo receber do grep a linha contendo a string exata que o usuário passou, mas eu não entendo perfeitamente como isso está funcionando. Eu entendo quase tudo, exceto como o “-F” está funcionando aí…

Sobre o “-x” eu li que ele “Selecione apenas correspondências que correspondam exatamente à linha inteira”, ok… faz sentido, ele está permitindo o grep pegar a string exata que foi passada.

Mas sobre o “-F”… li que ele “Interpreta PADRÃO como uma lista de cadeias fixas, separadas por novas linhas , que devem ser correspondidas”. No próprio “-help” do comando grep consta: “-F, --fixed-strings: PADRÃO são textos separados por nova linha

Mas admito que não ficou claro para mim como isso está funcionando… o papel exato do “-F” aí… Alguém com uma didática melhorzinha poderia me dar um help? Apesar de estar funcionando no meu código, o mais importante para mim é entender como funciona.

Obrigado desde já :upside_down_face:

1 curtida

Não exatamente, a opção -x é um shorthand para ^texto procurado$ ela vai retornar APENAS as linhas que são a string ou seja a linha exata, é ele que faz a mágica, considere um arquivo assim:

abc123
123
abc
123abc

Se você executar:

grep -n -x "abc"

O grep vai retornar apenas:

3:abc

O que está pegando a string exata é justamente o -F que você quer saber, o grep se usado com outras opções como a -P permite o uso de escape codes ou seja, 1 ou mais caracteres precedidos de \ por exemplo \t que representa . . ou seja o caractere de tabulação, considere o segunte arquivo:

ab	c
ab\t

Chamar o grep sem -F :

grep -n "ab\tc"

Não retorna nada, no entanto com -F retorna a string desejada:

2:ab\tc

Mas aí você me pergunta e se eu quiser o outro? nesse caso você vai precisar do -P:

grep -n -P "ab\tc"

Que retorna:

1:ab	c
2 curtidas

Olá, Natanael, obrigado por responder :smiley:

Acho que agora eu pude compreender… No caso, o “-x” vai me devolver a linha que contiver a string que passei, já o “-F” lerá exatamente a string (carácter por carácter) e me devolverá todas as linhas que contiver os caracteres. Correto?

Por exemplo, nesse seu primeiro exemplo:

grep -n -x “abc”

Se trocássemos o “-x” pelo “-F”, o resultado seria esse:

abc123
abc
123abc

porque o “-F” teria procurado em todas as linhas do arquivo a string passada, mesmo que ela acompanhasse outros caracteres, correto?

Uma coisa, entretanto, não me ficou clara, qual seria a vantagem de se usar conjuntamente, então, -x e -F?

edit: acho que saquei a vantagem do uso conjunto de “-F” e “-x”. Nesse caso, se eu passasse como string a palavra “santo$”, por exemplo, o grep conseguiria entender que o “$” não é uma expressão regular, por causa do “-F”, correto? Já se não usasse o “-F”, o grep acharia que “$” é uma expressão regular…

Isso

Convenção, o grep escapa o caractere mas não consegue executar a busca com ele, sendo assim pra buscar por ab\tc teria que ser feito algo assim:

grep -n -x "ab"'\t'"c"

Com -F:

grep -n -F "ab\tc"

Ambos são atalhos, no final você está lançando isso no grep:

grep -n ^"ab"'\t'"c"$
1 curtida