バッチファイルは、ファイル名に基づいてディレクトリ構造に移動します。

バッチファイルは、ファイル名に基づいてディレクトリ構造に移動します。

ファイル名に基づいてディレクトリにファイルを移動するスクリプトを作成しています。ファイルにはyyyyddmm-xxxxxxx.jpg名前の形式があります。必要なディレクトリ構造は次の形式に従います2013/01 Jan/31date月番号と月名の間のスペース形式を正しく指定できません。+%Y/%m %b型を使用しようとすると、次のエラーメッセージが表示されます。

日付: 追加オペランド `%b"'

私は二重引用符と一重引用符を試しましたが、成功しませんでした。ただし、date +"%Y/%m %b/%d"次の状況では正常に動作しますsh

2013年10月27日

MOVEDIRSTRまた、変数を使用するよりもディレクトリ名を生成するより良い方法がありますMOVEDIR(スクリプトを参照)。

これは私の現在のスクリプトです。

FLIST=`ls "$IMGDIR" | grep -E '^.*\.jpg$'`

# If there are files to move
if [ -n "${FLIST}" ]; then
    # For each file
    while read -r line; do
        # Parse filename to YYYY/mm Mmm/Dd
        echo $line
        MOVEDIRSTR=`sed -r -e 's:([0-9]{4})([0-9]{2})([0-9]{2}).*:date -d \1-\2-\3 +%Y/%m_%b/%d:' <<< "$line"`
        MOVEDIR=`$MOVEDIRSTR`

        # If a directory does not exist, create it
        [ -d "$ARCHIVEDIR/$MOVEDIR" ] || (mkdir -p "$ARCHIVEDIR/$MOVEDIR")

        # Move file into YYYY/mm Mmm directory
        # mv -f "$IMGDIR/$line" "$ARCHIVEDIR/$MOVEDIR"
    done <<< "$FLIST"
fi

答え1

+記号の後に日付形式を引用する必要があります。

$ date +"%Y/%m %b"
2013/10 Oct

変数について。$MOVEDIRSTR不要なようです。

MOVEDIR=$(sed -r -e 's:([0-9]{4})([0-9]{2})([0-9]{2}).*:date -d \1-\2-\3 +%Y/%m_%b/%d:' <<< "$line")

そのディレクトリの日付を解析しているので、$FLISTよりきれいな方法は見えません。

アップデート#1

以下の説明のOPからのフィードバックを考慮すると、彼はQNAPデバイスを使用しているため、BusyBoxが提供するこれらのコマンドのバージョンを弱めた可能性が高くなります。 dateコマンドを次のように見てみると、ls -l /bin/dateおそらくbusyboxまたは同様の実行可能ファイルへのリンクになります。これらのコマンドは完全に機能しないため、問題が発生します。

彼は次のように確認した。

あなたの言葉が正しいかもしれません。私の日付は独自の実行可能ファイルですが、/bin/sed -> busybox

これらの制限により、機能が制限されたツールを使用しているため、上記の方法が機能しない可能性があります。

答え2

まず、グローブを使って避けるためにlsを解析する.jpgこのロータリー方式でファイルのリストを取得します。次に、シェル自体(必須ではありませんsed)を使用して日付部分を抽出できます。

shopt -s nullglob
for file in "$IMGDIR"/*.jpg; do
    file_name="$(basename file)"
    printf "%s\n" "$file_name"
    numbers="${file%-*}"
    year="${numbers%[0-9][0-9][0-9][0-9]}"
    monthday="${numbers#[0-9][0-9][0-9][0-9]}"
    month="${monthday%[0-9][0-9]}"
    day="${monthday#[0-9][0-9]}"
    movedir="$(date -d "$year-$month-$day" +"%Y/%m %b/)"
    movefile="$(date -d "$year-$month-$day" +"%Y/%m %b/%d)"
    [ -d "$ARCHIVEDIR/$movedir" ] || mkdir -p "$ARCHIVEDIR/$movedir"
    mv "$file" "$movefile"
done

もちろん、dateこれはBusyBoxとは別の実行可能ファイルと呼ばれているので、コマンドに完全な機能セットがあるとします。日付文字列の長さが正確に8桁でない場合でも中断されます。

答え3

次に、この日付抽出と書式設定部分を解決することを確認してください。

$ f=20130131-abcdefgh.jpg
$ [[ $f =~ ^([[:digit:]]{4})([[:digit:]]{2})([[:digit:]]{2}) ]]
$ yyyy=${BASH_REMATCH[1]}
$ mm=${BASH_REMATCH[2]}
$ dd=${BASH_REMATCH[3]}
$ date -d ${yyyy}-${mm}-${dd} +'%Y/%m %b/%d'
2013/01 Jan/31

関連情報