我正在尝试按日期对证书进行排序,只将最新的证书保留在一个单独的文件中。
以下是一个示例主机的示例pki_certs.res输入文件,其中包含我需要排序的过去证书列表:
下面是排序并弹出最后一个的脚本:
cat "${_file}" | sort -k10,10 | sed -e 's/Not After : //' -e 's/GMT/GMT;/' | grep "${_domain}" |
while read line; do
_first=`echo $line | cut -d';' -f1`
_second=`echo $line | cut -d';' -f2-`
_date=`date -d "${_first}" +%Y%m%d%H%M`
echo "$_date $_second"
done |sort -k 3,3 -k 1,1r | awk "{if (i[$3] < $1) i[$3]=$1} END{for(x in i){ print x" "i[x] }}" |
sed -e 's/CN=//g' | sort -k 2,2 > pki_certs.final.sorted
问题是排序在pki_certs.final.sorted文件中留下了最近的前一个。
预期输出:
Apr 7 20:09:26 2023
但我得到的不是这样的输出:
Apr 12 18:12:02 2022
关于我错过了什么,有什么想法吗
使用任何版本的强制性Unix工具awk、Sort、cut和head应用DSU(Decorate/Sort/Uncorate(习惯用法以获得整行输出:
$ awk '{printf "%04d%02d%02d%st%sn", $7, (index("JanFebMarAprMayJunJulAugSepOctNovDec",$4)+2)/3, $5, $6, $0}' file |
sort -r | head -1 | cut -f2-
pki_certs.res:Not After : Apr 7 20:09:26 2023 GMT DNS:MDVARTREPO01.cpp.nonlive
或者只是日期:
$ awk '{printf "%04d%02d%02d%st%sn", $7, (index("JanFebMarAprMayJunJulAugSepOctNovDec",$4)+2)/3, $5, $6, $4" "$5" "$6" "$7}' file |
sort -r | head -1 | cut -f2-
Apr 7 20:09:26 2023
第一个awk在每行的前面添加一个日期+时间的可排序版本,然后根据时间戳对其进行排序,然后剪切删除awk添加的字符串。看到每一步的中间输出可以看出它是如何工作的:
$ awk '{printf "%04d%02d%02d%st%sn", $7, (index("JanFebMarAprMayJunJulAugSepOctNovDec",$4)+2)/3, $5, $6, $4" "$5" "$6" "$7}' file
2023040720:09:26 Apr 7 20:09:26 2023
2020050712:05:44 May 7 12:05:44 2020
2021040817:06:54 Apr 8 17:06:54 2021
2020050711:58:19 May 7 11:58:19 2020
2021040917:42:27 Apr 9 17:42:27 2021
2021041709:09:35 Apr 17 09:09:35 2021
2021040917:02:43 Apr 9 17:02:43 2021
2022041218:12:02 Apr 12 18:12:02 2022
$ awk '{printf "%04d%02d%02d%st%sn", $7, (index("JanFebMarAprMayJunJulAugSepOctNovDec",$4)+2)/3, $5, $6, $4" "$5" "$6" "$7}' file | sort -r
2023040720:09:26 Apr 7 20:09:26 2023
2022041218:12:02 Apr 12 18:12:02 2022
2021041709:09:35 Apr 17 09:09:35 2021
2021040917:42:27 Apr 9 17:42:27 2021
2021040917:02:43 Apr 9 17:02:43 2021
2021040817:06:54 Apr 8 17:06:54 2021
2020050712:05:44 May 7 12:05:44 2020
2020050711:58:19 May 7 11:58:19 2020
$ awk '{printf "%04d%02d%02d%st%sn", $7, (index("JanFebMarAprMayJunJulAugSepOctNovDec",$4)+2)/3, $5, $6, $4" "$5" "$6" "$7}' file | sort -r | head -1
2023040720:09:26 Apr 7 20:09:26 2023
$ awk '{printf "%04d%02d%02d%st%sn", $7, (index("JanFebMarAprMayJunJulAugSepOctNovDec",$4)+2)/3, $5, $6, $4" "$5" "$6" "$7}' file | sort -r | head -1 | cut -f2-
Apr 7 20:09:26 2023
顺便说一下,在你的代码中你有:
awk "{if (i[$3] < $1) i[$3]=$1} END{for(x in i){ print x" "i[x] }}"
你必须转义所有这些符号,因为你使用了错误的引号,因此邀请shell在awk看到脚本之前对其进行解释。只是不要这样做,除非你有特定的理由不这样做:
awk '{if (i[$3] < $1) i[$3]=$1} END{for(x in i){ print x" "i[x] }}'
(对我来说(OP的最终目标还不清楚,所以。。。
假设/理解:
- 目标#1-打印最新/最新日期
- 目标#2-打印包含最新/最新日期的行
- 目标#3-根据日期时间戳对整个输入文件进行排序
- 所有证书的详细信息都在一行上(即,单个证书的详细内容不跨越多行(
- 每一行都包含一个格式为"mmm-dd HH:MM:SS yyyy"的日期时间戳
使用GNU awk
:的一个想法
awk ' # define field pattern as " mmm dd HH:MM:SS yyyy "
BEGIN { FPAT=" [[:alpha:]]{3} [0-9]{1,2} [0-2][0-9]:[0-5][0-9]:[0-5][0-9] [0-9]{4} "
# build array of months to allow converting from 3-character to numeric
n=split("Jan:Feb:Mar:Apr:May:Jun:Jul:Aug:Sep:Nov:Dec",arr,":")
for (i=1;i<=n;i++)
month[(arr[i])]=i
}
{ n=split($1,arr) # split 1st (and only?) FPAT matching field on white space
gsub(/:/," ",arr[3]) # convert ":" to " "
# convert current datetime stamp to epoch seconds
epoch=mktime(arr[4] " " month[arr[1]] " " arr[2] " " arr[3])
if (epoch > maxepoch +0) {
maxepoch=epoch
dt=$1 # save current "max" datetime stamp
}
lines[epoch]=$0 # save current line, indexed by epoch
}
END { print dt # objective #1: print max datetime stamp
print lines[maxepoch] # objective #2: print cert line containing max datetime stamp
PROCINFO["sorted_in"]="@ind_num_asc" # sort array by numeric index in ascending order
for (i in lines) # objective #3: print lines[] array in epoch ascending order
print lines[i] > "pki_certs.final.sorted"
}
' cert.dat
注意:
- 对于a(
FPAT
、b(mktime()
函数和c(PROCinfo["sorted_in"]
排序指令需要GNU awk
- 替换OP的所有当前代码
- OP可以根据预期结果修改
END {...}
块
这会生成:
# objective #1:
Apr 7 20:09:26 2023
# objective #2:
pki_certs.res:Not After : Apr 7 20:09:26 2023 GMT DNS:MDVARTREPO01.cpp.nonlive
# objective #3:
$ cat pki_certs.final.sorted
pki_certs.res:Not After : May 7 11:58:19 2020 GMT Subject: CN=MDVARTREPO01.cpp.nonlive DNS:MDVARTREPO01.cpp.nonlive
pki_certs.res:Not After : May 7 12:05:44 2020 GMT Subject: CN=MDVARTREPO01.cpp.nonlive DNS:MDVARTREPO01.cpp.nonlive
pki_certs.res:Not After : Apr 8 17:06:54 2021 GMT Subject: CN=MDVARTREPO01.cpp.nonlive DNS:MDVARTREPO01.cpp.nonlive
pki_certs.res:Not After : Apr 9 17:02:43 2021 GMT Subject: CN=MDVARTREPO01.cpp.nonlive DNS:MDVARTREPO01.cpp.nonlive
pki_certs.res:Not After : Apr 9 17:42:27 2021 GMT Subject: CN=MDVARTREPO01.cpp.nonlive DNS:MDVARTREPO01.cpp.nonlive
pki_certs.res:Not After : Apr 17 09:09:35 2021 GMT Subject: CN=MDVARTREPO01.cpp.nonlive DNS:MDVARTREPO01.cpp.nonlive
pki_certs.res:Not After : Apr 12 18:12:02 2022 GMT Subject: CN=MDVARTREPO01.cpp.nonlive DNS:MDVARTREPO01.cpp.nonlive
pki_certs.res:Not After : Apr 7 20:09:26 2023 GMT DNS:MDVARTREPO01.cpp.nonlive