日付などの変数を含むいくつかの選択ステートメントをテキスト ファイルに保存したいです。
$ cat res.txt
select field1, field2 from log and log_time~'"${TODAY}"*'
このファイルを解析し、各ステートメントを実行するスクリプトを使用したいと思います。もちろん、${TODAY}
変数に置き換えられます。
残念ながら、${TODAY}
ファイルを読み込んだときに が日付に置き換えられることはありません...
これを実現する方法はありますか?
アップデート:
いくつかのSQL文を含むファイルを反復処理し、psql (postgres)を使用して実行したいとします。
ファイルは次のとおりです:
$cat sql.res
select path from log where log_host='toto' and log_time~'"${TODAY}"*' and log_msg='POLICY MISSING' and entry_status!='ACK' and path~'^/logs-${cli}/"${THREE_MONTHS_AGO}"_[0-9][0-9][0-9][0-9][0-9][0-9](_[0-9]{1,2}\.|\.)log(ptr|initial_ptr|account_ptr)?\.bz2$';
ここで、bash スクリプトで次の操作を実行します。
$cat script.sh
TODAY=$(date "+%Y-%m-%d")
THREE_MONTHS_AGO=$(date -d "$TODAY -91 days" "+%Y-%m-%d")
THREE_MONTHS_AGO_2=$(date -d "$TODAY -92 days" "+%Y-%m-%d")
ONE_MONTH_AGO=$(date -d "$TODAY -36 days" "+%Y-%m-%d")
ONE_MONTH_AGO_2=$(date -d "$TODAY -37 days" "+%Y-%m-%d")
YESTERDAY=$(date -d "$TODAY -1 day" "+%Y-%m-%d")
while read item; do
psql -P pager=off -t -c "$item" log | sed -e 's|^ *||' -e '/^$/d' > result.txt
done < sql.res
残念ながら、変数はスクリプトでは使用されません。そこで、eval を試しました。次のようになりました。
$while read item; do
c=$(echo $item | sed "s:':@:g" | sed "s:|:EE:g" | sed "s:(:AA:g" | sed "s:):BB:g" | sed 's:]{:TT:g' | sed 's|\.|OO|g')
b=$(eval echo ${c} 2>&1)
d=$(echo $b | sed "s:@:':g" | sed "s:EE:|:g" | sed "s:AA:(:g" | sed "s:BB:):g" | sed 's:TT:]{:g' | sed 's:OO:\\\.:g' )
echo "-> $b"
done < sql.res
しかし、私はいくつかの問題を抱えています
\.
答え1
変数文字列を値に置き換えるだけです。
sed -e "s/\${TODAY}/$TODAY/g" res.txt
しかし:
- 変数を信頼できるもの(提供されたDBによって作成されたものや、一般的なプログラミング言語APIの一部)で実行したことを必ず確認してください。ない自家製のもの脱出機構。
- また、文字をエスケープする必要があります特定の
sed
(各文字の前にバックスラッシュを追加することはできません)。 - おそらく意図せずに 2 レベルの引用符を使用しています。
- これにはBashよりも良い言語を使ってください。この種のものにはBashは最悪です。なぜなら、引用符やエスケープ処理が複雑で、本当に見逃しやすい特殊なケース。Python、Ruby、さらには PHP は、この種の問題を Bash よりもはるかにうまく処理します。