grepの結果をループ内の変数として保存するのに問題があります。
while read file;do
Server=$(echo $file | awk '{ print $1 }')
FDate=$(echo $file | awk '{ print $2 }')
ST=$(cat foobar | grep $Server | awk '{ print $3 }')
#ST=$(grep $Server foobar | awk '{ print $3 }')
echo "Server = $Server"
echo "FDate = $FDate"
echo "ST = $ST"
done < inputfile
最初のST varは、反復ごとに「Usage:grep [Option] ... Pattern [File]」出力を提供します。これは、コマンドが正しく読み取られていないことを意味します。
コメントアウトされた2番目のST変数は実際にスクリプト全体を中断し、エコーを試みると他のすべての変数が空になります。
これで、コマンドラインで同じことをしようとするとうまくいきます。
$ testme=$(cat foobar | grep Big | awk '{ print $3}'
$ echo "$testme"
tada
だから私の質問は、このgrepコマンドを変数に保存する方法です。パターンマッチングには可能な結果が1つしかないため、複数のマッチングについて心配する必要はありません。ただし、ループ内の各サーバーは、列3(tada、tada1、tada2)に異なる文字列を持つことができます。
編集する:
入力ファイルには、複数の列を含むサーバーのリストがあります。現在行の列1にリストされているサーバーをインポートし、foobarファイルから一致するものを検索し、列3から文字列を取得します。
「使用」メッセージが表示されるにもかかわらず、スクリプトが実際に機能していることがわかりました。入力ファイルの一部のサーバーエントリがfoobarファイルにまだ表示されていないため、grepに一致はありませんが、まだawkにパイプしようとする可能性があります。よくわかりません。
しかし、私はまだ「使用」メッセージを削除したいと思います。私の考えでは「set -opipelinefail」がうまくいくかもしれませんが、そうしない方が良いです。
ベストアンサー1
while read file;do # 1
Server=$(echo $file | awk '{ print $1 }') # 2
FDate=$(echo $file | awk '{ print $2 }') # 3
ST=$(cat foobar | grep $Server | awk '{ print $3 }') # 4
#ST=$(grep $Server foobar | awk '{ print $3 }') # 5
grep
少なくとも検索パターンが必要です(またはそれに対応するオプションを提供するかオプション-e
)。したがって、空の場合は、4行と5行の引用符なしの内容-f
$Server
$Server
噴射(あなたも見ることができます いつ二重引用符が必要ですか?)、そして
- 行4
grep
にはパラメータはありません。必須パラメーターがない場合は、使用法の説明が印刷されます。 - 行5では、
grep
単一のパラメータを取得してfoobar
パターンにします。基本的には標準入力から読み込み、ループ内にはループと同じ標準入力があるので、そこからすべてを読みます。
さて、ループ全体を見ると、次の質問が考えられます。シェルループを使用してテキストを処理するのはなぜ悪い習慣と見なされますか?少なくともある程度単純化することができます。read
入力はフィールド自体に分割できるため、コマンド置換を削除できます。
これにより、おそらく値のいずれかまたは両方が空の場合に対処する必要があります。そして、awkも作業を実行できるので、grep
次のようにしましょう。
while read server fdate; do
if [ -z "$server" ] || [ -z "$fdate" ]; do
continue
fi
ST=$(awk < foobar -v server="$server" '$0 ~ server { print $3 }')
echo "server $server fdate $fdate ST $ST"
done < inputfile
(または最終的に何をしたいかに応じて、全体をawkプログラムに置き換えます。)