다음 형식으로 csv 파일을 생성하는 bash 스크립트가 있습니다.
056_log_202312290735.csv
056_log_202312290736.csv
067_dat_202312290737.csv
067_dat_202312290838.csv
056_log_202312290951.csv
067_dat_202312290952.csv
056_log_202312290953.csv
...
056_log_YYYYmmddHHMM.csv
067_dat_YYYYmmddHHMM.csv
YYYYmmddHHMM
csv 파일 생성 시간이 아닌 csv 파일 자체에 포함된 데이터의 타임스탬프는 어디에 있습니까?
그래서 현재 시스템 시간(csv 파일과 동일한 형식, 즉 YYYYmmddHHMM
)을 파일 이름의 타임스탬프와 비교하는 bash 스크립트를 작성하고 싶습니다.
차이가 120분 이상이면 파일을 old_data
디렉터리로 이동해야 합니다.
둘 사이의 차이가 120분 미만인 경우 해당 파일을 current_data
해당 디렉터리 로 이동해야 합니다.
현재 시스템 시간인 202312291048을 사용하여 파일을 다음과 같이 이동해야 합니다.
~/old_data/
056_log_202312290735.csv
056_log_202312290736.csv
067_dat_202312290737.csv
067_dat_202312290838.csv
~/current_data/
056_log_202312290951.csv
067_dat_202312290952.csv
056_log_202312290953.csv
지금까지 나는 내가 원하는 형식을 사용하여 현재 시간을 얻을 수 있다는 것을 알고 있습니다.
CUR_TIME="`date +%Y%m%d%H%M`";
그리고 다음 명령을 사용하여 csv 파일에서 타임스탬프를 가져옵니다.
ls 056*.csv | cut -d'_' -f 3 | cut -c -12; #get timestamps from 056 files
ls 067*.csv | cut -d'_' -f 3 | cut -c -12; #get timestamps from 067 files
그 이후로 어떻게 진행해야 할지 모르겠습니다.. 도와주세요.
제가 생각할 수 있는 것은 다음과 같습니다.
#!/bin/bash
CUR_TIME=$(date +%Y%m%d%H%M);
for csvfile in *.csv
do
TIME_DIFF=0
TIMESTAMP= $(echo $csvfile | cut -d'_' -f 3 | cut -c -12)
TIME_DIFF= $CUR_TIME-$TIMESTAMP
if $TIME_DIFF >= 120
then
mv -f $csvfile ~/old_data/
else
mv -f $csvfile ~/current_data/
fi
done
답변1
예를 들어 202312291607(2023/12/29 16:07) 빼기 60은 202312291547이므로 실제로는 2023/12/29 15:47이므로 60분 전이 아닙니다. , 그런데 20분 전이에요. 기억하세요, 우리는60진수 체계, 따라서 귀하가 제안한 대로 간단한 10진수 계산을 수행할 수 없습니다. 일반적인 해결책은 시간을 다음으로 변환하는 것입니다.에포크 이후 초, 그런 다음 이를 비교하여 초 단위의 차이를 얻은 다음 이를 분으로 변환합니다. 예를 들어:
#!/bin/bash
## Get the current time in seconds since the epoch
curr_time=$(date +%s)
for csvfile in *.csv; do
## Extract the timestamp from the csv file name.
csv_date_string=$(basename "${csvfile##*_}" .csv |
sed -E 's|(....)(..)(..)(..)(..)|\1/\2/\3 \4:\5|')
## Convert the csv datestamp to seconds since the epoch
csv_time=$( date -d "$csv_date_string" +%s)
## Compare to the current time and, if more than or equal to 120
## echo the mv command, if less, echo that we do nothing.
if [[ $(( (curr_time - csv_time) / 60)) -ge 120 ]]; then
echo mv "$csvfile" old_data
else
echo "Not moving $csvfile"
fi
done
위의 스크립트를 실행하고 원하는 대로 작동하는 것처럼 보이면 제거하여 echo
실제로 mv
명령을 실행하고 파일을 이동하세요.
여기서의 비결은 기본을 사용하는 것입니다.문자열 연산파일 이름에서 타임스탬프를 추출합니다. 이 구문은 ${var##pattern}
문자열 시작 부분에서 가장 긴 일치 항목을 제거합니다. pattern
여기서 패턴은 *_
_까지의 모든 것입니다. 그녀는 다음과 같은 조치를 취하고 있습니다.
$ csvfile=056_log_202312290736.csv
$ echo ${csvfile##*_}
202312290736.csv
따라서 날짜 스탬프 플러스를 남기고 ${csvfile##*_}
끝까지 모든 것을 삭제하십시오 . 이 명령은 파일 이름에서 경로를 제거하고 파일 이름만 유지하도록 설계되었지만 제공된 확장자를 제거하는 유용한 트릭도 있으므로 실제 타임스탬프를 얻기 위해 with를 사용합니다._
.csv
basename
basename
.csv
$ basename "${csvfile##*_}" .csv
202312290736
나머지는 비교적 간단합니다. if
시차가 120분 이상인지 간단히 확인해보세요. 시간을 초 단위로 다루기 때문에 분을 얻으려면 60t로 나누어야 합니다. 또는 120분을 7200초(120 x 60)로 변환할 수 있습니다.
if [[ $(( curr_time - csv_time )) -ge 7200 ]]; then
중요한: 파일이 많고 처리하는 데 몇 분 또는 몇 시간이 걸릴 수 있는 경우 각 파일은 스크립트가 시작된 시간과 계속 비교된다는 점에 유의하세요. 즉, 스크립트가 도착했을 때 120분보다 오래되었지만 스크립트가 시작되었을 때는 그렇지 않은 콘텐츠는 이동되지 않습니다. 이 작업을 원하지 않으면 curr_time=$(date +%s)
루프 내부로 줄을 이동하여 for
각 파일에 대해 재설정되도록 하세요.