我有以下文件:
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
使用巴什和 GNUdate
命令:
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
使用 Perl 和日期::解析和时间::持续时间模块。 Date::Parse
是一个用于将日期解析为 unixtime_t
自从纪元以来的秒数(1970 年 1 月 1 日午夜)格式的模块,也是Time::Duration
一个用于将秒打印为英文表达式的模块。这些都不包含在 perl 中,它们需要通过安装潘或来自发行版包(例如在 Debian 上apt-get install libtimedate-perl libtime-duration-perl
:)
$ 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)
-如果您希望四舍五入到四舍五入,则可以使用最近的第二个,或者添加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
这比秒更容易理解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
小时、分钟和秒对于短持续时间仍然被认为是“重要的”,但对于长持续时间来说并不重要。