![在 BASH 中转换飞行日期时间](https://linux22.com/image/132497/%E5%9C%A8%20BASH%20%E4%B8%AD%E8%BD%AC%E6%8D%A2%E9%A3%9E%E8%A1%8C%E6%97%A5%E6%9C%9F%E6%97%B6%E9%97%B4.png)
我有一个包含以下输入的文件
Nov 29 15:15 ,alert_logevent
Nov 29 15:15 ,alert_webhook
Nov 29 15:15 ,appsbrowser
Oct 20 2017 ,ClearPassOnSplunk_2
Oct 10 2017 ,Dnslookup
Oct 12 2017 ,domainCategories
我想将日期时间转换为 YYYYMMDDHHMMSS 而不使用循环之类的东西
cat SOMEFILE_WITH_DATE_AND_DATE | awk '{print "date -d \""$1, $2, $3"\"" " +" "%Y%m%d%H%M%S" , $4 }'
我希望输出看起来像这样
20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20181129151500,appsbrowser
等等
我尝试了 awk 中的 system() 函数,但它不接受超过 1 个参数。
答案1
不确定您的预期输出与您的输入有何关系。我会建议:
$ perl -MPOSIX -MDate::Parse -pe 's{[^,]*}{
strftime("%Y%m%d%H%M%S", localtime str2time($&))}e' <your-file
20171129151500,alert_logevent
20171129151500,alert_webhook
20171129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories
要使用 GNUdate
解析这些日期的能力,并避免date
每行运行一次调用,您可以这样做(假设 shell 支持 ksh 样式的进程替换(如 ksh、bash 或 zsh)):
paste -d , <(<yourfile cut -d , -f1 | date -f- +%Y%m%d%H%M%S) \
<(<yourfile cut -d , -f2-)
但请注意,它给出了:
20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories
虽然这是您所要求的,但听起来不太可能是您想要的,因为这些Nov 29 15:15
听起来更有可能是 2017 年(去年)的时间戳,而不是未来的时间戳。
在这里,这些日期看起来像是ls -l
POSIX 语言环境中报告的。如此便携,您可以适应该功能来自另一个问答将其转换为更有用的格式。或者更好的是,使用一种比ls -l
首先在文件中存储文件日期更好的方法(例如 GNUfind -printf
或 GNUdate -r
或 zsh stat
,或 GNU/BSDstat
或 ast ls --format
...),您可以使用更有用、更精确和明确的格式。
答案2
如果零000000
就可以,HHMMSS
对于没有的条目时间数据,使用以下awk
方法:
awk 'BEGIN{ FS = OFS = "," }
{
cmd = "date -d\042" $1 "\042 +%Y%m%d%H%M%S";
cmd | getline d; close(cmd);
print d, $2
}' file
输出:
20181129151500,alert_logevent
20181129151500,alert_webhook
20181129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories
答案3
需要 GNU awk 来实现内置时间函数
gawk -F, -v OFS=, '
BEGIN {
# assumes english month names
split("Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec", m, ",")
for (idx in m) months[m[idx]] = idx
delete m
}
function date2timestamp(datestamp, tmp,now,timestamp,year,hour,minute) {
now = systime()
split(datestamp, tmp, " ")
if (tmp[3] ~ /:/) {
year = strftime("%Y", now)
hour = substr(tmp[3], 1, 2)
minute = substr(tmp[3], 4, 2)
}
else {
year = tmp[3]
hour = minute = 0
}
timestamp = mktime(year " " months[tmp[1]] " " tmp[2] " " hour " " minute " 0")
if (timestamp > now)
timestamp = mktime((year-1) " " months[tmp[1]] " " tmp[2] " " hour " " minute " 0")
return strftime("%Y%m%d%H%M00", timestamp)
}
{
$1 = date2timestamp($1)
print
}
' file
输出
20171129151500,alert_logevent
20171129151500,alert_webhook
20171129151500,appsbrowser
20171020000000,ClearPassOnSplunk_2
20171010000000,Dnslookup
20171012000000,domainCategories
您的输入文件看起来像结果解析ls -l
。您可能想跳过该文件并执行类似的操作
stat -c '%Y,%n' * | gawk -F, -v OFS=, '{$1 = strftime("%Y%m%d%H%M%S", $1)}1'
这并不安全(从处理带有换行符的文件名的意义上来说),但它会给您准确的文件 mtime。