私は次の 2 つの文字列を介して変数を読み込む bash スクリプトを書いていますread
:
log.*.console.log log.*.log
それらはスペースで区切られます。
スクリプト内で呼び出される次のプログラムの変数からの出力がこの形式になるように文字列を書き換えるにはどうすればよいでしょうか?'log.*.console.log' 'log.*.log'
sed と awk を試してみましたが、どうもうまくいきませんでした。
スクリプト全体:
#!/bin/bash
if [ -z "$*" ] ; then
echo "USAGE: ./some text"
exit 1
else
echo "some text"
read varlogname
i=1
for file in $@
do
echo "Doing" $file
GTAR=$(gtar -xvf $file --wildcards --ignore-case --no-anchored "$varlogname")
for file in ${GTAR[*]}
do
mv $file $file"."${i}
i=$((i+1))
done
done
echo "Files extracted."
fi
exit 0
答え1
に一重引用符を付けるのは好ましくないと思いますgtar
。 などのコマンドではsomecmd 'foo bar' 'files*.log'
、シェルが引用符を処理し、特殊文字を特別に扱わないように指示し、somecmd
引数foo bar
と を渡しますfiles*.log
。 Unix プログラムは、コマンドラインを 1 つの文字列として取得するのではなく、複数の引数文字列として取得します。コマンドラインを文字列に分割するのはシェルです。
read
Bash で複数の値を取得したい場合は、 を使用してread -a array
、配列をコマンドに渡すことができます。
-a array assign the words read to sequential indices of the array
variable ARRAY, starting at zero
つまり
read -a filenames
gtar "${filenames[@]}"
配列を[@]
(引用符で囲んで) でインデックスすると、配列メンバーが個別の単語として展開されます。これが目的の動作です。
また、 がありますfor file in ${GTAR[*]}
。これはGTAR
配列としてアクセスしているように見えますが、配列ではなく、gtar
コマンドの出力を文字列として割り当てているだけです。この場合、${GTAR[*]}
は と同じです$GTAR
。展開が引用符で囲まれていないため、文字列はこの時点で単語分割され、デフォルトでは空白で分割されます。しかし、その後、単語はまたファイル名のグロブとして取得され、一致するファイル名に展開されます。
ファイル名に空白やグロブ文字 ( が含まれていない限り*?[]
、これは問題ありません。ただし、一般的には、これは望ましいことではありません。
"${array[@]}"
適切な配列の場合は、の代わりにを常に使用することをお勧めします[*]
。