Bashスクリプトで日付を比較する方法

Bashスクリプトで日付を比較する方法

ファイル構造内の最も古いディレクトリを確認するためにbashにスクリプトを作成しようとしています。

この例には、生成された日時を模倣したタイトルを持つ4つのディレクトリがあります。これらのファイルは、2022-02-21:20:30:23およびです。この場合、日付は任意であり、単にスクリプトテスト用に開発されました。2022-02-21:22:30:232022-02-28:22:30:232023-02-28:22:30:23

私はスクリプトがそのディレクトリ内に存在するディレクトリを識別し、ディレクトリ名に基づいて最も古いディレクトリを識別できるようにしたいと思います。

私の最初の試みは次のとおりです。はい、文字列が日付として正しく宣言されていないことを知っていますが、これを行う方法がわからず、いくつかのアドバイスを使用できます。

oldest="1899-01-01:01:01:01"
dirs=`ls -d */`
for i in $dirs ; do
    if [[ oldest < $i  ]] ; then
        oldest=$i
    fi
done
echo $oldest

答え1

(私はあなたが示す命名規則があなたのためであると仮定します。目次そして、最も古いディレクトリを探したいです。私は無視した文書このディレクトリに。 )

命名規則に応じて、ディレクトリ名は拡張シェル glob によって自動的に正しくソートされ、*/最も古いディレクトリ名が最初に拡張されます。デフォルトでは、シェルはアルファベット順に一致する名前を提供します。

*/これは、ワイルドカードパターンを拡張し(正確に一致すると仮定)、結果を配列に保存し、その配列の最初と最後の要素を確認して、最も古い最新のディレクトリを取得できることを意味します。

dirs=( */ )
printf 'Oldest dir by name is "%s"\n' "${dirs[0]}"
printf 'Newest dir by name is "%s"\n' "${dirs[-1]}"

上記の「最も古い名前/最新の名前」を参照してください。実際に「事前順で最初/最後のソート」を意味します。

/出力ディレクトリー・パスの尾を削除するには、標準パラメーター置換を使用します。

dirs=( */ )
printf 'Oldest dir by name is "%s"\n' "${dirs[0]%/}"
printf 'Newest dir by name is "%s"\n' "${dirs[-1]%/}"

答え2

ファイル名がすべてこのYYYY-MM-DD:HH:MM:SS形式でファイル名が重要な場合は、アルファベット順に並べ替えることができます。たとえば、次は最も古い名前のフォルダーでなければなりません。

printf "%s\n" */ | sort | head -n1

答え3

ファイル名は常にこの形式をとりますかYYYY-mm-dd:HH:MM:ss?そうすれば、数字だけを扱えば良いので簡単です。すでに述べた@muruのようにを使用することがsort最も直感的な方法になります。このように:ls -d --format=single-column */ | sort | head -n 1

変更日を使用するには、ls直接使用できます。

ls -dt --format=single-column */ | head -n 1 # most recent modification date
ls -dt --format=single-column */ | tail -n 1 # oldest modification date

-d:ディレクトリのみ表示します。 -t:日付順に並べ替えます。 single-column:(ファイル)名前のみを表示します。 */

クラシックif a < b; then min = bループは、bashでセットの最大/最小数を見つけるための基本的な方法です。しかし、翻訳もできます。日付文字列を数値に変換してdatebash組み込み関数を使用できます[ .. -t .. ]。これはあなたの特定の状況には適用されません。date- 現在の日付は最初のコロン(YYYY-mm-dd HH:MM:SS)のために解析できません。:

# mind the space ---v
filename='1989-06-08 12:42:00'
number=$(date -d "$filename" '+%s'))
# 'date' values can directly be compared:
now=$(date '+%s')
if [ number -lt  now ]; then
  echo $(date -d "number") was in the past.
else
  echo $(date -d "number") is in the future.
fi
  

関連情報