
Eu tenho um arquivo "input.txt" que contém as variáveis A1, A2, A3, θ, θ1 e θ2 - a amostra de input.txt é a seguinte:
$ cat input1.txt
A1=5.2 A2=4.9 A3=6.1 θ=space θ1=2.5 θ2=1.2
A1=3.1 A2=5.1 A3=3.7 θ=triangle θ1=8.1 θ2=3.9
Quero criar um script para rodar sobre o arquivo input.txt - esse arquivo será passado como segundo argumento, o primeiro argumento seria o valor de θ
Criei um script da seguinte forma:
#! /bin/bash
file=input1.txt
if grep -q $1 "$file";
then
awk -F '[= ]+' '{ print $12 }' <$2
else
echo "Not available"
fi
}
Mas quando executo esse script da seguinte maneira:
./script space input.txt
(o primeiro argumento é o valor de θ e o segundo argumento é o nome do arquivo), a saída são todos os valores no campo 12:
$ ./script1 space input1.txt
1.2
3.9
a saída deveria ser 1.2 apenas, procurei e descobri que preciso criar um loop para ler o arquivo linha por linha mas não consigo fazer funcionar.
Responder1
Você pode fazer todo o trabalho em awk
:
#!/bin/sh
file=$2
awk -v theta="$1" -F '[= ]+' '
$0 ~ theta { print $12; found++ }
END { if (!found) { print "Not available"; exit 1 } }' "$file"
Você pode querer adicionar tratamento de erros para verificar se há dois argumentos de linha de comando e $2
se é o nome de um arquivo legível, porque
- se
$2
for algo diferente de um arquivo legível, você receberá uma mensagem de erro deawk
- se
$2
estiver em branco ou ausente,awk
lerá silenciosamente a entrada padrão.
(É claro que um ou ambos os comportamentos podem ser adequados para você.)
Notas:
- Você pode obter resultados mais direcionados mudando
$0 ~ theta
para$8 == theta
. - Variáveis em
awk
são inicializadas em branco. Isso é tratado como 0 em contextos matemáticos, portantofound++
é definidofound
como 1 na primeira vez que é executado. Eu disse deliberadamente ,found++
em vezfound = 1
disso, se várias linhas corresponderem ao valor teta,found
será definido comonúmerode tais linhas. Parece que deveria ser uma condição de erro; se você estiver preocupado com isso, poderá modificar oEND
bloco para relatar um erro sefound
for diferente de 1. - Claro, se você precisar que seu script faça uma coisa se um valor for encontrado e outra coisa se não for, você pode excluir a
print
instrução doEND
bloco e fazer com que o script apenas testeawk
o status de saída de e emita sua própria mensagem de erro . Você também deve fazer isso se quiser capturar a saída deawk
(ou seja, o valor θ2). Por outro lado, se tudo que você precisa é de uma mensagem de erro legível e não precisa verificar o status de saída, você pode excluir aexit
instrução doEND
bloco.
Responder2
Experimente isto:
#! /bin/bash
file=input1.txt
if grep -q $1 "$file";
then
grep $1 $2 | awk -F '[= ]+' '{ print $12 }'
else
echo "Not available"
fi
Responder3
Parece que sua lógica pode ser resumida em:
grep -om1 "$1" < "$2" ||
echo 'Not available.'
...forneceu um GNU grep
, de qualquer maneira. Porém, se fosse eu, eu abandonaria o echo
, ou pelo menos o faria ...
! echo 'Not available.' >&2
...em vez de.