最初のファイルの特定の列と部分的に一致する可能性がある他のファイルのパターンに基づいてファイルから行を削除します。

最初のファイルの特定の列と部分的に一致する可能性がある他のファイルのパターンに基づいてファイルから行を削除します。

同様の回答を検索しましたが、部分一致の問題を解決した回答はありません。スキーマファイルはfile2で、削除する行はfile1.csvにあります。これは、ここに示されているよりも多くの列を含むかなり大きなファイルです。

file1.csv には次のフィールドがあります。

修正する:

Linking page,Last crawled
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
https://imgcop.com/img/Bwin-Mobile-App-77898390/,"Nov 17, 2018"
https://start.me/site/unibet.be?locale=fr,"Nov 17, 2018"
https://poker.partypoker402.com/en/blog/matt-savage-talks-wpt500.html,"Nov 17, 2018"

ファイル 2 には以下が含まれます。

https://roulette2.tk
paradisebingo.t
paradisebingo.tm
free-bwin.ro
sb288.co

OUTPUT
Linking page,Last crawled
Linking page,Last crawled
Linking page,Last crawled
Linking page,Last crawled
Linking page,Last crawled
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
https://start.me/discover/be/entertainment/betting?locale=ro,"Nov 17, 2018"
etc....

出力が繰り返されます。何が間違っているのかよくわかりません。

awk 'FNR == NR{ neg[$1]; next } { for ( i in neg ) if ( $1 !~ i) print }' file2.txt FPAT='([^,]*)|("[^"]+")' file1.csv > out.csv

しかし、正しく動作しませんでした。奇妙な理由でgrepが失敗します。

grep -vwF -f file2 file1.csv > output.csv

答え1

あなたがしたことは良い試みのように見えますが、正規表現のマッチング句は望む方法で動作しません。では、検索したい値が$2 !~ neg[$1]2番目のファイルから検索されます。file1neg['156398439']$1いいえ最初。したがって、あなたの状態は決して一致しません。

file1繰り返しでは、作業セクション内で正規表現比較を実行するためにこのような操作を実行できます。

awk 'FNR == NR { neg[$1]; next }{ for ( i in neg ) if ( $2 !~ i) print  }' file2 FS="," file1

FSまた、このような複雑な正規表現を使用してCSVファイルの制限を解除することはできないようですFS。フィールドを定義するのではなく、分割する制限解除子を定義することを忘れないでください。フィールドがどのように見えるかを説明する表現があるようです。 GNUは、awk他の変数がFPATこれらの正規表現を定義できるようにします。

あなたはそれを使用することができます

awk 'FNR == NR { neg[$1]; next }{ for ( i in neg ) if ( $2 !~ i) print  }' file2 FPAT='([^,]*)|("[^"]+")' file1

答え2

イニアンの答えfile21行だけ長いとうまく機能し、より一般的な答えを始めるのに最適です。しかし、私は信じています。

awk 'FNR == NR { neg[$1]; next } { ok=1; for (i in neg) if ($2 ~ i) ok=0; if (ok) print }' file2 FS="," file1

一般的にあなたが望むことを行います。答えと同様に、最初にfile2内容(から削除したいパターンfile)を読み、配列に保存します。 Inianの答えのように、次のようになりますfile1。の各行に対してのfile1パターンを繰り返しますfile2。我々は、ラインが大丈夫だと仮定します。どんなパターンにマッチすればそうではありません。すべてのパターンを確認後、問題がない場合は印刷いたします。


FS=","しかし、私はそれをイニアンがすることだからとの間の論争にしました。何も構わないfile2file1F生産するS読み取るときに使用する区切り文字は、表示されず、file2カンマfile2が含まれていない限りです。したがって、「一般的な」方法でフィールド区切り文字を指定することで、上記の内容を少し簡単にすることができます。-Fコマンドの先頭にオプションを追加するだけです。

アッ-F、'FNR == NR {否定[$1];次} { OK=1 for (i in neg) if ($2 ~ i) ok=0 if (OK) print}' file2 file1

-F","必要に応じて使用できます。


このテストはあまりにFNR == NRも一般的で一般的であり、私たちは何も考えずに使用します。  FNR行番号(別名レコード番号)。現在のファイルではNR行番号ですすべての入力にわたって。  例えば、

$ cat cats
Felix
Garfield
Heathcliff

$ cat dogs
Lassie
Marmaduke
Snoopy

$ awk '{ print FNR, NR, $0 }' cats dogs
1 1 Felix
2 2 Garfield
3 3 Heathcliff
1 4 Lassie
2 5 Marmaduke
3 6 Snoopy

…したがって、処理する最初のファイルの各行FNRの合計は同じで、後続のファイルでは同じではありません。NRだから私たちはそれを使ってFNR == NR最初のファイルが処理されているかどうかをテストします。

しかし、これは実際に悪い習慣です。最初のファイルが空の場合はどうなりますか?

$ cat unicorns

$ wc unicorns
      0       0       0 unicorns

$ awk '{ print FNR, NR, $0 }' unicorns dogs
1 1 Lassie
2 2 Marmaduke
3 3 Snoopy

FNR == NRそれは真実です。最初のファイルの場合実際にデータがあります  あなたfile2の意志が決して空でない場合は、この質問を無視できます。ただし、問題の定義によると、空の場合は何も削除されないため、file2出力はallにする必要があります。file1ただし、何もせずに上記のコマンドを実行すると、次のような結果file2が表示されます。いいえ なぜなら、実際には2番目のファイル()を読むときに最初のファイルawk()を読み込んでいると思うからです。file2file1

より安全なアプローチは、ファイルパラメータ間に値を割り当てることです。

awk -F, 'ドキュメント! = 2{否定[$1];次} { ok = 1; for(i in neg)if($ 2〜i)ok = 0 if(ok)印刷} 'ファイルファイル=2ファイル1

この質問は少しあいまいです。 「部分一致」とはどういう意味ですか?正確に? Inianは質問が提案した意味で解釈することにしました  grepfile2 2番目の列の値と一致する値がある場合file1 正規表現では、 次にその行を削除します  file1。しかし、2つの問題があります。

  1. 驚くべき要因。質問のファイルをインポートして追加しました。

    154376352,"http://sb288eco.tm","example4"
    

    に行を置いてfile1最初のコマンドを実行します。 (from)が正規表現として扱われるため、この"example4"行は出力されません(ここではsb288.cofile2.「すべての文字と一致」を意味します)、match sb288eco

    これがあなたが望んで期待するものなら、今この記事を読んではいけません。

  2. 正規表現処理には計算コストがかかります。正規表現は解析され処理されなければなりません。これは、単純な文字列比較よりも時間がかかる場合があります。

上記の2つの問題をテストすることで解決できます。ひもfrom この awk 関数のfile2 from 値に存在します。file1index

awk -F, 'FILE != 2 { neg[$1];next} { OK=1;for (i は負の数)if(index($2,i)>0)OK = 0; if(ok)印刷} 'file2 FILE = 2 file1

要約すると、.ゲームfile2にはたった一つしかありません。.file1、他の文字ではありません。お客様のデータについて上記の内容をテストし、速度が速いことを確認してください。


PS回答を投稿した後にファイル形式が変更されたことを確認しました。最初は値とfile2 値をテストしようとしています。 第二列  file1。今テストしたいようです。最初列  file1。この変更に対応するには、$2上記のいずれかの回答と比較したセクションをi使用するように変更する必要があります$1。または、行全体をテストするにはを  file1使用します$0


したがって、結論として、以下を使用したい場合があります。

awk -F, 'FILE != 2 { neg[$1]; next } { ok=1; for (i in neg) if (index($1,i) > 0) ok=0; if (ok) print }' file2 FILE=2 file1

あなたの命令に従って。読みやすくするために、改行は次のとおりです。

awk -F, 'FILE != 2 { neg[$1]; next }
                   {
                     ok=1
                     for (i in neg)
                             if (index($1,i) > 0) ok=0
                     if (ok) print
                   }' \
        file2 FILE=2 file1

関連情報