bash script para ler o primeiro argumento como entrada e procurar por variável em outro arquivo linha por linha

0

Eu tenho um arquivo "input.txt" tem 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

Eu quero criar um script para executar o arquivo input.txt - este arquivo será passado como um segundo argumento, o primeiro argumento seria o valor de θ

Eu 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 este script da seguinte forma:

./script space input.txt   

(primeiro argumento é o valor de θ e segundo argumento é o nome do arquivo), a saída é todos os valores no campo 12:

$ ./script1 space input1.txt 
1.2
3.9

a saída deve ser apenas 1.2, eu procurei e descobri que preciso criar um loop para ler o arquivo linha por linha, mas não consigo fazê-lo funcionar.

    
por user156999 17.02.2016 / 21:15

3 respostas

2

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 que existem dois argumentos de linha de comando, e $2 é o nome de um arquivo legível, porque

  • se $2 for algo diferente de um arquivo legível, você receberá uma mensagem de erro de awk
  • se $2 estiver em branco ou ausente awk lerá silenciosamente a partir da entrada padrão.

(É claro que um ou ambos os comportamentos podem estar bem com você.)

Notas:

  • Você pode obter resultados mais segmentados alterando $0 ~ theta para $8 == theta .
  • Variáveis em awk são inicializadas em branco. Isso é tratado como 0 em contextos matemáticos, portanto, found++ define found para 1 na primeira vez em que é executado. Eu disse deliberadamente found++ em vez de found = 1 , se várias linhas corresponderem ao valor theta, found será definido para o número de tais linhas. Isso parece que deveria ser uma condição de erro; Se você está preocupado com isso, você pode modificar o bloco END relatar um erro se found for algo 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 instrução print do bloco END e faça o script apenas testar o status de saída de awk e emite sua própria mensagem de erro. Você também deve fazer isso se você quiser capturar a saída do awk (ou seja, o valor θ2). Por outro lado, se tudo o que você precisa é de uma mensagem de erro legível por humanos, e você não precisa ser capaz de verificar o status de saída, você pode excluir a instrução exit do bloco END .
por 17.02.2016 / 22:50
0

Tente isto:

#! /bin/bash

file=input1.txt

if grep -q $1 "$file";
then
        grep $1 $2 | awk -F '[= ]+' '{ print $12 }'
else
        echo "Not available"
fi
    
por 17.02.2016 / 21:32
0

Parece que sua lógica pode ser reduzida a:

grep -om1 "$1" < "$2" ||
echo 'Not available.'

... forneceu um GNU grep , de qualquer forma. Porém, se fosse eu, eu descartaria o echo , ou pelo menos ...

! echo 'Not available.' >&2

... em vez disso.

    
por 18.02.2016 / 00:06