在特定列中搜索模式并输出整行

在特定列中搜索模式并输出整行

我正在 HDFS 中工作,并试图获取第四列以数字 5 开头的整行:

100|20151010|K|5001
695|20151010|K|1010
309|20151010|R|5005
410|20151010|K|5001
107|20151010|K|1062
652|20151010|K|5001

因此应该输出:

100|20151010|K|5001
309|20151010|R|5005
410|20151010|K|5001
652|20151010|K|5001

答案1

最简单的方法可能是awk

awk -F'|' '$4~/^5/' file

-F'|'字段分隔符设置为|$4~/^5/如果第四个字段以 开头,则为true 5。当某些内容评估为 true 时的默认操作awk是打印当前行,因此上面的脚本将打印您想要的内容。

其他选择有:

  • 珀尔

    perl -F'\|' -ane 'print if $F[3]=~/^5/' file
    

    同样的想法。该-a开关会perl根据给定的值将其输入字段拆分-F到数组中@F。然后,我们打印数组(数组从 0 开始计数)的第 4 个元素(字段)是否以 开头5

  • grep

    grep -E  '^([^|]*\|){3}5' file 
    

    正则表达式将匹配字符串 non-|后跟|3 次 a,然后是5.

  • GNU 或 BSDsed

    sed -En '/([^|]*\|){3}5/p' file 
    

    打开-E扩展正则表达式并-n抑制正常输出。正则表达式与上面相同grepp最后的 使sed仅打印与正则表达式匹配的行。

答案2

这将打印所有匹配的行|5,然后不再打印,|直到行尾:

grep '|5[^|]*$' <in >out

答案3

如果您希望使用支持 CSV 的工具来解决包含嵌入|字符和换行符字段的 CSV 文件的问题,那么您可以使用以下方法mlr(Miller):

mlr --csv --fs '|' -N filter -S '${4} =~ "^5"' file

这使得使用字段分隔符将mlr原始数据读取为无标头 CSV 文件(这就是作用)。它应用一个过滤表达式来提取该表达式为真的记录。这样做时,它避免推断数据类型并将数据视为字符串(,因为正则表达式通常仅适用于字符串)。|--csv --fs '|' -N-S

该表达式将正则表达式^5与记录的第四个字段相匹配。

提取的记录以 CSV 格式再现,并具有与输入相同的字段分隔符。

您可以使用 csvkit 包中的工具执行相同的操作,但由于无法告诉输出使用自定义字段分隔符,因此如果您想保留分隔符csvgrep,则必须重新格式化结果:csvformat|

csvgrep -d '|' -H -c 4 -r '^5' file | csvformat -K 1 -D '|'

跳过由 生成的匿名标题行-K 1的选项。csvformatcsvgrep

答案4

使用(以前称为 Perl_6)

~$ raku -ne '.put if .split("|")[3].starts-with("5");' file

输入示例:

100|20151010|K|5001
695|20151010|K|1010
309|20151010|R|5005
410|20151010|K|5001
107|20151010|K|1062
652|20151010|K|5001

示例输出:

100|20151010|K|5001
309|20151010|R|5005
410|20151010|K|5001
652|20151010|K|5001

-ne简而言之,Raku 被指示使用标志(n意味着非自动打印)从命令行逐行读取输入。put如果split|垂直条上零索引的3-rd 元素(即第四列),则行出线starts-with("5")

对于更复杂的CSV文件,请使用 Raku 的Text::CSV模块。

https://unix.stackexchange.com/a/705099/227738
https://raku.org

相关内容