ファイル名の日付に基づいてファイルをコピーする

ファイル名の日付に基づいてファイルをコピーする

ファイル名に含まれる日付に基づいて一連のファイルをあるディレクトリから別のディレクトリにコピーしようとすると問題が発生します。ファイル名の日付は UTC 時間、生成日は CST 時間です。ディレクトリに含まれるすべてのファイル名には、次のようなファイル名があります。

foo_20160227_0015.gif
foo_20160227_0030.gif
.....
.....
foo_20160304_0030.gif
foo_20160304_0045.gif

私が使用したいスクリプトは次のとおりです。

# Variables
strPrevDay=$(date +"%Y%m%d" -d "yesterday")
str7DaysAgo=$(date +"%Y%m%d" -d "7 days ago")
strImgDir="~/Documents/Projects/Radar/Images/"
strTmpImgDir="~/Documents/Projects/Radar/Images/Temp/"
strFileName="foo_"
strFile=

# Copy files created in the last week
for f in $strImgDir$strFileName{$str7DaysAgo..$strPrevDay}*.gif; do cp "$f" $strTmpImgDir; done

スクリプトが実行された後、次のエラーメッセージが表示されます。

cp: cannot stat ‘/home/user/Documents/Projects/Radar/Images/foo_{20160227..20160304}*.gif’: No such file or directory

ベストアンサー1

このエラーは、中{$str7DaysAgo..$strPrevDay}かっこが最初に拡張された後(フォームではないため、何もしません)変数が拡張されるために発生します。これはバッシュトラップです。{NUMBER1..NUMBER2}

日数を計算するために7日を使用するのは無理ではありませんdate。バラよりジェフ・シャラーの答え

別の選択肢は、eval評価が望ましい順序で行われるように強制することです。 2回評価される部分には非常に注意する必要があるため、使用エラーが発生しやすいが、evalここではファイル名部分に数字だけが含まれていることを知っているので問題にはなりません。必要な点を参考にしてくださいnullglobこのオプションをオンにしてください数日間ファイルが生成されない場合。

#!/bin/bash
last_day=$(date +"%Y%m%d" -d "yesterday")
first_day=$(date +"%Y%m%d" -d "7 days ago")
eval "all_days=({$first_day..$last_day})"
image_directory=~/Documents/Projects/Radar/Images/
temporary_directory="$image_directory/Temp/"
filename_prefix="foo_"
shopt -s nullglob
for day in "${all_days[@]}"; do
  files=("$image_directory/$filename_prefix$day"*.gif)
  if [[ ${#files[@]} != 0 ]]; then
    cp "${files[@]}" "$temporary_directory"
  fi
done

VAR="~/something"(引用符と読みにくい変数名も修正しましたVAR。他のシェル特殊文字が含まれている場合は中断されます。

別のアプローチは、ファイルを列挙し、目的の範囲内のファイルのみをコピーすることです。ワイルドカードを使用するたびにディレクトリ内のファイルを列挙する必要があるため、範囲が大きい場合は高速になります(特定のパターンに一致するファイルを取得するより高速な方法はありません)。

#!/bin/bash
last_day=$(date +"%Y%m%d" -d "yesterday")
first_day=$(date +"%Y%m%d" -d "7 days ago")
image_directory=~/Documents/Projects/Radar/Images/
temporary_directory="$image_directory/Temp/"
filename_prefix="foo_"
shopt -s nullglob
for file in "$image_directory/$filename_prefix"*.gif; do
  file_date="${file##*/"$filename_prefix"}"; file_date=${file_date:0:8}
  if ((file_date >= first_day && file_date <= last_day)); then
    cp "$file" "$temporary_directory"
  fi
done

おすすめ記事