web-dev-qa-db-ja.com

SynologyでのBASHとASHの使用

私の写真ファイルの大部分には、写真が撮影された日時を示す次の命名規則/形式IMG_20131204_120000.JPGがあります(iPhone/Appleの命名規則)。ただし、すべての写真がこの命名規則に従っているわけではありません。このフォーラムの助けを借りて、スクリプトを次のように進化させました。

for x in *.JPG *.jpg *.TIF *.tif *.PNG *.png *.BMP *.bmp *.GIF *.gif *.IMG *.img *.JPEG *.jpeg *.TIFF *.tiff; do
  d=$(date -r "$x" +%Y%m%d)" - Family Photos"
  if [[ "$x" =~ ^[iI][mM][gG][_-][1-2][09][0-9][0-9][0-1][0-9][0-3][0-9][_-][0-2][0-9][0-6][0-9][0-6][0-9][.][a-zA-Z]*$ ]]; then
    d=$(expr substr "$x" 5 8)" - Family Photos"
  fi
  mkdir -p "$d" >/dev/null 2>&1
  mv -- "$x" "$d/" >/dev/null 2>&1
done
rmdir ' - Family Photos' >/dev/null 2>&1

ファイル名がIMG_20131204_120000.JPGの形式の場合、ifステートメントを使用してファイル名自体から日付を取得します。この日付は写真が実際に撮影された日付を最も正確に反映しているためですが、ファイルがこの命名規則に従わないでください。ファイルが最後に変更/作成されたオペレーティングシステムの日付を使用します。

このスクリプトを毎晩実行して、過去24時間にアップロードされた写真を分類する予定です。私の問題は、SynologyシステムがBASHシェルではなくASHのみをサポートしているため、ifステートメントの正規表現=~が機能しないことです。 IPKGを使用してBASHパッケージをインストールできます。システムの他の部分が変更されておらず、ASHを使用しているときに、このスクリプトだけでBASHを使用する簡単な方法はありますか?または、ASHシェルを使用してifステートメントで同じことを行う方法はありますか?

2
Wags

Ashには正規表現はありませんが、Shellワイルドカードマッチングがあります。 caseを使用する必要があります。ワイルドカードの照合は、test a.k.a. [ … ]では利用できません。

ワイルドカードを使用して正規表現[a-zA-Z]*を表現する方法はありませんが、最初の部分と2番目の部分の2つのステップで同じテストを実行できます。

case "$x" in
  [iI][mM][gG][-_][1-2][09][0-9][0-9][0-1][0-9][0-3][0-9][_-][0-2][0-9][0-6][0-9][0-6][0-9][.]*)
    case "${x#*.}" in
      *[!a-zA-z]*) :;;
      *) d=${x#*[-_]}; d="${d%%[-_]*} - Family Photos";;
    esac
esac

プレフィックスとサフィックスのストリッピング構造は、すべてのPOSIXシェルに移植可能であり、exprを使用する必要はありません。