我正在 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 或 BSD
sed
sed -En '/([^|]*\|){3}5/p' file
打开
-E
扩展正则表达式并-n
抑制正常输出。正则表达式与上面相同grep
,p
最后的 使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
的选项。csvformat
csvgrep
答案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