行削除構文

行削除構文

この構文を使用して、2.txt次の行を削除します1.txt

awk 'NR==FNR{a[$0]=1;next}!a[$0]' 2.txt 1.txt  > lines.txt

私の行の形式は次のとおりです。

[email protected]:something

両方のファイルの行が同じであれば、この内容がないのでlines.txt大丈夫です。しかし[email protected]、同じ場合は、行を削除して次の単語を無視したいと思います:

答え1

これを使用してください:

awk -F: 'NR==FNR{a[$1]=1;next}!a[$1]' 2.txt 1.txt > lines.txt

-F:- 区切り文字を:(コロン)に設定した後、最初のフィールド($1)のみを比較に使用します。

答え2

以下を行う必要があります。

  1. :フィールド区切り文字を使用しているとawkに通知します。
  2. 行全体ではないフィールドを配列インデックスとして使用し、
  3. 値の代わりにインデックスが存在するかどうかをテストする

つまり、これを行う:

awk -F':' 'NR==FNR{a[$1]; next} !($1 in a)' 2.txt 1.txt  > lines.txt

これにより、フィルを最初に読み込み、次に読み込むときにNR==FNR{a[$1]=1; next} !a[$1]不要にメモリをsで埋めます。12.txta[]1.txt $1そのファイルのすべての内容を追加します。a[]これは、a["foo"]インデックスに不必要に多くのメモリを消費するエントリを生成し、スクリプトが遅くなり、2番目のファイルが十分に大きい場合、スクリプトが失敗する可能性があるためです。a[]"foo"

一般的に、このタイプの質問では、最初のファイルは2番目のファイルよりもはるかに少ない値を持っているので、2つの方法の間の時間差についてのアイデアを提供するためにfile2の値を印刷するとします。 file1に1000行があり、file2に1000万行があると仮定すると、file1の行数は次のようになります。次のコマンドを使用して入力を生成できます。

$ awk 'BEGIN{for (i=1; i<=1000; i++) print "foo"i}' > file1
$ awk 'BEGIN{for (i=1; i<=10000000; i++) print "foo"i}' > file2

次に、file2のfile1の行印刷をテストします。

$ time awk 'NR==FNR{a[$0]=1;next}a[$0]' file1 file2 >/dev/null

real    0m4.279s
user    0m3.375s
sys     0m0.796s

$ time awk 'NR==FNR{a[$0];next}$0 in a' file1 file2 >/dev/null

real    0m1.453s
user    0m1.343s
sys     0m0.046s

そして、file1にないfile2の行印刷をテストします。

$ time awk 'NR==FNR{a[$0]=1;next}!a[$0]' file1 file2 >/dev/null

real    0m5.549s
user    0m4.828s
sys     0m0.656s

$ time awk 'NR==FNR{a[$0];next}!($0 in a)' file1 file2 >/dev/null

real    0m2.701s
user    0m2.640s
sys     0m0.000s

関連情報