Primeiro, alguns comentários / perguntas para você pensar de uma maneira diferente:
(em outras palavras, isso começou como um comentário, mas se tornou uma resposta real em algum lugar ao longo do caminho)
-
Por que você está tentando extrair o elemento
devicename
quando já o conhece - é o que você usou para buscar o XML (comname=devicename
na URL)? -
Mesmo se você ainda não o tiver, o segundo comando
curl
(com?.devicestatus
) contém os elementosdevicename
estatus
, portanto, você só precisa buscar o segundo. -
Suas linhas
variable1=
evariable2=
estão seriamente confusas. você usou$grep
em vez de$(grep
nas duas linhas e finalizou a aspa dupla com:
em vez de outras aspas duplas.i.e. deveria ser como
<<< "$test"
, não<<< "$test:
-
Como outros já mencionaram nos comentários, usar expressões regulares para analisar XML não é uma boa maneira de fazer isso. Use um processador XML, por ex.
xmlstarlet
é uma ferramenta útil para trabalhar com XML em scripts de shell. Ou escreva seu script em um idioma (por exemplo,perl
oupython
que tem bibliotecas de processamento XML disponíveis. Pesquise aqui neste site e no link para muitos exemplos). -
Por causa de 3. e 4. acima, a resposta à sua pergunta é "Não, isso não é prático porque não funciona e porque expressões regulares não devem ser usadas aqui". / p>
Agora, para algumas soluções possíveis:
Isso apenas corrige os erros de sintaxe em seu script para que ele seja executado:
#!/bin/bash
test=$(curl -k --silent "https://username:[email protected]?.full=true&name=devicename")
test2=$(curl -k --silent "https://username:[email protected]?.devicestatus&name=devicename")
variable1=$(grep -oPm1 "(?<=<name>)[^<]+" <<< "$test1")
variable2=$(grep -oPm1 "(?<=<status>)[^<]+" <<< "$test2")
echo "$variable"
echo "$variable2"
Isso está longe de ser ideal, embora as expressões regulares não possam analisar de maneira confiável o XML. Tentar fazê-lo é, na melhor das hipóteses, um truque feio e só funciona se as condições (ou seja, a entrada XML) forem absolutamente perfeitas para o que você está tentando extrair. Mesmo pequenas alterações na saída XML pelo servidor (como a eliminação de espaços em excesso, incluindo novas linhas) podem e irão quebrar seu script.
Se eu estivesse tentando fazer o que você parece estar fazendo, é mais ou menos assim:
#!/bin/bash
U='username'
P='password'
site='website.api.address'
element_base='queryResponse/entity'
element_AP="${element_base}/accessPointDetailsDTO"
element_status="${element_AP}/status"
devname='devicename'
url="https://${U}:${P}@${site}?.devicestatus&name=${devname}"
xml=$(curl -k --silent "$url")
status=$(printf '%s\n' "$xml" | xmlstarlet sel -t -v "$element_status")
echo "$devname: $status"
Uma das coisas úteis sobre como escrever o script dessa maneira é que, construindo as várias strings ( $url
e $element_status
em particular) de outras variáveis, é fácil alterá-las sem muito risco de erros de digitação ou outros erros. . Eles também podem vir da linha de comando (por exemplo, U="$1" ; P="$2" ; devname="$3"
ou usando getopts
para processar opções de linha de comando como -u username -p passsword -d devicename
) ou de um arquivo de configuração, ou ambos. Você também pode fornecer vários devname
s na linha de comando e buscá-los em um loop.
Aqui está outra versão do script que combina algumas dessas ideias:
#!/bin/bash
# get username and password, and remove them from the args
U="$1" ; shift
P="$1" ; shift #edited. was $2
site='website.api.address'
element_base='queryResponse/entity'
element_AP="${element_base}/accessPointDetailsDTO"
element_status="${element_AP}/status"
url="https://${U}:${P}@${site}?.devicestatus"
for devname in "$@" ; do
xml=$(curl -k --silent "${url}&name=${devname}")
status=$(printf '%s\n' "$xml" | xmlstarlet sel -t -v "$element_status")
echo "$devname: $status"
done