如何 grep 出与给定模式不匹配的所有行

如何 grep 出与给定模式不匹配的所有行

我在 Linux 上收到了 csv 文件,它们有自己不同的模式,这里有一个例子:

$ head test.csv
wampproduct,wamp_date,wampregion,region_search_phrase,wamp,date_pull,end_of_month_dt
CD Short-Term WAMP,2010-1-1,MA,MA,0.8763918845487475,201901,2019-01-31
CD Short-Term WAMP,2010-1-1,RI,RI,0.8576695707678873,201901,2019-01-31
CD Short-Term WAMP,2010-1-1,NH,NH,0.9038538021630779,201901,2019-01-31
CD Short-Term WAMP,2010-1-1,CT,CT,0.9699202728104309,201901,2019-01-31
CD Short-Term WAMP,2010-1-1,VT,VT,1.0631714504202636,201901,2019-01-31
CD Short-Term WAMP,2010-1-1,PGH,PGH,0.9517353522520116,201901,2019-01-31
CD Short-Term WAMP,2010-1-1,COM,COM,0.7401903422784099,201901,2019-01-31
CD Short-Term WAMP,2010-1-1,DE,DE,0.8485585323154969,201901,2019-01-31
CD Short-Term WAMP,,2010-1-1,PHI|,PHI,,,,1.0009405151305597,201901,2019-01-31

您可能已经注意到,所有字段均采用 xxxx,xxxx,xxxx,xxxx,xxxx,xxx,xxxx 的模式

但是,有一行(示例中的最后一行)包含格式错误的数据: xxxx,,xxxx,xxx|,xxx,,,,xxx,xxxx

我想知道如何编写命令或脚本来 1. 定义模式的正则表达式(最好将其放在单独的文件中); 2. 从原始数据中 grep 出不匹配的行,在这种情况下,应 grep 出最后一行。

答案1

假设没有任何字段实际上包含引号:

awk -F, 'NF == 7' file
awk -F, 'NF != 7' file   # show the "bad lines"

这会打印任何包含 7 个逗号分隔字段的行。

如果这是一个正确的 CSV 文件(其中引用的字段可能包含字段分隔符),那么您将需要一个 CSV 解析器。我喜欢用 ruby​​ 来表示:

ruby -rcsv -pe 'next unless CSV.parse_line($_).length == 7' test.csv
ruby -rcsv -pe 'next if CSV.parse_line($_).length == 7' test.csv  # show the "bad"

正则表达式提供优雅的解决方案,但在我看来不是这里

grep -E '^([^,]+,){6}[^,]+$' test.csv
grep -vE '^([^,]+,){6}[^,]+$' test.csv   # show the "bad" lines

相关内容