Estou tentando encontrar uma string em uma página da web baixada com curl
. Estou usando grep
para encontrar a string que corresponde a um padrão de expressão regular .
A seguir está a string que estou tentando encontrar:
./download/file.php?id=86753
Esta string faz parte desta string maior na página da web:
href="./download/file.php?id=86753"
O grep
encantamento com o qual estou trabalhando é o seguinte:
grep -Eo '\.\/download\/file\.php\?id=[0-9]+' dlfile.html
Mas isso não encontra nada no arquivo html. No entanto, se eu modificar grep
da seguinte forma, recebo duas (2) correspondências. A primeira partida é a que preciso; a segunda é uma distração inútil e não deve ser incluída:
grep -Eo '\/download\/file\.php\?id=[0-9]+' dlfile.html
/download/file.php?id=86753
/download/file.php?id=62517
A string que contém a segunda correspondência (indesejada) é a seguinte:
href="https://web.archive.org/web/20190824162104/https://www.somewhere.com/forums/download/file.php?id=62517&sid=907ab04af81e19ad758c5bcf8ebdca32"
Parece que o problema é a falha em reconhecer o início .
(ponto) na string. Observe que esta é a principal diferença entre a string desejada e a string indesejada.
P: Por que isso não funciona e o que eu preciso?
Meu ambiente: derivado do Debian (Raspberry Pi), versão 'bullseye'
Qual grep
e bash
estou usando?
$ grep --version
grep (GNU grep) 3.6
...
$ bash --version
GNU bash, version 5.1.4(1)-release (arm-unknown-linux-gnueabihf)
Você usou
grep -E
, exigindo Expressões Regulares Estendidas (EREs). Dot sempre deve ser escapado como literal. O ponto de interrogação é um operador válido para EREs, portanto, para corresponder como literal, ele também deve ter escape:Você perguntou,
Seu padrão corresponde e requer um ponto literal (é isso que
\.
significa). No entanto, a string que você descreveu na sua pergunta não aparece na página da web que você está tentando pesquisar.grep
não ignora isso; isso exige. Olhar:Presumo que você queira o primeiro deles, então vamos extrair esse:
Se você quiser apenas a parte começando,
/download
você pode retirá-la facilmenteSe você realmente deseja usar
grep
a ferramenta certa para o trabalho, isso retornará o mesmo resultado:A resposta à pergunta na sua linha de assunto:
é simplesmente - isso não acontece.
Usando as duas linhas de entrada de amostra que você forneceu juntas em um arquivo:
e apenas removendo as barras invertidas indesejáveis (provavelmente inofensivas, mas definitivamente dependendo do comportamento indefinido por POSIX) antes do
/
s e executando os 2grep
comandos em sua pergunta:O primeiro
grep
, que inclui um início.
, corresponde apenas à string da entrada que tem um início,.
enquanto o segundogrep
, que não inclui um início.
, sem surpresa corresponde a 2 strings da entrada que não começam com um.
.Em relação ao seu comentário sobre o primeiro
grep
acima:qualquer então:
portanto, não há realmente nada que possamos fazer para ajudá-lo a depurar um comando que você está usando para analisar alguma entrada quando não sabemos a aparência do seu comando ou não sabemos como é a sua entrada.
Houve muitos comentários aqui. Alguns deles levantaram preocupações e questões válidas. Acredito que finalmente resolvi o problema e estou postando isso aqui em um esforço para encerrar.
Como você deve ter percebido, eu estava "raspando" uma URL em busca de uma string contendo um item de informação que eu precisava. Desenvolvi um script para "automatizar" essa tarefa, talvez há 2 anos, e funcionou perfeitamente. O script faz duas coisas principais:
curl
egrep
a página da webgrep
resultado"Algo mudou" há alguns dias. Meu script "confiável" começou a gerar um erro durante cada execução; a indicação de erro sugeria que
grep
não estava conseguindo encontrar a string. O quegrep
eu estava usando:Até agora, ainda não sei tudo o que mudou. Acredito que uma das mudanças é que o site foi terceirizado para uma empresa chamada “CloudFlare”; outra parece ser que eles não lidam mais com
curl
downloads da mesma forma que lidam com downloads de um navegador. Mudanças adicionais parecem estar ocorrendo.A confusão refletida na minha pergunta se deve em parte a essas alterações no site, mas se deve principalmente a mim . Eu deveria ter sido paciente e investigado o erro mais detalhadamente antes de postar uma pergunta. Minhas desculpas a todos os envolvidos.
Uma coisa que afirmo ter aprendido com essa experiência:
grep
não é a ferramenta correta para analisar HTML . Tenho duas referências para compartilhar:Este tópico polêmico do SO está usando regexes para analisar HTML
Esta postagem informativa de Hiks Gerganov intitulada "Análise de HTML para extrair texto entre tags HTML no Shell".
Funciona bem aqui se eu mudar
\/
para plain/
:Saída:
Você também pode considerar adicionar
\B
no início e\b
no final para melhor rejeição de quase-acidentes indesejados.