script bash para leer el primer argumento como entrada y buscar variable en otro archivo línea por línea

script bash para leer el primer argumento como entrada y buscar variable en otro archivo línea por línea

Tengo un archivo "input.txt" que tiene las variables A1, A2, A3, θ, θ1 y θ2; la muestra de input.txt es la siguiente:

$ 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

Quiero crear un script para ejecutar el archivo input.txt. Este archivo se pasará como segundo argumento, el primer argumento sería el valor de θ.

Creé un script de la siguiente manera:

#! /bin/bash

file=input1.txt

if grep -q $1 "$file"; 
then
awk -F '[= ]+' '{ print $12 }' <$2

else

echo "Not available"
fi
}

Pero cuando ejecuto este script de la siguiente manera:

./script space input.txt   

(el primer argumento es el valor de θ y el segundo argumento es el nombre del archivo), la salida son todos los valores en el campo 12:

$ ./script1 space input1.txt 
1.2
3.9

el resultado debería ser solo 1.2, busqué y descubrí que necesito crear un bucle para leer el archivo línea por línea pero no puedo hacerlo funcionar.

Respuesta1

Puedes hacer todo el trabajo en awk:

#!/bin/sh
file=$2

awk -v theta="$1" -F '[= ]+' '
        $0 ~ theta { print $12; found++ }
        END        { if (!found) { print "Not available"; exit 1 } }' "$file"

Es posible que desee agregar manejo de errores para verificar que haya dos argumentos de línea de comando y $2que sea el nombre de un archivo legible, porque

  • Si $2no es un archivo legible, recibirá un mensaje de error deawk
  • si $2está en blanco o ausente, awkleerá silenciosamente desde la entrada estándar.

(Por supuesto, cualquiera de estos comportamientos o ambos podrían estar bien para usted).

Notas:

  • Puede obtener resultados más específicos cambiando $0 ~ thetaa $8 == theta.
  • Las variables en awkse inicializan en blanco. Esto se trata como 0 en contextos matemáticos, por lo que found++se establece founden 1 la primera vez que se ejecuta. Dije deliberadamente que found++en lugar de found = 1eso, si varias líneas coinciden con el valor theta, foundse establecerá en elnúmerode tales líneas. Parece que debería ser una condición de error; Si le preocupa, puede modificar el ENDbloque para informar un error si foundes distinto de 1.
  • Por supuesto, si necesita que su secuencia de comandos haga una cosa si se encuentra un valor y otra si no, puede eliminar la printdeclaración del ENDbloque y hacer que la secuencia de comandos simplemente pruebe awkel estado de salida y emita su propio mensaje de error. . También debe hacer esto si desea capturar la salida de awk(es decir, el valor θ2). Por el contrario, si todo lo que necesita es un mensaje de error legible por humanos y no necesita poder verificar el estado de salida, puede eliminar la exitdeclaración del ENDbloque.

Respuesta2

Prueba esto:

#! /bin/bash

file=input1.txt

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

Respuesta3

Parece que su lógica se puede reducir a:

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

...proporcionó un GNU grep, de todos modos. Aunque, si fuera yo, dejaría de lado el echo, o al menos lo haría...

! echo 'Not available.' >&2

...en cambio.

información relacionada