ฉันจะเปลี่ยนการประทับเวลาของชื่อไฟล์ได้อย่างไร


8

ฉันมีชื่อไฟล์ dat ตามลำดับเวลา:

FileName_YYYY_MM_DD_HHMM.dat

มีคำสั่งใด ๆ สำหรับเพิ่ม 30 นาทีในแต่ละการบันทึกหรือไม่


1
การประทับเวลาเหล่านั้นเหมือนกับวันที่สร้างหรือไม่ มันเหมือนกันls --full-timeไหม
Sergiy Kolodyazhnyy

1
ไม่การประทับเวลาจะแตกต่างจากวันที่สร้าง / แก้ไข การประทับเวลาจะขึ้นอยู่กับเวลาที่ข้อมูลถูกวัด
strawberrie

1
ดูเนื่องจากการประทับเวลาเหล่านั้นเป็นแบบกำหนดเองจึงต้องมีสคริปต์ที่ต้องคำนวณการเพิ่ม 30 นาทีในวันที่จึงไม่มีคำสั่งง่ายๆ ดังนั้นอาจต้องใช้เวลาสักหน่อยเพื่อให้ผู้คนตอบกลับ
Sergiy Kolodyazhnyy

1
มีการประทับเวลาใด ๆ ที่ใกล้ถึงเที่ยงคืนหรือไม่เช่นนั้นการเพิ่ม 30 นาทีอาจส่งผลให้ต้องเปลี่ยนวันละหนึ่งครั้ง?
Sergiy Kolodyazhnyy

1
รูปแบบชั่วโมงคืออะไร? 12 จากนั้น 1,2,3 (รูปแบบ 12 ชั่วโมง) หรือ 12 ถึง 13 ถึง 14, 15 . . 23, 00 (รูปแบบ 24 ชั่วโมง)
Sergiy Kolodyazhnyy

คำตอบ:


6

การใช้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 นาที) ไฟล์ที่ถูกเปลี่ยนชื่อจะเขียนทับชื่อถัดไปดังนั้นจึงเป็นการดีกว่าที่จะเพิ่มวินาทีในชื่อไฟล์ที่ถูกเปลี่ยนชื่อเพื่อให้มันปลอดภัย มิฉะนั้นคุณต้องบันทึกไฟล์ที่เปลี่ยนชื่อไปยังไดเรกทอรีอื่นแล้วแทนที่ด้วยไฟล์เดิมในภายหลัง


คุณและหลามเป็นความรักที่ยิ่งใหญ่ =) +1
AB

คุณไม่ควรใช้สตริงFilename_ในวิธีการเปลี่ยนชื่อ
AB

@AB ทำไมถึงเป็นเช่นนั้น (+1 สำหรับคุณด้วย)
heemayl

คุณรู้หรือไม่ว่าทำไมฉันถึงมีบางไฟล์หายไปหลังจากเรียกใช้สคริปต์ python เวลาประทับสำหรับแต่ละไฟล์มีความแตกต่าง 30 นาที ด้านล่างนี้คือการส่งออกไม่กี่ชื่อไฟล์แรก: Filename_2011_01_11_1630.dat Filename_2011_01_11_1830.dat Filename_2011_01_11_1900.dat Filename_2011_01_11_2030.dat Filename_2011_01_11_2100.dat
strawberrie

@strawberrie ฉันไม่รู้ .. มันได้ทดสอบแล้วและทำงานได้ดีสำหรับฉันโดยไม่มีปัญหาใด ๆ ... คุณเรียกใช้สคริปต์แทนที่/path/to/fileด้วยพา ธ เต็มไปยังไดเรกทอรีหรือไม่
heemayl

2

การใช้ไฟล์เปลี่ยนชื่ออยู่ในโฟลเดอร์ย่อยใหม่bashrenamed

เริ่มสคริปต์ในโฟลเดอร์ที่มีไฟล์อยู่

#!/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

@strawberrie ไฟล์ที่ถูกเปลี่ยนชื่อจะถูกวางไว้ในโฟลเดอร์ย่อยrenamed
AB

ขอแนะนำให้บันทึกไฟล์ที่เปลี่ยนชื่อไว้ในโฟลเดอร์พิเศษ ในกรณีที่บางอย่างผิดปกติ OP ยังคงมีต้นฉบับอยู่ การคิดที่ดีจึง +1
Sergiy Kolodyazhnyy

ขอบคุณ @AB ฉันได้รับข้อผิดพลาดต่อไปนี้หลังจากเรียกใช้สคริปต์ของคุณ: TimeChange.sh: 21: TimeChange.sh: การทดแทนที่ไม่ดีชื่อไฟล์จริงของฉันหรือคำนำหน้าคงที่ก่อนการประทับเวลาจะเป็นเหมือน FileName_123.Data_YYYY_MM_DD_HHMM.dat
strawberrie

สำหรับคำจำกัดความFileName_123.Data_YYYY_MM_DD_HHMM.datส่วนหนึ่ง.Data_YYYY_MM_DD_HHMM.datคือส่วนขยาย และดังนั้นจึงFileName_123ไม่ใช่เวลาประทับที่ถูกต้อง
AB

@strawberrie ฉันมีการเปลี่ยนแปลงสคริปต์ของฉัน
AB

1

SCRIPT

นี่เป็นเวอร์ชันดั้งเดิมของสคริปต์ต้นฉบับของฉัน OP เดิมไม่ได้ให้ข้อมูลเต็มรูปแบบเกี่ยวกับรูปแบบการตั้งชื่อ สคริปต์นี้ปรับให้เหมาะกับสิ่งที่ OP กล่าวถึงในความคิดเห็นคือการตั้งชื่อไฟล์ที่ถูกต้อง

* หมายเหตุทางเทคนิค: *

ในสคริปต์นี้เราแยกชื่อไฟล์ออกเป็น 6 เขตข้อมูลโดยใช้ awk โดยมีเครื่องหมายขีดล่างเป็นตัวคั่นฟิลด์ สองฟิลด์แรก $ 1 และ $ 2 ถือว่าเป็นสตริงข้อความแบบคงที่ ฟิลด์ 3,4,5 และ 6 เป็นเวลาประทับที่ข้อมูลของ OP ถูกสุ่มตัวอย่างไม่ใช่วันที่สร้างไฟล์บนระบบไฟล์

ตัวแปร COPYDIR ถือชื่อของไดเรกทอรีใหม่ที่ไฟล์ที่มีการประทับเวลาที่อัปเดตจะไป เราสร้างไดเรกทอรีนั้นในไดเรกทอรีการทำงานปัจจุบันด้วยmkdir $COPYDIR

ตัวแปร TEXTSTRING และ DATESTRING จะเก็บข้อความและการประทับเวลาที่เคารพ ในตัวอย่างผลลัพธ์ร้องฉันได้ใช้สองสายที่แตกต่างกันเพื่อพิสูจน์ว่าสคริปต์จะทำงานโดยไม่คำนึงถึงสิ่งที่ข้อความสองช่องแรกถือ

NEWEPOCHTIME เป็นตัวแปรที่เก็บการประทับเวลาใหม่ในรูปแบบ unix epoch NEWDATE เป็นตัวแปรที่มีการประทับเวลาที่แปลงจาก unix epoch เป็น YYYY-MM-DD HH: MM NEWAPPEND เป็นเวลาจริงที่จะเพิ่มลงในไฟล์ในรูปแบบ YYYY_MM_DD_HHMM ที่ OP ต้องการ

cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat คัดลอกไฟล์เก่าไปยังไดเรกทอรี "convert_files" (แทนที่จะย้ายเพื่อป้องกันการสูญหายของข้อมูล) ด้วย datastamp ที่อัปเดต

แจ้งให้ทราบล่วงหน้าสคริปต์จะทำงานเป็นเวลานานเป็นรูปแบบการตั้งชื่อเป็นจริงตามเช่นไฟล์ทั้งหมดที่มีจริงๆมีSomeText_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

สคริปต์ในการดำเนินการ

ซอลเบลโลว์สาธิตเป็นการคัดลอกโดยตรงจากเครื่องของฉัน โปรดสังเกตว่าฉันได้สร้างไฟล์ต้นฉบับด้วยสองสายที่ต่างกันในสองฟิลด์แรก ดังนั้นสคริปต์นี้ควรทำงานไม่ว่าอะไรจะเกิดขึ้นในตอนเริ่มต้นของชื่อไฟล์ตราบใดที่มีสองสายเท่านั้นที่คั่นด้วยเครื่องหมายขีดล่าง

สคริปต์ได้รับการตั้งชื่อnotes-conversionเพราะฉันพัฒนาสคริปต์จากบันทึกย่อที่ฉันใช้ขณะทำงานกับคำถามนี้

โปรดสังเกตว่าชื่อไฟล์ที่มีส่วน HHMM เป็น 2345 (ซึ่งคือ 15 นาทีก่อนเที่ยงคืน) รับการอัปเดตเป็น 0015 และส่วน DD จะได้รับการอัปเดตในวันถัดไป รักษารูปแบบ 24 ชั่วโมง

นอกจากนี้เนื่องจากการวนซ้ำจะค้นหาเฉพาะ.datไฟล์เราจึงหลีกเลี่ยงการเปลี่ยนชื่อไฟล์หรือไดเรกทอรีอื่น ๆ ที่อาจเกิดขึ้นในไดเรกทอรีทำงานดังนั้นจึงหลีกเลี่ยงการสูญเสียข้อมูลที่อาจเกิดขึ้น ในตัวอย่างด้านล่างไดเรกทอรีดั้งเดิมมี 11 รายการซึ่ง 3 รายการเป็น*.txtไฟล์สำหรับการทดสอบดังนั้นเราจึงทำงานกับ 8 .datไฟล์เท่านั้น ในไดเรกทอรีที่ไฟล์ที่อัปเดตไปเราจะเห็น 8 ไฟล์ทั้งหมด.datและไม่มีไฟล์อื่น ข้อมูลปลอดภัยสคริปต์ทำงานได้

[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 $ 

คำอธิบาย (จากโพสต์ต้นฉบับ)

*) วันนี้ฉันได้เรียนรู้ว่าระบบ Unix-Linux นับเวลาในยุคหรือเพียงแค่ใส่วินาที

*) สคริปต์ใช้ชื่อไฟล์แต่ละไฟล์แยกวันที่แปลงเป็นยุคเพิ่ม 1800 วินาที (ซึ่งเท่ากับ 30 นาที) และบันทึกไฟล์ด้วยเวลาประทับใหม่กว่า

*) สคริปต์นี้ระบุสิ่งที่ OP ต้องการ - เปลี่ยนการประทับเวลาในชื่อไฟล์ไม่ใช่อัปเดตเวลาสร้างไฟล์เอง

เครื่องมือที่ใช้:

  • อูบุนตู 15.04

  • GNU ทุบตี 4.3.30

  • GNU awk 4.1.1

  • วันที่ (GNU coreutils) 8.23


โดยวิธีการ ls | wc -l ก่อนให้ 36 ไฟล์และหลังจากสคริปต์ยัง 36 ไฟล์ไม่มีใครหายไป
Sergiy Kolodyazhnyy

นอกจากนี้เหตุผลที่ฉันใช้ไฟล์ stat -c% n เป็นเพราะการแยกเอาต์พุตของ ls ไม่ใช่ความคิดที่ดี บางคนใช้findคำสั่งซึ่งก็ดีเช่นกัน
Sergiy Kolodyazhnyy

ขอบคุณ @Serg ผมไม่ทราบว่าทำไมฉันเหลือเพียง 2 จาก 727 เหลือไฟล์ในโฟลเดอร์หลังจากใช้สคริปต์ของคุณ ...
strawberrie

มีความแตกต่างระหว่างชื่อไฟล์จริงและตัวอย่างที่คุณโพสต์หรือไม่?
Sergiy Kolodyazhnyy

คุณเคยใช้งานบรรทัดแรกใน "Script in action" หรือไม่? rm * นั้นใช้สำหรับล้างไดเรกทอรีของตัวเองแล้วสร้างกลุ่มไฟล์ทดสอบที่มีวันที่แตกต่างกันในชื่อไฟล์ คุณไม่ควรที่จะทำเช่นนั้น
Sergiy Kolodyazhnyy

-1

คุณอาจใช้รหัสนี้เพื่อทำสิ่งที่คุณต้องการสมมติ

  1. คุณควรสำรองข้อมูลและทดสอบรหัสก่อนเพื่อดูว่าเหมาะสำหรับกรณีของคุณหรือไม่
  2. คุณกำลังใช้รูปแบบ 24H
  3. ไม่มีไฟล์จะถูกตั้งชื่อหลังจาก 23:29 (หากคุณมีไฟล์หลังจากเวลานั้นควรแก้ไขรหัสเพื่อเปลี่ยนวันที่ด้วย)

รหัสคือ:

cd /path/to/the/files

for i in `ls`; do MM=${i:(-6): -4}; HH=${i: -8 : -6 }; NAME=${i: 0 : -8 } ; if [ "$MM" -lt 30 ] ; then  NEWMM=$((10#$MM+30)); mv -f $i $NAME$HH$NEWMM.dat ; else NEWHH=$((10#$HH+1));NEWMM=$((10#$MM-30)) ; mv -f $i $NAME$NEWHH$NEWMM.dat ; fi ; done ;

มันทำงานอย่างไร: รหัสจะตรวจสอบนาทีส่วนในชื่อไฟล์ MMแล้วถ้ามันน้อยกว่า 30 มันจะเพิ่ม 30 ถึงMMถ้ามันเท่ากับ 30 หรือมากกว่านั้นจะเพิ่ม 1 ชั่วโมงในHHส่วนของชื่อและหัก 30 นาทีจากMMส่วนหนึ่งของชื่อ


สำหรับผู้ลงคะแนนเสียงกรุณาแจ้งเหตุผล?
Fat Mind
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.