Linux/bash 解析文本输出,选择字段,仅忽略一个字段中的空值
Posted
技术标签:
【中文标题】Linux/bash 解析文本输出,选择字段,仅忽略一个字段中的空值【英文标题】:Linux/bash parse text output, select fields, ignore nulls in one field only 【发布时间】:2015-07-02 14:47:08 【问题描述】:我已经完成了必要的 20 次搜索,但我找不到包含我正在尝试做的“忽略 null”部分的示例。在使用 bash 并具有 grep/awk/sed/perl 和其他常见嫌疑人的 Linux 系统上工作。作业的输出格式为:
Some Field I Dont Care About = Nothing Interesting
Another Field That Doesnt Matter = 216
Name = The_Job_name
More Useless Stuff = Blah blah
Estimated Completion = Aug 13, 2015 13:30 EDT
Even Yet Still More Nonsense = Exciting value
...
当前未激活的作业的预计完成时间将为空值。字段名称很长,多词名称包含空格,如图所示。定界符始终为“=”,并且始终出现在同一列中,并在两侧用空格填充。可能列出了几十个工作,每个工作大约有 36 个字段。在任何给定时间,只有一两个活跃的,而那些是我关心的。
我正在尝试为当前活动的每条记录在一行上获取“名称”字段的值和“估计完成”字段的值,因此忽略空值,如下所示:
Job_04 Aug 13, 2015 13:30 EDT
Job_21 Aug 09, 2015 10:10 EDT
...
我从<command> | grep '^Name\|^Estimated'
开始,这让我得到了我关心的台词。
我已经转到awk -F"=" '/^Name|^Estimated/ print $2'
,它自己获取值。这就是开始出错的地方 - 我尝试使用awk -F"=" '/^Name|^Estimated/ print $2'| sed 'N;s/\n/ /'
加入所有其他行,但输出非常不稳定。除此之外,我不确定我是否应该寻找空行并消除它们(和前一行)以在这一点上摆脱空值,或者是否最好将值读入变量并打印它们。
我不是 Perl 人,但如果那是更好的方法,我很乐意换档并朝那个方向前进。任何想法或建议表示赞赏,谢谢!
Some Field I Dont Care About = Nothing Interesting
Another Field That Doesnt Matter = 216
Name = Job_4119
More Useless Stuff = Blah blah
Estimated Completion =
Even Yet Still More Nonsense = Exciting value
...
【问题讨论】:
您能澄清一下您对 NULL 的含义吗?如果名称为空,估计是否为空? 贴一个空字段的例子。 【参考方案1】:我无法评论,没有足够的声誉...... 但我认为这样的事情会在你的打印命令中起作用
printf "%s,",$2;nextprint;
或者使用粘贴命令?
paste -s -d",\n" file
【讨论】:
【参考方案2】:你可以这样做:
awk -F"=" '/^Name/ name=$2 /^Estimated/ print name, $2' file
如果它们总是以相同的顺序出现:首先命名,然后估计。
然后您可以在最后一个字段中添加一个 NULL 检查,如果匹配,则不打印该行:
awk -F"=" '/^Name/ name=$2 /^Estimated/ if($2 != "") print name, $2' file
【讨论】:
第二个版本非常接近工作 - 从上面 Ed 的评论中将 -F"=" 更改为 -F" = " 并且它可以工作。由于某种原因,结果周围有一些额外的空格,使用更大的导出进行测试以验证这没有什么不同。for some reason
- 这并不神秘,-F" = "
您告诉 awk =
两侧的 1 (one) 空间是字段的一部分分隔符和之前/之后的所有其他空格都是该字段的一部分。
抱歉,我遗漏了尝试“=”、“=”、'[[:space:]]*=[[:space:]]*' 和 '\\ s*=\\s* 第一次。后两者都完全消除了空行,并按预期返回了日期,但没有返回对应的名称字段值。我现在意识到我不应该在凌晨 3:00 发布这些内容,因为我在等号右侧的输入示例格式中犯了一个错误——实际文件在等号和等号之间总是有一个空格右侧的数据。我已经更新了示例以显示这一点。很抱歉造成混乱。【参考方案3】:
$ awk -F'\\s*=\\s*' 'a[$1]=$2 /^Estimated/ && $2print a["Name"], $2' file
The_Job_name Aug 13, 2015 13:30 EDT
如果您不使用 gawk,请将 \\s
替换为 [[:space:]]
,即:
$ awk -F'[[:space:]]*=[[:space:]]*' 'a[$1]=$2 /^Estimated/ && $2print a["Name"], $2' file
如果你的 awk 甚至不支持字符类,那么 GET A NEW AWK 但与此同时:
$ awk -F'[ \t]*=[ \t]*' 'a[$1]=$2 /^Estimated/ && $2print a["Name"], $2' file
【讨论】:
这很接近 - 不使用 gawk(所以我在命令中使用了-F' = '
)。它不显示空值,但也不显示“名称”的值,只显示估计完成的值。
这是绝对正确的行为。现在请重新阅读我的答案的最后一行,我在其中给出了明确、具体、简单的说明,说明如果您不使用 gawk 需要进行哪些更改,然后将其与您实际所做的更改进行比较。以上是关于Linux/bash 解析文本输出,选择字段,仅忽略一个字段中的空值的主要内容,如果未能解决你的问题,请参考以下文章