私はしばしば同じパターンに従うKSHシェルスクリプトを書いています。
- (1) 1 つ以上のコマンド出力の検索
- (2) grep|cut|awk|sed でフォーマットし、画面やファイルに印刷します。
そのために、私はしばしば(1)の出力を一時ファイルに保存し、(2)のようにファイル形式を指定します。
次のコードを例に挙げます。
TMPFILE=file.tmp
# If tmpfile exists rm it.
[ -f $TMPFILE ] && rm -f $TMPFILE
for SERVICE in $(myfunc); do
getInfo $SERVICE > $TMPFILE # Store raw output in the TMPFILE
# I retrieve the relevant data from the TMPFILE
SERV_NAME=$(head -1 $TMPFILE | sed -e 's/ $//')
SERV_HOSTNAME=$(grep HOSTNAME $TMPFILE | cut -d "=" -f2)
SERV_ARGS=$(grep Arguments $TMPFILE | cut -d ":" -f2)
print $SERV_NAME $SEP $SERV_HOSTNAME $SEP $SERV_ARGS
rm -f $TMPFILE #rm the TMPFILE in vue of next iteration
done
毎回ファイルをディスクに書き込まないようにパイプ、リダイレクトなどを使用する方法はありますか?
役立つ場合は、kshバージョンM-11/16/88iを使用しています。
答え1
あなたのコードが一時ファイルを完全に合法的に使用しているようです。私はこの方法に固執します。本当に変更する唯一のことは、一時ファイルが生成される方法です。次のようなものを使用してください
TMP=$(tempfile)
または
TMP=$(mktemp)
または少なくとも
TMP=/tmp/myscript_$$
これにより、名前を簡単に予測でき(同時に)同時に実行される複数のスクリプトインスタンス間の干渉を排除できなくなります。
答え2
変数を使用できます。
info="$(getInfo $SERVICE)"
SERV_NAME="$(head -1 $TMPFILE <<<"$info" | sed -e 's/ $//')"
...
からman ksh
:
<<<word A short form of here document in which word becomes the
contents of the here-document after any parameter expan-
sion, command substitution, and arithmetic substitution
occur.
利点は次のとおりです。
- 並列実行を有効にします。
- 私の経験では、これは一時ファイルよりはるかに高速です。データが多すぎて交換が必要でない限り、速度ははるかに速くなければなりません(小さいデータサイズの場合はより高速なHDキャッシュバッファを除く)。
- 他のプロセスやユーザーがあなたのデータを台無しにすることはできません。
答え3
2つのオプションがあります。
データを一度(例では
getInfo
)検索してファイルに保存します。データは毎回インポートされ、ローカルには保存されません。つまり、
getInfo
呼び出されるたびに
再処理/再インポートを防ぐために一時ファイルを生成することに問題はありません。
一時ファイルをどこかに残すことが心配な場合は、trap
スクリプトが終了/中断された場合は常に削除したことを確認するために使用できます。
trap "rm -f $TMPFILE" EXIT HUP INT QUIT TERM
mktemp
一時ファイルの一意のファイル名を作成するために使用されます。
答え4
ファイルを生成する代わりに、シェル割り当てステートメントを構成して出力を評価します。
for SERVICE in $(myfunc); do
eval $(getInfo $SERVICE |
sed -n -e '1/\(.*\) *$/SERV_NAME="\1"/p' \
-e '/HOSTNAME/s/^[^=]*=\([^=]*\).*/SERV_HOSTNAME="\1"/p' \
-e '/Arguments/^[^:]*:\([^:]*\).*/SERV_ARGS="\1"/p')
print $SERV_NAME $SEP $SERV_HOSTNAME $SED $SERV_ARGS
done
または情報のみを印刷したい場合:
for SERVICE in $(myfunc); do
getInfo $SERVICE | awk -vsep="$SEP" '
BEGIN{OFS=sep}
NR == 1 { sub(/ *$/,""); SERV_NAME=$0 }
/HOSTNAME/ { split($0, HOST, /=/; SERV_HOSTNAME=HOST[2]; }
/Arguments/ { split($0, ARGS, /:/; SERV_ARGS }
END { print SERV_NAME, SERV_HOSTNAME, SERV_ARGS }'
done