Tôi có tên của tệp dat theo thứ tự thời gian:
FileName_YYYY_MM_DD_HHMM.dat
Có lệnh nào để thêm 30 phút cho mỗi dấu thời gian không?
Tôi có tên của tệp dat theo thứ tự thời gian:
FileName_YYYY_MM_DD_HHMM.dat
Có lệnh nào để thêm 30 phút cho mỗi dấu thời gian không?
Câu trả lời:
Sử dụng 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')
sẽ thay đổi thư mục hiện tại thành thư mục chứa các .dat
tệp. Thay thế /path/to/dir
bằng đường dẫn thực tế.
glob.glob('*.dat')
sẽ tìm thấy các tập tin kết thúc bằng .dat
ini_time
đầu tiên, biến sẽ cắt thời gian ngày từ tên tệp gốc bằng cách sử dụng re
mô-đun và sau đó sắp xếp mục nhập nào thể hiện những gì trong chuỗi được lấy ra để chúng ta có thể thêm thời gian cần thiết vào đây
fin_time
sẽ chứa thời gian kết quả tức là ini_time
cộng thêm 30 phút
os.rename
sẽ đổi tên tập tin cho phù hợp.
Cũng lưu ý rằng, với các tên tệp liên tiếp (khác nhau 30 phút), tệp được đổi tên sẽ ghi đè lên tệp tiếp theo, do đó tốt hơn là thêm giây vào tên tệp đã đổi tên để giữ an toàn. Nếu không, bạn cần lưu các tệp đã đổi tên vào một thư mục khác và sau đó thay thế chúng bằng các tệp gốc sau đó.
Filename_
trong phương thức đổi tên.
/path/to/file
bằng đường dẫn đầy đủ đến thư mục không?
Sử dụng bash
, các tập tin được đổi tên là trong một thư mục phụ mới renamed
.
Bắt đầu tập lệnh trong thư mục chứa các tập tin.
#!/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
đầu ra ví dụ:
% 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
với một phần .Data_YYYY_MM_DD_HHMM.dat
là phần mở rộng. Và do đó FileName_123
không phải là dấu thời gian hợp lệ.
KỊCH BẢN
Đây là phiên bản chỉnh sửa của kịch bản gốc của tôi. OP ban đầu không cung cấp thông tin đầy đủ về định dạng đặt tên. Kịch bản này thích ứng với những gì OP đề cập trong các bình luận là cách đặt tên tệp chính xác.
* Ghi chú kỹ thuật: *
Trong kịch bản này, chúng tôi tách tên tệp thành 6 trường riêng biệt bằng awk, với dấu gạch dưới là dấu phân cách trường. Hai trường đầu tiên, $ 1 và $ 2 được coi là chuỗi văn bản tĩnh. Các trường 3,4,5 và 6 là dấu thời gian mà dữ liệu của OP được lấy mẫu, không phải ngày tạo tệp trên hệ thống tệp.
Biến COPYDIR giữ tên của thư mục mới nơi các tệp có dấu thời gian được cập nhật sẽ đi. Chúng tôi tạo thư mục đó trong thư mục làm việc hiện tại vớimkdir $COPYDIR
Các biến VĂN BẢN và DATESTRING giữ văn bản tĩnh và dấu thời gian đáng kính. Trong phần đầu ra mẫu dưới đây, tôi đã sử dụng hai chuỗi khác nhau để chứng minh rằng tập lệnh sẽ hoạt động bất kể văn bản nào mà hai trường đầu tiên giữ.
NEWEPOCHTIME là biến giữ dấu thời gian mới được tính toán ở định dạng unix epoch. NEWDATE là biến giữ dấu thời gian được chuyển đổi từ định dạng unix epoch sang định dạng YYYY-MM-DD HH: MM. NEWAPPEND là dấu thời gian thực tế sẽ được thêm vào tệp theo định dạng YYYY_MM_DD_HHMM mong muốn của OP.
cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat
sao chép tệp cũ vào thư mục "convert_files" (thay vì di chuyển, để tránh mất dữ liệu) với kho dữ liệu được cập nhật.
Lưu ý , tập lệnh sẽ hoạt động miễn là định dạng đặt tên thực sự được tuân theo, tức là tất cả các tệp đều thực sự có SomeText_123.Data_YYYY_MM_DD_HHMM.dat
định dạng.
#!/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 TRONG HÀNH ĐỘNG
Dưới đây trình diễn là bản sao trực tiếp từ thiết bị đầu cuối của tôi. Lưu ý rằng tôi đã tạo các tệp gốc với hai chuỗi khác nhau trong hai trường đầu tiên. Vì vậy, tập lệnh này sẽ hoạt động bất kể đầu tập tin là gì, miễn là thực sự chỉ có hai chuỗi được phân tách bằng dấu gạch dưới
Kịch bản được đặt tên notes-conversion
bởi vì tôi đã phát triển kịch bản từ các ghi chú tôi đã thực hiện khi làm việc với câu hỏi này.
Lưu ý rằng tên tệp có phần HHMM là 2345 (tức là 15 phút trước nửa đêm) được cập nhật thành 0015 và phần DD được cập nhật vào ngày hôm sau. Định dạng 24 giờ được bảo quản.
Ngoài ra, vì vòng lặp chỉ tìm kiếm .dat
các tệp, chúng tôi tránh đổi tên các tệp hoặc thư mục khác có thể xảy ra trong thư mục làm việc, do đó tránh mọi mất mát dữ liệu tiềm ẩn. Trong ví dụ dưới đây, thư mục gốc chứa 11 mục, 3 trong số đó là *.txt
các tệp để kiểm tra, vì vậy chúng tôi chỉ làm việc với 8 .dat
tệp. Trong thư mục nơi các tệp được cập nhật đi, chúng tôi thấy 8 tệp, tất cả .dat
và không có tệp nào khác. Dữ liệu là an toàn, kịch bản làm công việc của nó.
[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 $
GIẢI THÍCH (từ bài gốc)
*) Hôm nay tôi đã học được rằng các hệ thống Unix-Linux đếm thời gian theo thời gian Epoch , hoặc chỉ đơn giản là đặt giây.
*) tập lệnh lấy từng tên tệp, trích xuất ngày, chuyển đổi thành epoch, thêm 1800 giây (chính xác là 30 phút) và lưu tệp với dấu thời gian mới.
*) Tập lệnh này giải quyết những gì OP muốn - thay đổi dấu thời gian trong tên tệp, không cập nhật thời gian tạo tệp của chính tệp
Công cụ được sử dụng:
Ubuntu 15.04
GNU bash 4.3.30
GNU awk 4.1.1
ngày (GNU coreutils) 8.23
find
lệnh, cũng tốt.
Bạn có thể sử dụng mã này để làm những gì bạn cần giả sử
mã là:
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 ;
Cách thức hoạt động:
Mã sẽ kiểm tra phần phút trong tên tệp MM
sau đó nếu dưới 30, nó sẽ thêm 30 vào MM
nếu bằng 30 hoặc nhiều hơn, nó sẽ thêm 1 giờ vào HH
phần trong tên và trừ 30 phút từ MM
một phần của tên
ls --full-time
không?