sed - 3番目のフィールドに「hotmail」を含む行を削除します。

sed - 3番目のフィールドに「hotmail」を含む行を削除します。

3番目のフィールドに、hotmailという単語を含む.txtファイルからすべての電子メールを削除しようとしています。現在、以下を使用しようとしていますが、一部の行のみが削除されます。なぜかはわかりませんが

sed -i '/^[^,]*,[^,]*,[^,]*hotmail/d' *.txt

以下は削除されていない行の1つです。

"field1","field2.","[email protected]","whoeditedoutn.com","NeditedoutOW.COM|NeditedoutW.COM","editedout",""
"foo,bar","baz,qux","[email protected]","whoeditedoutn.com","NeditedoutOW.COM|NeditedoutW.COM","editedout",""

誰でも私に正しい命令を出すことができますか?可能であれば、単語に大文字と小文字、またはhotmailその他HoTmAiLのバリアントの両方を含めるように注文してください。

答え1

これはCSVファイルなので、フィールド1と2にカンマを含めることができます。したがって、正規表現の一致は機能しません。適切なCSVパーサーが必要です。これは例です

ruby -rcsv -ne 'row = CSV::parse_line($_); puts $_ unless row[2] =~ /hotmail/i' file

修正する:このRubyコマンドはファイルを変更しません。上記のsedコマンドも同様です。変更をファイルに再保存するには、この-iオプションを使用します。 Pastebinデータの使用:

wc -l file
ruby -rcsv -i -ne 'row = CSV::parse_line($_); puts $_ unless row[2] =~ /hotmail/i' file
wc -l file
  22 file
  20 file

PerlにはCSVモジュールもありますが、標準ではありません。CPANで獲得- エラー処理が実装されていません。

perl -MText::CSV -le '
  $csv = Text::CSV->new({ binary=>1, always_quote=>1 });
  open $fh, "<", shift(@ARGV);
  while ($row = $csv->getline($fh)) {
    $csv->print(STDOUT, $row) unless $row->[2] =~ /hotmail/i;
  }
' file

答え2

解決方法を問い合わせるとsed

sed -n -e '/^"[^,]*","[^"]*",".*@hotmail/Ip' file

ここでは削除する行のみを印刷します。元の選択に戻り、必要に応じて正確に実行してください。/Ip次に変更してもう一度/Id変更-n-i

/I大文字と小文字を区別しない検索を提供

2番目のフィールドは、カンマの代わりに使用され、[^"]内部にカンマを含むフィールドが分​​割されないようにします。

フィールドに引用符を追加し、ドメイン名の前に@を追加してEメールアドレスのように見えました。

更新:このバージョンは@hotmail.comの後に2つの電子メールアドレスが続くことを保証します。つまり、初めてオンラインに接続したのです。

3番目の列でホットメールアドレスを検索します。

sed -n -e '/^"[^"]*","[^"]*","[email protected]",.+@.+,.+@.+$/Ip' file

これは、3番目の列のどこでもホットメールに適用されるため、Pastebinのテストデータでも機能します。

sed -n -e '/^"[^"]*","[^"]*",".*hotmail.+",.+@.+,.+@.+$/Ip' file

アップデート2:

正規表現を次のように単純化しました。

sed -n -e '/^("[^"]*",){2}"[^"]*hotmail[^"]*"/Ip'

答え3

使用csvkit:

csvgrep -c 3 -i -r '(?i)hotmail' file.csv

これはfile.csvヘッダー行があると仮定します。

関連情報