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 解析文本输出,选择字段,仅忽略一个字段中的空值的主要内容,如果未能解决你的问题,请参考以下文章

Linux Bash - 修改从标准输出中提取的文本

以编程方式读取在控制台窗口中选择的当前文本

jquery,将部分文本输入解析为格式化的html输出?

如何在颤动中选择基于下拉项添加文本字段值

Linux Bash编程之read

在 .NET 中解析分隔的 CSV