我有一个 csv 文件,其中我必须找到第 6 个位置处包含特定单词“Happy”的行数,即。 5 个逗号后。
所以我正在写这个:
grep -P -c ",\{5,\}"'Happy' file.csv
但它返回 0。
文件内容为:
123、abc、def、ghi、e444、快乐、224、e44
答案1
grep -E '^([^,]*,){5}Happy' <in >out
这样就会发现Happy
仅当它紧邻第五个逗号时。如果您想在第 6 个字段内的任何位置找到它,请添加一点喘息空间:
grep -E '^([^,]*,){5}[^,]*Happy' <in >out
如果您只想计算匹配的行数,请使用以下-c
选项:
grep -cE '^([^,]*,){5}[^,]*Happy' <in >out
我对正则表达式非常熟悉,但即使我不熟悉,我想我仍然会选择 re 语法而不是其他类型。一旦你掌握了一些基线的窍门,其余的就会一起出现。正则表达式通过以多种方式组合极少数基本构建块来描述输入。
*
克林星- 表示前一个表达式出现 0 次或多次
[
括号表达式]
- 表示出现任何一个(可能
^
被否定)包含的字符集
- 表示出现任何一个(可能
{
最小,
最大}
重复次数指定前一个表达式的出现次数
扩展的正则表达式元
?
字符只是 的简写{0,1}
。
(
子表达式)
- 将所有包含的表达式收集到单个表达式中。
.
特点- 匹配任何单个字符
^|$
- 指示
^
以下表达式的行头锚点,或|
表达式之间的交替,或$
行尾锚点
- 指示
这些是基础知识。 POSIX-E
扩展正则表达式语法还包括克莱内 +
- 这与*
除了需要以外的各个方面最后一个与前一个表达式匹配。[
括号表达式还存在各种可能的微妙之处]
- 特别是与内部[(:|.|=)
字符类(=|.|:)]
以及它们如何匹配重复有关。大多数实现实际上延长扩展的 re 语法至少可以处理对早期子表达式的基本正则表达式\[num]
反向引用。(
)
但仅考虑到基础知识,上述任何一个表达式或任何其他单个字符本身就是一个表达式,它们全部组合成整体表达式来描述您想要的匹配。
把所有这些放在一起,grep
上面的表达式分解如下:
^([^,]*,){5}Happy
- 从最左边的位置开始,匹配的行必须包含不超过或少于 5 个由 0 个或多个非逗号字符组成的序列,每个序列后面紧跟一个逗号字符,并且所有序列后面都紧跟字符串
Happy
。
- 从最左边的位置开始,匹配的行必须包含不超过或少于 5 个由 0 个或多个非逗号字符组成的序列,每个序列后面紧跟一个逗号字符,并且所有序列后面都紧跟字符串
答案2
你可以做:
grep '^[^,]*,[^,]*,[^,]*,[^,]*,[^,]*,Happy' file.txt
假设从行的开头开始有 5 个逗号,如果从行中的任何位置开始,只需删除 initial ^
。
您的模式只是寻找连续具有五个或更多逗号的行。
答案3
我认为awk
在处理 CSV 文件时,使用命令会更简单、更容易。它对场的概念有天然的支持,这使得生活变得更加容易。
awk -F, '$6 == "Happy" { count++ } END { print count }' file.csv
该命令分解如下:
awk - The command to run
-F, - Use a comma as the field separator
$6 == "Happy" - Only match lines where the sixth field equals "Happy"
{ count++ } - For each line matched, add one to the "count" variable
END - When all that is done...
{ print count } - ...print the value of "count"
file.csv - The file to read from