この構文を使用して、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
以下を行う必要があります。
:
フィールド区切り文字を使用しているとawkに通知します。- 行全体ではないフィールドを配列インデックスとして使用し、
- 値の代わりにインデックスが存在するかどうかをテストする
つまり、これを行う:
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で埋めます。1
2.txt
a[]
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