从第二个字段逐行搜索模式并打印出与找到该模式的行对应的第一个字段

Posted

技术标签:

【中文标题】从第二个字段逐行搜索模式并打印出与找到该模式的行对应的第一个字段【英文标题】:search for pattern line by line from the second field and print out the first field corresponding to the line where the pattern was found 【发布时间】:2021-12-03 08:28:07 【问题描述】:

我在下面有以下0.txt 文件按列(字段)分隔内容:

'Disinfectants', 'Brand A', 'Brand B', 'Brand C'
'brand A', 'below brand C', 'greater than brand B'
'brand B', 'greater than brand D', 'below brand A'

我想在每次出现模式(比如“品牌 A”)时查找(从第二列),并打印出属于该模式所在行的第一列的内容。 对于这两个结果文件的内容都是这样的:

Disinfectants
brand B

我见过其他类似的问题,但只打印找到模式的列本身,通常使用grep

编辑更新:来自@jubilatious1 建议 ,作为寻找解决方案的一部分,我在操作系统上发现了一个问题 (https://***.com/a/9153113)。

awk '/brand A/ print substr( $1, RLENGTH )' 0.txt > 1.txt

但我的1.txt 输出与预期不同,因为它仅打印第一个字段(列)的部分内容:

'brand
'brand

此外,仅使用 awk '/brand A/ print substr( $1, RLENGTH )' 我无法指定搜索只能从第二个字段(列)开始对每一行进行。

编辑更新 1:也许只是修复awk '/brand A/ print substr( $1, RLENGTH )' 的输出,以便正确打印第一列中的字段内容是第一步。

【问题讨论】:

您至少尝试过什么吗?这似乎是一个awk 任务,您没有在 SO 上查看现有答案吗?有很多地方可以检查与模式匹配的行并打印第一个字段。 我已经使用grep 找到了粗略的答案,但还没有专注于使用awk 获取答案,我现在会尝试这样做,让我休息一下。 第一行有4列,而第二行和第三行只有三列。 @jubiloso1 是的,只有第一行有 4 列,但正是在这种情况下,我正在寻找解决方案。我还没有抽出时间使用awk搜索问题,但我会继续尝试新的努力。 【参考方案1】:

Hackish 管道:

cut -d, -f2- 0.txt | grep -ni 'brand a' | sed 's/:.*/p/' | sed -nf- 0.txt | cut -d, -f1

以逗号分隔并省略字段 1 grep 查找带有“品牌 a”的行号(不区分大小写) 将行号转换为 linenumberp -- 用于打印该行的 sed 命令 将这些 sed 命令通过管道传送到 sed -nf- ...这将仅在来自标准输入的指示时打印...因此您只会获得所需的行 以逗号分隔并仅打印第一个字段

或者perl:

perl -lanF, -e 'print $F[0] if grep /brand a/i, @F[1..$#F]' 0.txt

自动拆分为 @F 逗号,如果在任何其他字段中找到“品牌 a”(不区分大小写),则打印第一个字段。

都输出这个:

'Disinfectants'
'brand B'

您可以随意去掉单引号,或者,您可以更改 split 正则表达式以实现 perl 自动拆分:

perl -lanF"/[',]+/" -e 'print $F[1] if grep /brand a/i, @F[2..$#F]' brand.txt

要得到这个:

Disinfectants
brand B

...请注意,一旦行以拆分分隔符开头,$F[0] 就是一个空字符串。

【讨论】:

当搜索模式包含单引号时,我无法使用它 最后一个是将任何单引号和/或逗号序列转换为字段分隔符,因此引号将消失。如果您想搜索单引号,我建议您使用第二个 perl 示例(逗号分隔符),并尝试在 'grep' 之后的正则表达式中使用反斜杠转义单引号 感谢您的建议和澄清,但我在代码上的 grep 中添加了 -w 选项,并在搜索字符串周围的单引号周围添加双引号,它起作用了 grep -w 将等同于在正则表达式的任一端添加\b。 (对于单词边界) 是的,我还记得\b,我试过cut -d, -f2- 0.txt | grep -ni 'brand a\b' | sed 's/:.*/p/' | sed -nf- 0.txt | cut -d, -f1perl -lanF, -e 'print $F[0] if grep /brand a\b/i, @F[1..$#F]' 0.txt,它成功了。

以上是关于从第二个字段逐行搜索模式并打印出与找到该模式的行对应的第一个字段的主要内容,如果未能解决你的问题,请参考以下文章

如何设置纵向和横向约束

我想写两个plsql程序。在一个过程中获取数据并从第二个过程中打印出来

iPad 搜索显示控制器从第二个单元格开始显示结果

通过一次提交发送双表单,同时将电子邮件字段从第一个表单拉到第二个表单

2-websocket 模式下的 Websocket 挂起

文本处理三剑客之GREP