bash-скрипт для чтения первого аргумента в качестве входных данных и поиска переменной в другом файле строка за строкой

bash-скрипт для чтения первого аргумента в качестве входных данных и поиска переменной в другом файле строка за строкой

У меня есть файл «input.txt» с переменными A1, A2, A3, θ, θ1 и θ2 — пример input.txt выглядит следующим образом:

$ 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

Я хочу создать скрипт для запуска файла input.txt - этот файл будет передан как второй аргумент, первым аргументом будет значение θ

Я создал следующий скрипт:

#! /bin/bash

file=input1.txt

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

else

echo "Not available"
fi
}

Но когда я запускаю этот скрипт следующим образом:

./script space input.txt   

(первый аргумент — значение θ, а второй аргумент — имя файла), вывод — все значения в поле 12:

$ ./script1 space input1.txt 
1.2
3.9

на выходе должно быть только 1.2, я поискал и обнаружил, что мне нужно создать цикл для построчного чтения файла, но я не могу заставить его работать.

решение1

Вы можете выполнить всю работу в awk:

#!/bin/sh
file=$2

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

Возможно, вы захотите добавить обработку ошибок, чтобы убедиться, что есть два аргумента командной строки, и $2это имя читаемого файла, потому что

  • если $2это что-то, что не является читаемым файлом, вы получите сообщение об ошибкеawk
  • если $2пусто или отсутствует, awkбудет молча прочитано со стандартного ввода.

(Конечно, любой из этих вариантов поведения или оба они могут быть для вас приемлемы.)

Примечания:

  • Вы можете получить более точные результаты, изменив $0 ~ thetaзначение на $8 == theta.
  • Переменные в awkинициализируются пустыми. Это рассматривается как 0 в математических контекстах, поэтому found++устанавливается foundв 1 при первом выполнении. Я намеренно сказал found++вместо found = 1этого, если несколько строк соответствуют значению тета, foundбудет установлено вчислотаких строк. Кажется, это должно быть условием ошибки; если вас это беспокоит, вы можете изменить блок ENDтак, чтобы он сообщал об ошибке, если foundэто что-то, кроме 1.
  • Конечно, если вам нужно, чтобы ваш скрипт делал что-то одно, если значение найдено, и что-то другое, если нет, вы можете удалить оператор printиз ENDблока и заставить скрипт просто проверить awkстатус выхода и выдать собственное сообщение об ошибке. Вы также должны сделать это, если хотите захватить вывод из awk(т. е. значение θ2). И наоборот, если вам нужно только понятное человеку сообщение об ошибке, и вам не нужно иметь возможность проверять статус выхода, вы можете удалить оператор exitиз ENDблока.

решение2

Попробуй это:

#! /bin/bash

file=input1.txt

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

решение3

Похоже, вашу логику можно свести к следующему:

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

...в любом случае предоставили GNU grep. Хотя, если бы это был я, я бы отказался от echo, или, по крайней мере, сделал бы...

! echo 'Not available.' >&2

...вместо.

Связанный контент