
次のawk
コマンド1.txt
は2.txt
。
awk 'NR==FNR{b[$0]=1;next}!b[$0]' 1.txt 2.txt
awk
この構成が欠落している行を見つける方法を段階的に調べる必要があります。
答え1
スクリプトは、最初のファイルに表示されない2番目のファイルのすべての行を出力します。
awk 'NR==FNR { b[$0] = 1; next } !b[$0]' 1.txt 2.txt
スクリプトはawk
まず。現在のレコードを含む、これまでに読み取ったレコード(行)の総数。読み取ったレコードの数。NR
FNR
NR
FNR
現在の入力ファイル。これら2つの数字が同じであれば、私たちはまだ読んでいます。最初入力ファイル。衝突が発生します。最初のファイルが次の場合空NR == FNR
2番目のファイルも同じです。
最初の入力ファイルを読み取ると(空ではないと仮定)、現在のレコードb[$0] = 1
の内容がハッシュキーとして使用され、そのキー1の値が配列に格納されますb
(配列インデックスはawk
から文字列になります。次にスクリプトが実行されますnext
。)スクリプトの先頭に戻り、次のレコードを読みます。
のNR
場合いいえ同じFNR
、それは私たちが読んでいることを意味します。第二現在の入力レコード(行)を以前に入力した配列のキーとして使用する2つの入力ファイルのテスト!b[$0]
。b
現在のレコードが 1 として保存されている場合、以前b
に最初のファイルでレコードが見つかったことがわかります。否定的な!
テスト。
テストが真の場合、つまり、2番目のファイルの現在の行が以前に最初のファイルに表示されていない場合は、基本的な操作が実行されます。そのブロックがないテストのデフォルトの動作は、{...}
現在の行を出力することです(つまり、コードがあるかのように動作します!b[$0] { print }
)。
このawk
スクリプトは、最初のファイルのすべての(固有の)行をメモリに読み込むため、次を実行します。非常に大容量ファイル。
このような場合は、次のことをお勧めします。
comm -13 <( sort -u file1 ) <( sort -u file2 )
(これはプロセスの置き換えについて知っているシェルが必要です)または単に
comm -13 file1 file2
ファイルがすでにソートされている場合。
これは生成されません精密スクリプトと同じ出力は、awk
2回以上発生するすべての行をfile2
各発生ごとに1回出力しますが、入力で上記のコマンドを使用しても出力されませんcomm
。sort -u
詳しくは、comm
システムのマニュアルを参照してください。
コメントの問題を解決するには、次の手順に従ってください。
- はい、
FNR
現在の入力ファイルから読み取られたレコードの数。 NR
そして、FNR
いずれかのファイルに「属していない」。これはカウンターだけです。FNR
ファイルの終わりに達すると、カウンタはリセットされます。- ファイルから1行を読むと
NR
増加します。FNR
このnext
コマンドはスクリプトの先頭に強制的に移動し、次の行を読み取らせます。新しい行を読むと、NR
合計が増えます。FNR
- もしそうなら
NR != FNR
、これは最初のファイル以上に移動したことを意味します。FNR
前のファイルの終わりに達するとゼロにリセットされますが、NR
計算を続けます。 $0
現在行を保持する変数です。ファイルから読み取った行全体を保存します。開催待機$1
中$2
フィールド現在の行の値はIFS
変数値(通常は空白)に分割されます。現在行がある場合は、そのhello world
値$0
を持ち、その値を持ち、hello world
その値を持ちます(行がスペースに分割されるため)。スクリプトは、「現在の入力行の内容」と考えられるwhileを使用します。$1
hello
$2
world
$0
$0
b[$0] = 1
配列の特定の場所/インデックスに値を割り当てますb
。位置は現在の行によって決定され、$0
値1が割り当てられます。これにより、配列はb
「照会テーブル」のように動作します。b[i]
特定のインデックスが1の場合、i
最初の入力ファイルで発生することを意味します。!b[$0]
$0
インデックスに格納されている値がb
0(または初期化されていない場合)の場合は真です。つまり、b[$0]
値 1 が割り当てられていない場合、つまり、2 番目のファイルから読み込んだ行が最初に最初のファイルに表示されなかった場合です。このテストに対応するアクション(ブロックなし)がないため、デフォルトのアクションである{...}
印刷を実行します。$0
これは、最初のファイルにない2番目のファイルのすべての行を印刷する効果があります。