
У меня есть файл «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
...вместо.