将参数传递给 sed 的 LHS 中的 date 命令

将参数传递给 sed 的 LHS 中的 date 命令

我需要将日期字符串从以下形式转换:“Jan 07, 2016 12:12:12 EDT”(来自 nessus 报告)到简单的 2016-01-07。我在 sed (以及 python 和 awk)中解决了匹配逻辑,并且还使用 date 命令解决了转换逻辑(在 sed 之外): date "Jan 07, 2016 12:12:12 EDT" +%Y-%m-%d

我使用匹配组来捕获月份、日期和年份,以便我可以在后面的引用中引用它们。我似乎找不到正确的引号组合来获取 data 命令来识别 sed 匹配的 RHS 中的参数,例如:

sed -E "s/(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)(\s[0-9]{1,2}[,].[0-9]{1,4}.?[0-9]{1,2}.[0-9]{1,2}.[0-9]{1,2}.\w{3})/`date -d "\1\2" "+%Y-%m-%d"`/g" 20170917.csv

请注意,使用任何引号都会导致日期忽略第一个参数并根据第二个参数打印今天的日期。

我已经迭代使用", ', \",\' 包围 backrefs \1 和 \2 但似乎一旦它们被包含在反引号 `` 中以允许执行日期命令,它们就会被忽略。

输入是来自 Tenable Nessus 报告的 csv。

头tmp/20180121.csv

(1)“插件”、“插件名称”、“系列”、“严重性”、“IP 地址”、“协议”、“端口”、“利用?”、“存储库”、“MAC 地址”、“DNS 名称” ","NetBIOS 名称","插件文本","首次发现","最后观察到的","缓解","利用框架"

(2) "73571","Oracle Java SE 多个漏洞(2014 年 4 月 CPU)(Unix)","杂项","严重","10.140.162.132","TCP","0","是", "Individual Scan","00:50:56:c0:00:01","host.example.com","","插件输出:以下易受攻击的 Java 实例安装在远程主机上:

路径:/opt/Geneious_linux64_7_1_9_with_jre/ 安装版本:1.7.0_51 修复版本:1.5.0_65 / 1.6.0_75 / 1.7.0_55 / 1.8.0_5","2018 年 1 月 21 日 22:14:50 EST","1 月 21 日, 2018 年 22:14:50 美国东部时间","",""

每行编号都是一条记录——(1) 是标题,(2) 代表其余部分。

要转换的日期字符串位于第 2 行的最后一行。在这两种情况下,我需要的都是简单的:2018-01-21。

答案1

一种常见的方法是添加转换表并使用反向引用:

echo 'Jan 07, 2016 12:12:12 EDT' | sed -E '
  s/$/Jan01Feb02Mar03Apr04May05Jun06Jul07Aug08Sep09Oct10Nov11Dec12/
  s/^(...) (..), (....).*\1(..).*/\3-\2-\4/'

如果你想运行seddate翻译日期,你必须使用 GNU 扩展:命令e的标志s(以及 GNUdate扩展-d)。

echo 'Jan 07, 2016 12:12:12 EDT' | sed -E '
  s/^([[:alpha:]]{3} [[:digit:]]{2}, [[:digit:]]{4}).*$/date -d "\1" +%F/e'

不过,这意味着date为每一行输入运行一个 shell,这是相当低效的(而且也很危险,因为我们让 sh 解释根据输入动态生成的代码,而我们不知道我们是否可以信任该输入)。如果perl您不想在sed.

相关内容