目的の形式と一致しないcsvファイルの行を削除する

目的の形式と一致しないcsvファイルの行を削除する

次のように自動生成されたCSVファイルがたくさんあります。

1603145914502,48.12,0.085,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
1603145915612,48.12,0.033,s
1603145915899,48.12,0.019,s

整数、2つの浮動小数点数と文字。

ビルド中のスレッドの問題により、一部のファイルが破損しています。

1603145914502,48.12,0.085,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
1603145915612,48.12,0.033,s
1603145915899,48.12,0.019,s
1603145914502,48.12,0.085,s915899,48.12,0.019,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
1603145915612,48.12,0.033,s
1603145915899,48.12,0.019,s
1459143
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s

形式に合わない行を見つけて削除する方法はありますか? awkはうまくいくようですが、どのように使用するのかわかりません:)

これを行う方法がある場合は、コマンドから何かを学ぶことができるようにコマンドも説明できれば本当に感謝します。


編集:形式を明確にしています。

整数、浮動小数点、浮動小数点、文字

カンマの後にスペースを入れてはいけません。値は、上記の形式に準拠する任意の値にすることができます。

答え1

次の単純/基本形式(符号なし、指数なし)と一致するために必要なのは、これらのうちの1つだけですINT,FLOAT,FLOAT,CHAR

grep -E '^[0-9]+,([0-9]+\.[0-9]+,){2}[[:alpha:]]$' file

sed -En '/^[0-9]+,([0-9]+\.[0-9]+,){2}[[:alpha:]]$/p' file

awk '/^[0-9]+,([0-9]+\.[0-9]+,){2}[[:alpha:]]$/' file

答え2

形式に合わない行を見つけて削除する方法はありますか?

いくつかの方法があり、そのうちの1つは次のとおりです。

$ perl -n -i.bak -e 'print if /\d{13},\d\d.\d\d,\d\.\d\d\d,s$/' t.dat

$ diff t.dat.bak t.dat
7d6
< 1603145914502,48.12,0.085,s915899,48.12,0.019,s
13d11
< 1459143

$ cat t.dat
1603145914502,48.12,0.085,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
1603145915612,48.12,0.033,s
1603145915899,48.12,0.019,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
1603145915612,48.12,0.033,s
1603145915899,48.12,0.019,s
1603145914815,48.12,0.020,s
1603145914941,48.12,0.019,s
1603145915404,48.12,0.031,s
$

私はawk / sedの前にperlを使用する傾向がありますが、awkを使用してほぼ同じ方法で同じことを実行できます。


そのコマンドも説明できるので、そのコマンドで何かを学ぶことができれば本当に感謝します。

説明する

  • -nSTDOUTで印刷せずにファイルの行を繰り返します。
  • -iその場でファイルを編集
  • -i.bakそして、間違えた場合に備えて、指定されたファイル拡張子を持つバックアップコピーを保管してください。
  • -e 'script'スクリプトからコマンドを実行します(-nオプションの後の各入力行から)。
  • print if ...条件式と一致すると、その行を印刷します。
  • / ... /- これを使用してください正規表現パターンマッチングのため
  • ^行の始めに...
  • \d数字と一致
  • {3}以前に指定した3文字と正確に一致します。
  • ,リテラルのカンマ文字と一致します。
  • \.リテラルストップ文字と一致します(そうでない場合は.ワイルドカードメタ文字)。
  • sリテラル s 文字一致
  • $行の終わりと一致します(つまり、行に文字が含まれなくなりました。

より柔軟な表現は `^\d+,\d+.\d+,\d+.\d+,[a-zA-Z]$ です。

  • +少なくとも1つの古い文字
  • [...]指定されたセットの1つ
  • [a-z]aとz(含む)の間の小文字のASCII文字
  • [[:alpha:]]POSIX アルファベットのすべての文字
  • \p{Lowercase_Letter}すべてのUnicode文字小文字財産

Perl正規表現は、awk / grepで使用される正規表現とは若干異なります。私の考えでは、awk / grepの最新バージョンにはPerlスタイルの正規表現を使用するオプションがあります。-Pgrepオプションについては、マニュアルページを参照してください。

答え3

# expect
#          1         2
# 123456789012345678901234567
# 160314591xxxx,48.12,0.0xx,s

grep -Ex '160314591[0-9]{4},48\.12,0\.0[0-9]{2},s' < file.csv

厳格なマッチが行われます。一致させたい項目を多少制限して正規表現を調整できます。

関連情報