変数から空白で区切られた文字列の単一引用符を置き換えます

変数から空白で区切られた文字列の単一引用符を置き換えます

私は次の 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 つの文字列として取得するのではなく、複数の引数文字列として取得します。コマンドラインを文字列に分割するのはシェルです。

readBash で複数の値を取得したい場合は、 を使用して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[@]}"適切な配列の場合は、の代わりにを常に使用することをお勧めします[*]

見る:単語の分割シェル スクリプトが空白文字やその他の特殊文字で動作しなくなるのはなぜですか?そして配列

関連情報