シェルスクリプト変数構造

シェルスクリプト変数構造

次の形式のファイル名で変数を生成するには:

ファイル名パターン:SnapshotIR__somenumber.csv

私は次のことを試しました:

TODAY=$(date +"%m%d%Y")    
SNAPSHOT = $(SnapshotIR$TODAY*.csv)

次のエラーが発生します。

test.sh: line 2: SnapshotIR02122013_2239.csv: command not found
test.sh: line 2: SNAPSHOT: command not found

だからifと一緒に使いたいとき

if [ -f SnapshotIR$TODAY*.csv]  -> works 
if [ -f ${SNAPSHOT} ]           -> does not work (I get the above error)

ベストアンサー1

SNAPSHOT = $(SnapshotIR$TODAY*.csv)

課題にはスペースを含めることはできません。$(…)しかも、コマンドの置き換え:この行はSnapshotIR02122013_2239.csvプログラムで実行しようとします。

bash、ksh、またはzshは、SNAPSHOT一致するファイル名のリストを含む配列に設定します。

SNAPSHOT=("SnapshotIR$TODAY"*.csv)

一致するファイルがない場合、パターンは拡張されません。 Bashまたはzshからnullglob空の配列を取得するオプションを設定します。 kshは~(N)パターンの先頭に配置されます(例SNAPSHOT=(~(N)"SnapshotIR$TODAY"*.csv):)。その後、配列の長さをテストして、一致するファイルがあるかどうかをテストできます。

shopt -s nullglob
SNAPSHOT=("SnapshotIR$TODAY"*.csv)
if [ ${#SNAPSHOT} -eq 0 ]; then
  echo 1>&2 "No snapshot file for $TODAY"
  exit 2
elif [ ${#SNAPSHOT} -gt 1 ]; then
  echo 1>&2 "Multiple snapshot files for $TODAY, I don't know which one to pick"
  exit 2
fi
echo "The snapshot file is ${SNAPSHOT[0]}"

配列のないシェルでは、一致項目のリストを受け取り、数を計算する関数を使用できます。一致するものがない場合、関数は拡張されていないパターンを受け取ります。

set_snapshot () {
  if [ $# -gt 1 ]; then
    echo 1>&2 "Multiple snapshot files for $TODAY, I don't know which one to pick"
    exit 2
  elif [ -e "$1" ]; then
     SNAPSHOT=$1
  else
    echo 1>&2 "No snapshot file for $TODAY"
    exit 2
  fi
}
set_snapshot "SnapshotIR$TODAY"*.csv
echo "The snapshot file is $SNAPSHOT"

(1桁の名前のファイルはありませんが、5文字の名前のファイルがあるなど、病理的な場合は、[ -e "$1" ]パターンが拡張されていないかどうかをテストするために使用すると失敗します。)またはメタ文字が一致するためです。[0-9][0-9]*?

次の方法はある程度効果があります。

SNAPSHOT=SnapshotIR$TODAY"*.csv
if [ -e $SNAPSHOT ]; then …

拡張は$SNAPSHOT引用されていないため、スペースで区切られたワイルドカードパターンのリストとして扱われます。ここでは大丈夫です。ただし、一致するファイルが複数ある場合、コマンドは一致を別の引数として扱うため、[構文エラーが発生します。 (特別に細工されたファイル名を使用すると誤った結果が生じる可能性があります。)したがって、この方法は壊れやすいので推奨しません。

おすすめ記事