web-dev-qa-db-ja.com

ファイル名のタイムスタンプを変更するにはどうすればよいですか?

私は日付順にdatファイルの名前を持っています:

FileName_YYYY_MM_DD_HHMM.dat

各タイムスタンプに30分を追加するコマンドはありますか?

8
strawberrie

pythonを使用:

#!/usr/bin/env python2
import glob, re, os, datetime
os.chdir('/path/to/dir')
for f in glob.glob('*.dat'):
    ini_time = datetime.datetime.strptime(re.search(r'(?<=_)(?:\d|_)+(?=.dat$)', f).group(), '%Y_%m_%d_%H%M')
    fin_time = (ini_time + datetime.timedelta(minutes=30)).strftime('%Y_%m_%d_%H%M%S')
    os.rename(f, 'Filename_' + str(fin_time) + '.dat')
  • os.chdir('/path/to/dir')は、現在のディレクトリを.datファイルを含むディレクトリに変更します。 /path/to/dirを実際のパスに置き換えます。

  • glob.glob('*.dat')は、.datで終わるファイルを検索します

  • ini_time変数は、最初にreモジュールを使用して元のファイル名から日時を切り取り、次に、必要な時間を追加できるように、取り出した文字列の内容を表すエントリを整理します。これに

  • fin_timeには結果の時間、つまりini_timeに30分が含まれます

  • os.renameはそれに応じてファイルの名前を変更します。

また、ファイル名が連続すると(30分異なる)、名前が変更されたファイルは次のファイルを上書きするため、名前が変更されたファイル名に秒を追加して安全を確保することをお勧めします。それ以外の場合は、名前を変更したファイルを別のディレクトリに保存し、後で元のファイルに置き換える必要があります。

6
heemayl

bashを使用すると、名前が変更されたファイルは新しいサブフォルダーrenamedにあります。

ファイルが置かれているフォルダーでスクリプトを開始します。

#!/bin/bash

mkdir -p renamed   

# loop over all dat files in the current folder
for f in *.dat; do

    # the filename without extension    
    filename="${f%%.*}"

    # your timestamp
    old_timestamp=$(echo $filename | grep -P "[0-9]{4}_[0-9]{2}_[0-9]{2}_[0-9]{4}$")

    if [ "$old_timestamp" == "" ]; then
        >&2 echo "not a valid filename: '$f', skipped."
    else
      # a valid date from the timestamp
      new_date=$(echo "$old_timestamp" | awk -F_ '{HM=NF; D=NF-1; M=NF-2; Y=NF-3; print $Y "-" $M "-" $D " " substr($HM,1,2) ":" substr($HM,3,2) ":00"}')

      # the new time stamp, 30 mins in the future
      changed_timestamp=$(date --date "$new_date 30 minutes" "+%Y_%m_%d_%H%M")

      # copy the file, ${f##*.} is the extension
      cp "$f" renamed/"${filename/$old_timestamp/$changed_timestamp.${f##*.}}"
    fi
done

出力例:

% ls -og FileName*
-rw-rw-r-- 1 0 Mai 16 20:35 FileName_2015_05_16_2235.dat

% ./timestamp

% ls -og renamed/FileName*
-rw-rw-r-- 1 0 Mai 16 20:35 FileName_2015_05_16_2305.dat
2
A.B.

スクリプト

これは、元のスクリプトの編集バージョンです。 OPは元々、命名形式に関する完全な情報を提供していませんでした。このスクリプトは、コメントで言及されたOPが正しいファイル命名であることに適応します。

*テクニカルノート:*

このスクリプトでは、awkを使用して、ファイル名をフィールド区切り文字としてアンダースコアを使用して6つの個別のフィールドに分けています。最初の2つのフィールド、$ 1および$ 2は静的テキスト文字列と見なされます。フィールド3、4、5、および6は、OPのデータがサンプリングされたタイムスタンプであり、ファイルシステムでのファイルの作成日ではありませんnot

変数COPYDIRは、タイムスタンプが更新されたファイルが保存される新しいディレクトリの名前を保持します。 mkdir $COPYDIRを使用して、現在の作業ディレクトリにそのディレクトリを作成します

変数TEXTSTRINGとDATESTRINGは、それぞれ静的テキストとタイムスタンプを保持します。以下の出力例では、2つの異なる文字列を使用して、最初の2つのフィールドに含まれるテキストに関係なくスクリプトが機能することを証明しました。

NEWEPOCHTIMEは、計算された新しいタイムスタンプをUNIXエポック形式で保持する変数です。 NEWDATEは、Unix EpochからYYYY-MM-DD HH:MM形式に変換されたタイムスタンプを保持する変数です。 NEWAPPENDは、OPの希望するYYYY_MM_DD_HHMM形式でファイルに追加される実際のタイムスタンプです。

cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".datは、更新されたデータスタンプを使用して、古いファイルを(移動ではなく、データ損失を防ぐために)「converted_files」ディレクトリにコピーします。

注意、命名形式が本当にに従っている限り、スクリプトは機能します。つまり、すべてのファイルはreallySomeText_123.Data_YYYY_MM_DD_HHMM.dat形式です。

#!/usr/bin/env bash
#
# Author: Serg Kolo
# Description: this script takes timestamp within the filename
# (which may be different from file's actual creation date)
# converts that date and time to unix's Epoch time
# adds 30 minutes to it and renames it

COPYDIR="converted_files"
mkdir $COPYDIR

for file in *.dat; do
        TEXTSTRING=$(stat -c %n $file | awk -F'_' '{print $1"_"$2"_"}' )
        DATESTRING=$( stat -c %n $file | awk -F'_' '{gsub(".dat","");  print $3"-"$4"-"$5" "$6}' )
        NEWEPOCHTIME=$( expr $( date --date="$DATESTRING" +%s ) + 1800 )
        NEWDATE=$(date --date=@"$NEWEPOCHTIME" +%F"_"%R)
        NEWAPPEND=$(echo $NEWDATE | awk '{gsub("-","_");gsub(":","");print}')
        cp $file "$COPYDIR"/"$TEXTSTRING""$NEWAPPEND".dat
done

SCRIPT IN ACTION

以下のデモは、私の端末から直接コピーしたものです。最初の2つのフィールドに2つの異なる文字列を持つ元のファイルを作成したことに注意してください。そのため、実際にはアンダースコアで区切られた2つの文字列のみが存在する限り、このスクリプトはファイル名の先頭に関係なく動作するはずです。

この質問に取り組んでいる間に取ったメモからスクリプトを開発したため、スクリプトはnotes-conversionと名付けられました。

HHMM部分が2345(真夜中の15分前)であるファイル名は0015に更新され、DD部分は翌日に更新されます。 24時間形式が保持されます。

さらに、forループは.datファイルのみを検索するため、作業ディレクトリにある可能性のある他のファイルまたはディレクトリの名前を変更することを避け、潜在的なデータ損失を防ぎます。次の例では、元のディレクトリには11個のアイテムがあり、そのうち3個はテスト用の*.txtファイルであるため、8個の.datファイルのみを使用します。更新されたファイルが保存されるディレクトリには、すべての.datがあり、他のファイルはない8つのファイルがあります。データは安全です、スクリプトはその仕事をします。

[68 ]SERGIY@UBUNTU_[/home/xieerqi/testdir/conversion/convert2]
***********************************************
85 $ ls
FileName_123.Dat_2015_05_31_1245.dat  Test.txt
FileName_123.Dat_2015_05_31_2345.dat  YoloSwag_123.Dat_2015_05_31_1245.dat
FileName_Foo.Bar_2015_05_31_1245.dat  YoloSwag_123.Dat_2015_05_31_2345.dat
FileName_Foo.Bar_2015_05_31_2345.dat  YoloSwag_Foo.Bar_2015_05_31_1245.dat
File.txt                              YoloSwag_Foo.Bar_2015_05_31_2345.dat
Random.txt

[68 ]SERGIY@UBUNTU_[/home/xieerqi/testdir/conversion/convert2]
***********************************************
86 $ ls | wc -l
11

[68 ]SERGIY@UBUNTU_[/home/xieerqi/testdir/conversion/convert2]
***********************************************
87 $ notes-conversion                                                                                

[68 ]SERGIY@UBUNTU_[/home/xieerqi/testdir/conversion/convert2]
***********************************************
88 $ ls converted_files/; ls converted_files/ | wc -l                                                
FileName_123.Dat_2015_05_31_1315.dat  YoloSwag_123.Dat_2015_05_31_1315.dat
FileName_123.Dat_2015_06_01_0015.dat  YoloSwag_123.Dat_2015_06_01_0015.dat
FileName_Foo.Bar_2015_05_31_1315.dat  YoloSwag_Foo.Bar_2015_05_31_1315.dat
FileName_Foo.Bar_2015_06_01_0015.dat  YoloSwag_Foo.Bar_2015_06_01_0015.dat
8

[67 ]SERGIY@UBUNTU_[/home/xieerqi/testdir/conversion/convert2]
***********************************************
89 $ 

EXPLANATION(元の投稿から)

*)今日、Unix-Linuxシステムは エポック時間 で時間をカウントすること、または単に秒を入れることを学びました。

*)スクリプトは各ファイル名を取得し、日付を抽出してエポックに変換し、1800秒(正確には30分)を追加し、新しいタイムスタンプでファイルを保存します。

*)このスクリプトは、OPの要求に対応します-ファイル自体の作成時間を更新するのではなく、ファイル名のタイムスタンプを変更します

使用ツール:

  • ubuntu 15.04

  • GNU bash 4.3.30

  • GNU awk 4.1.1

  • 日付(GNU coreutils)8.23

1