我有很多(巨大且混乱的)CSV 文件,其中包含一堆(思科)序列号。
我的目标是提取它们(顺便说一句:稍后调用 Cisco API 以获得服务/支持覆盖范围反馈)
现在我正在寻找一种正确的方法来处理该 CSV 文件。
我很感兴趣是否还有其他方法,以及为什么我最初的“首选”方法不起作用——它使用包含 [:alpha:] 和 [:digit:] 组合的命名类。
为了破译序列号,以下是它的组成方式。
Cisco S/N 格式为:LLLYYWWXXXX。
LLL = 位置代码(即 FOC = 富士康中国)
YY = 年份代码(08 = 2004...09=2005...等...)
WW = 周代码(周 01 至 52)
XXXX = Base-34 字母数字唯一标识符(包括 0 到 9 以及除 I 和 O 之外的整个字母表)。
来源:https://community.spiceworks.com/how_to/96973-cisco-device-serial-number-explanation
# Doesn't Work
grep -E -o -w "[[:alnum:]]{11}" Inventory.csv | head
Description
UNIVERSALK9
techsupport
FCW203.....
UNIVERSALK9
techsupport
FCW203.....
UNIVERSALK9
techsupport
FDO201.....
[..]
# Does work
grep -o -w -P '([A-Z]){3}[0-9]{4}[[:alnum:]]{4}' Inventory.csv
FCW1234A1EF
FCW1234A1NG
FDO1234A1KB
FDO1234A103
FOC1234A137
FCW1234A10A
FOC1234A1GH
FOC1234A1GU
[..]
答案1
正如正则表达式一样,您最初的 grep 太“松散”。您要求[[:alnum:]]{11}
,这意味着 11 个“字母数字”,它允许这些非思科序列号术语:
- 技术支持
- 描述
- 通用Salk9
你的第二个 grep 是“更严格的”,这意味着它在匹配的内容上有更多的限制。它仍然不是一个伟大的不过,有两种方式适合思科序列号:
[0-9]{4}
允许 4 位数字,从 0 到 9;这将允许无效的“周”数据,例如0899
或0900
。[[:alnum:]]{4}
将允许任意 4 个字母数字,这将允许禁止的I
和O
.
您的第二个 grep 将捕获所有 Cisco 序列号,因为它允许更多的比要求,但它也会被愚弄,允许无效的序列号。
我可能会使用 awk 处理杂乱的文件,因为它允许进行一些强大的模式匹配和字符串操作。下面的 awk 脚本在较高级别上做了两件事:
- 循环输入的每一行,寻找可能是 Cisco 序列号的内容
- 在这些输入行上,查找每个潜在的匹配项;只要存在匹配,就提取该序列号并执行附加测试(检查“周”值是否有效)。如果您更了解您期望这些值是什么,您可以在此处执行“年份”测试。对于位置代码也类似,如果您希望显示一组较小的位置。
我做的唯一一件事是调整正则表达式,使其与 Base-34 部分更加紧密。
这是脚本:
awk '
BEGIN {
recisco="[A-Z]{3}[0-9]{4}[0-9ABCDEFGHJKLMNPQRSTUVWXYZ]{4}"
}
$0 ~ recisco {
while(match($0, recisco) > 0) {
week=substr($0, RSTART+5, 2);
if (week > 1 && week < 54) {
print "Found: "substr($0,RSTART,RLENGTH)
}
$0=substr($0, RSTART+RLENGTH);
}
}'