
ファイル「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ファイルを実行するスクリプトを作成したいのですが、このファイルは2番目の引数として渡され、最初の引数はθの値になります。
次のようなスクリプトを作成しました。
#! /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
(最初の引数はθの値、2番目の引数はファイル名)、出力はフィールド12のすべての値になります。
$ ./script1 space input1.txt
1.2
3.9
出力は 1.2 のみになるはずです。検索したところ、ファイルを 1 行ずつ読み取るループを作成する必要があることがわかりましたが、動作させることができません。
答え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
読み取り可能なファイルの名前であることを確認するためのエラー処理を追加する必要があるかもしれません。
$2
読み取り可能なファイルでない場合は、エラーメッセージが表示されます。awk
$2
が空白または存在しない 場合は、awk
標準入力から黙って読み取ります。
(もちろん、これらの動作のどちらか、または両方があなたにとって問題ないかもしれません。)
ノート:
$0 ~ theta
に変更すると、より的を絞った結果が得られる可能性があります$8 == theta
。- 変数は
awk
空白に初期化されます。これは数学的なコンテキストでは0として扱われるため、最初に実行されると1に設定されます。代わりに意図的にそう言いました。複数found++
の行がシータ値と一致する場合、found
found++
found = 1
found
番号このような行があります。これはエラー状態であると思われます。心配な場合は、ブロックを変更して、が1 以外の場合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
...その代わり。