다음 파일이 있습니다.
File: ‘./Payment_Volume_and_Value_Report_000000501C5_2.10_2022_11_14_06_24_49.xml’
Modify: 2022-11-14 06:24:54.466847421 -0500
Change: 2022-11-14 06:25:02.166883414 -0500
File: ‘./Payment_Volume_and_Value_Report_000000501C5_2.9_2022_11_14_06_24_54.xml’
Modify: 2022-11-14 06:24:54.740847211 -0500
Change: 2022-11-14 06:25:02.166883414 -0500
File: ‘./Payment_Volume_and_Value_Report_000000501C5_2022_11_14_06_24_54.xml’
Modify: 2022-11-14 06:24:54.637847290 -0500
Change: 2022-11-14 06:25:02.166883414 -0500
각 파일의 출력이 다음과 같기를 원합니다.
Payment_Volume_and_Value_Report_000000501C5_2.10_2022_11_14_06_24_49.xml
06:24:54
06:25:02
가능하다면 마지막에 표시된 두 시간 간의 차이를 계산하고 싶습니다(변경-수정).
Payment_Volume_and_Value_Report_000000501C5_2.10_2022_11_14_06_24_49.xml
00:00:08
답변1
사용세게 때리다그리고 GNU date
명령:
while read -r attr data; do
[[ $attr == File: ]] && echo "$data"
[[ $attr == Modify: ]] && m="$data"
if [[ $attr == Change: ]]; then
c="$data"
c_epoch=$(date -d"$c" +%s)
m_epoch=$(date -d"$m" +%s)
echo "$((c_epoch - m_epoch)) seconds"
fi
done < file
산출:
‘./Payment_Volume_and_Value_Report_000000501C5_2.10_2022_11_14_06_24_49.xml’
8 seconds
‘./Payment_Volume_and_Value_Report_000000501C5_2.9_2022_11_14_06_24_54.xml’
8 seconds
‘./Payment_Volume_and_Value_Report_000000501C5_2022_11_14_06_24_54.xml’
8 seconds
답변2
#! /usr/bin/env bash
INPUT_FILENAME="$1"
while read -r FIELD_NAME DATA; do
# echo "REPLY=<$REPLY>"
case "${FIELD_NAME}" in
"File:")
# Get only text between ‘ and ’
FILE="${DATA#*‘}"
FILE="${FILE%’*}"
# Print filename
printf "%s\n" "$FILE"
;;
"Modify:")
DATE_MODIFY="${DATA}"
# Print date
DATE_MODIFY_PRINT="${DATE_MODIFY#* }"
DATE_MODIFY_PRINT="${DATE_MODIFY_PRINT%.*}"
printf "%s\n" "${DATE_MODIFY_PRINT}"
# Compute seconds since 01/01/1970
SECONDS_MODIFY=$(date --date "${DATE_MODIFY}" +%s)
;;
"Change:")
DATE_CHANGE="${DATA}"
# Print date
DATE_CHANGE_PRINT="${DATE_CHANGE#* }"
DATE_CHANGE_PRINT="${DATE_CHANGE_PRINT%.*}"
printf "%s\n" "${DATE_CHANGE_PRINT}"
# Compute seconds since 01/01/1970
SECONDS_CHANGE=$(date --date "${DATE_CHANGE}" +%s)
# Compute hours, minutes and seconds between two dates (assume CHANGE >= MODIFY)
SECONDS_DIFF=$(( SECONDS_CHANGE - SECONDS_MODIFY ))
MINUTES_DIFF=$(( SECONDS_DIFF / 60 ))
SECONDS_DIFF=$(( SECONDS_DIFF - ( MINUTES_DIFF * 60 ) ))
HOURS_DIFF=$(( MINUTES_DIFF / 60 ))
MINUTES_DIFF=$(( MINUTES_DIFF - ( HOURS_DIFF * 60 ) ))
printf "%02d:%02d:%02d\n" "$HOURS_DIFF" "$MINUTES_DIFF" "$SECONDS_DIFF"
;;
esac
done < <(cat "${INPUT_FILENAME}"; echo)
산출:
./Payment_Volume_and_Value_Report_000000501C5_2.10_2022_11_14_06_24_49.xml
06:24:54
06:25:02
00:00:08
./Payment_Volume_and_Value_Report_000000501C5_2.9_2022_11_14_06_24_54.xml
06:24:54
06:25:02
00:00:08
./Payment_Volume_and_Value_Report_000000501C5_2022_11_14_06_24_54.xml
06:24:54
07:28:02
00:00:08
답변3
펄을 사용하고날짜::분석그리고시간::기간기준 치수. 는 신기원(1970년 1월 1일 자정) 형식 이후의 날짜를 유닉스 초로 구문 분석하고 초를 영어 표현으로 인쇄하는 Date::Parse
모듈입니다 . 이들 중 어느 것도 Perl에 포함되어 있지 않으며 다음을 통해 설치해야 합니다.time_t
Time::Duration
팬또는 배포 패키지에서(예 apt-get install libtimedate-perl libtime-duration-perl
: Debian에서:)
$ perl -MDate::Parse -MTime::Duration -lne '
if (/^\s*File:\s*/) {
s/^.*?: //; # remove field name
s/^‘|’$//g; # remove quotes
print;
} elsif (/^\s*Modify:\s*/) {
s/^.*?: //;
$mod = $_;
} elsif (/^\s*Change:\s*/) {
s/^.*?: //;
$change = $_;
print duration_exact(str2time($change) - str2time($mod));
}' file.txt
./Payment_Volume_and_Value_Report_000000501C5_2.10_2022_11_14_06_24_49.xml
7 seconds
./Payment_Volume_and_Value_Report_000000501C5_2.9_2022_11_14_06_24_54.xml
7 seconds
./Payment_Volume_and_Value_Report_000000501C5_2022_11_14_06_24_54.xml
7 seconds
이 출력은 놀라운 일이 아닙니다(초가 반올림되는 것을 제외하고).아래에int(str2time($change) - str2time($mod) + 0.5)
- 가장 가까운 0으로 반올림하려면 다음을 사용할 수 있습니다.최근의초 또는 BEGIN {$Time::Duration::MILLISECOND=1};
밀리초 모드를 활성화하고 가장 가까운 밀리초로 반올림하기 위해 스크립트 시작 부분에 추가됨) 그러나 Time::Duration 모듈은 수정 및 변경 타임스탬프 사이의 더 큰 시간 간격으로 해당 값을 표시합니다. 예를 들어, 마지막 변경 시간이 다음과 file.txt
같다면:
Change: 2022-11-18 09:25:02.166883414 -0500
그러면 이 파일의 출력은 다음과 같습니다.
./Payment_Volume_and_Value_Report_000000501C5_2022_11_14_06_24_54.xml
4 days, 3 hours, and 7 seconds
그리고 변경 타임스탬프가 다음과 같은 경우:
Change: 2029-11-18 09:25:02.166883414 -0500
그러면 출력은 다음과 같습니다.
./Payment_Volume_and_Value_Report_000000501C5_2022_11_14_06_24_54.xml
7 years, 6 days, 3 hours, and 7 seconds
이는 second 보다 이해하기 쉽습니다 221281207.529036
.
또는 스크립트가 Time::Duration duration()
함수를 대신 사용하는 duration_exact()
경우 기간 중 가장 중요하지 않은 부분을 반올림합니다("중요도"는 기간 크기에 따라 변경됩니다).
./Payment_Volume_and_Value_Report_000000501C5_2.10_2022_11_14_06_24_49.xml
7 seconds
./Payment_Volume_and_Value_Report_000000501C5_2.9_2022_11_14_06_24_54.xml
7 seconds
./Payment_Volume_and_Value_Report_000000501C5_2022_11_14_06_24_54.xml
7 years and 6 days
시, 분, 초는 짧은 기간 동안에는 여전히 "중요한" 것으로 간주되지만 장기간에는 그렇지 않습니다.