与えられたパターンと一致しないすべての行を特定する方法

与えられたパターンと一致しないすべての行を特定する方法

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パターンに従うことに気づきます。

ただし、1行(例の最後の行)には、無効な形式のデータ(xxxx、、xxxx、xxx |、xxx、、、、xxx、xxxx)が含まれています。

1.パターンの正規表現を定義します(別のファイルに入れることをお勧めします)。 2. 生データから一致しない行を見つけます。最後の行をクリーンアップする必要があります。

答え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

関連情報