最初の引数を入力として読み取り、別のファイル内の変数を行ごとに検索する 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ファイルを実行するスクリプトを作成したいのですが、このファイルは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++の行がシータ値と一致する場合、 foundfound++found = 1found番号このような行があります。これはエラー状態であると思われます。心配な場合は、ブロックを変更して、が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

...その代わり。

関連情報