Mam nazwy plików danych w kolejności chronologicznej:
FileName_YYYY_MM_DD_HHMM.dat
Czy są jakieś polecenia dodawania 30 minut do każdego znacznika czasu?
Mam nazwy plików danych w kolejności chronologicznej:
FileName_YYYY_MM_DD_HHMM.dat
Czy są jakieś polecenia dodawania 30 minut do każdego znacznika czasu?
Odpowiedzi:
Używanie 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')
zmieni bieżący katalog na katalog zawierający .dat
pliki. Zamień /path/to/dir
na rzeczywistą ścieżkę.
glob.glob('*.dat')
znajdzie pliki kończące się na .dat
ini_time
zmienna najpierw wycina datę i czas z oryginalnej nazwy pliku za pomocą re
modułu, a następnie sortuje, który wpis reprezentuje to, co w łańcuchu, który jest usuwany, abyśmy mogli dodać do tego wymagany czas
fin_time
będzie zawierać wynikowy czas, tj. ini_time
plus 30 minut
os.rename
odpowiednio zmieni nazwę pliku.
Zauważ też, że przy kolejnych nazwach plików (różniących się o 30 minut) plik o zmienionej nazwie zastąpi następny, dlatego lepiej jest dodać sekundy do nazwy o zmienionej nazwie, aby zachować bezpieczeństwo. W przeciwnym razie należy zapisać pliki o zmienionej nazwie w innym katalogu, a następnie zastąpić je oryginalnymi plikami później.
Filename_
w metodzie zmiany nazwy.
/path/to/file
pełną ścieżkę do katalogu?
Za bash
pomocą pliki o zmienionej nazwie znajdują się w nowym podfolderze renamed
.
Uruchom skrypt w folderze, w którym znajdują się pliki.
#!/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
przykładowe dane wyjściowe:
% 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
części .Data_YYYY_MM_DD_HHMM.dat
jest rozszerzeniem. I dlatego FileName_123
nie jest prawidłowym znacznikiem czasu.
SCENARIUSZ
To jest zredagowana wersja mojego oryginalnego skryptu. OP początkowo nie dostarczył pełnych informacji o formacie nazewnictwa. Ten skrypt dostosowuje się do tego, co OP wspomniane w komentarzach było prawidłowym nazewnictwem plików.
* Uwagi techniczne: *
W tym skrypcie rozdzielamy nazwę pliku na 6 oddzielnych pól za pomocą awk, z podkreślnikiem jako ogranicznikiem pola. Pierwsze dwa pola, 1 $ i 2 $, są traktowane jako ciąg tekstowy. Pola 3,4,5 i 6 to znacznik czasu, w którym próbkowane były dane OP, a nie data utworzenia pliku w systemie plików.
Zmienna COPYDIR zawiera nazwę nowego katalogu, do którego trafią pliki ze zaktualizowanym znacznikiem czasu. Tworzymy ten katalog w bieżącym katalogu roboczym za pomocąmkdir $COPYDIR
Zmienne TEXTSTRING i DATESTRING przechowują odpowiednio tekst statyczny i znacznik czasu. W poniższym przykładzie wyjściowym użyłem dwóch różnych ciągów, aby udowodnić, że skrypt będzie działał niezależnie od tego, jaki tekst zawierają dwa pierwsze pola.
NEWEPOCHTIME jest zmienną, która przechowuje obliczony nowy znacznik czasu w formacie epoki uniksowej. NEWDATE jest zmienną, która przechowuje konwertowany znacznik czasu z epoki uniksowej na format RRRR-MM-DD GG: MM. NEWAPPEND to rzeczywisty znacznik czasu, który zostanie dodany do pliku w pożądanym formacie YYYY_MM_DD_HHMM PO.
cp $file "$COPYDIR"/"%TEXTSTRING""$NEWAPPEND".dat
kopiuje stary plik do katalogu „przekonwertowane pliki” (zamiast przenosić, aby zapobiec utracie danych) za pomocą zaktualizowanego znacznika danych.
Wskazówki , skrypt będzie działać tak długo, jak format nazewnictwa jest rzeczywiście następuje, czyli wszystkie pliki są naprawdę mieć SomeText_123.Data_YYYY_MM_DD_HHMM.dat
format.
#!/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
PISMO W AKCJI
Poniższa demonstracja jest bezpośrednią kopią z mojego terminalu. Zauważ, że utworzyłem oryginalne pliki z dwoma różnymi ciągami w pierwszych dwóch polach. Więc ten skrypt powinien działać bez względu na to, co jest na początku nazwy pliku, o ile tak naprawdę są tylko dwa ciągi znaków oddzielone znakiem podkreślenia
Skrypt został nazwany, notes-conversion
ponieważ opracowałem go na podstawie notatek, które sporządziłem podczas pracy nad tym pytaniem.
Zauważ, że nazwy plików, które mają część HHMM jako 2345 (czyli 15 minut przed północą), są aktualizowane do 0015, a część DD jest aktualizowana do następnego dnia. Zachowano format 24-godzinny.
Ponadto, ponieważ dla pętli szuka tylko .dat
plików, unikamy zmiany nazw innych plików lub katalogów, które mogą znajdować się w katalogu roboczym, co pozwala uniknąć potencjalnej utraty danych. W poniższym przykładzie oryginalny katalog zawiera 11 elementów, z których 3 to *.txt
pliki do testowania, więc pracujemy tylko z 8 .dat
plikami. W katalogu, do którego trafiają zaktualizowane pliki, widzimy 8 plików, wszystkie .dat
i żadnych innych plików. Dane są bezpieczne, skrypt spełnia swoje zadanie.
[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 $
WYJAŚNIENIE (z oryginalnego postu)
*) Dzisiaj dowiedziałem się, że systemy Unix-Linux liczą czas w epoce lub po prostu umieszczają sekundy.
*) skrypt pobiera każdą nazwę pliku, wyodrębnia datę, konwertuje ją do epoki, dodaje 1800 sekund (dokładnie dokładnie 30 minut) i zapisuje plik z nową datą.
*) Ten skrypt dotyczy tego, czego chciał OP - zmień znacznik czasu w nazwie pliku, a nie aktualizuj czasu utworzenia samego pliku
Narzędzia użyte:
ubuntu 15.04
GNU bash 4.3.30
GNU awk 4.1.1
data (GNU coreutils) 8.23
find
polecenia, co jest również dobre.
Możesz użyć tego kodu do zrobienia tego, czego potrzebujesz
kod to:
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 ;
Jak to działa:
kod sprawdzi część minut w nazwie pliku, MM
a jeśli jest mniejsza niż 30, doda 30 do, MM
jeśli jest równa 30 lub więcej, doda 1 godzinę do HH
części w nazwie i odejmie 30 minut od MM
część nazwy
ls --full-time
?