ฉันมีชื่อไฟล์ dat ตามลำดับเวลา:
FileName_YYYY_MM_DD_HHMM.dat
มีคำสั่งใด ๆ สำหรับเพิ่ม 30 นาทีในแต่ละการบันทึกหรือไม่
ฉันมีชื่อไฟล์ dat ตามลำดับเวลา:
FileName_YYYY_MM_DD_HHMM.dat
มีคำสั่งใด ๆ สำหรับเพิ่ม 30 นาทีในแต่ละการบันทึกหรือไม่
คำตอบ:
การใช้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 นาที) ไฟล์ที่ถูกเปลี่ยนชื่อจะเขียนทับชื่อถัดไปดังนั้นจึงเป็นการดีกว่าที่จะเพิ่มวินาทีในชื่อไฟล์ที่ถูกเปลี่ยนชื่อเพื่อให้มันปลอดภัย มิฉะนั้นคุณต้องบันทึกไฟล์ที่เปลี่ยนชื่อไปยังไดเรกทอรีอื่นแล้วแทนที่ด้วยไฟล์เดิมในภายหลัง
Filename_
ในวิธีการเปลี่ยนชื่อ
/path/to/file
ด้วยพา ธ เต็มไปยังไดเรกทอรีหรือไม่
การใช้ไฟล์เปลี่ยนชื่ออยู่ในโฟลเดอร์ย่อยใหม่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
renamed
FileName_123.Data_YYYY_MM_DD_HHMM.dat
ส่วนหนึ่ง.Data_YYYY_MM_DD_HHMM.dat
คือส่วนขยาย และดังนั้นจึงFileName_123
ไม่ใช่เวลาประทับที่ถูกต้อง
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
find
คำสั่งซึ่งก็ดีเช่นกัน
คุณอาจใช้รหัสนี้เพื่อทำสิ่งที่คุณต้องการสมมติ
รหัสคือ:
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
ส่วนหนึ่งของชื่อ
ls --full-time
ไหม