awk
を使用してファイル比較を学習しています。
私は以下のような構文を見つけました、
awk 'NR==FNR{a[$1];next}$1 in a{print $1}' file1 file2
これでNR==FNR
の重要性が理解できませんでしたか? FNR==NR
を試してみると、同じ出力が得られますか?
それは正確に何をしますか?
Awkでは、FNR
は現在のファイルのレコード番号(通常は行番号)を指し、NR
は合計レコード番号を指します。演算子==
は比較演算子で、周囲の2つのオペランドが等しい場合にtrueを返します。
つまり、FNR
は各ファイルの最初の行で1にリセットされますが、NR
は増加し続けるため、条件NR==FNR
は最初のファイルに対してのみ真になります。
このパターンは通常、最初のファイルに対してのみアクションを実行するために使用されます。ブロック内のnext
は、それ以降のコマンドがスキップされることを意味するため、最初のコマンド以外のファイルでのみ実行されます。
条件FNR==NR
は、NR==FNR
と同じ2つのオペランドを比較するため、同じように動作します。
File1にもあるfile2のキー(行の最初のワード)を探します。
ステップ1:配列aをファイル1の最初の単語で埋めます。
awk '{a[$1];}' file1
ステップ2:配列aを埋め、同じコマンドでファイル2を無視します。これについては、現在の入力ファイルの数を使用して、これまでのレコードの総数を確認してください。
awk 'NR==FNR{a[$1]}' file1 file2
ステップ3:ファイル1の解析時に}
の後に続く可能性のあるアクションを無視する
awk 'NR==FNR{a[$1];next}' file1 file2
ステップ4:配列aで見つかったfile2のキーを印刷する
awk 'NR==FNR{a[$1];next} $1 in a{print $1}' file1 file2
AwkマニュアルでNR
とFNR
を検索し、次の例でNR==FNR
がどの条件に該当するかを自問してください。
$ cat file1
a
b
c
$ cat file2
d
e
$ awk '{print FILENAME, NR, FNR, $0}' file1 file2
file1 1 1 a
file1 2 2 b
file1 3 3 c
file2 4 1 d
file2 5 2 e
awk
組み込み変数があります。
NR
-処理されたレコードの総数を示します。
FNR
-各入力ファイルのレコードの総数を示します。
ファイルa.txtとb.txtがあり、
cat a.txt
a
b
c
d
1
3
5
cat b.txt
a
1
2
6
7
NRとFNRはawk組み込み変数であることに注意してください。 NR-処理されたレコードの総数を示します。 (この場合、a.txtとb.txtの両方)FNR-各入力ファイルのレコードの総数を提供します(a.txtまたはb.txtのいずれかのレコード)
awk 'NR==FNR{a[$0];}{if($0 in a)print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
a.txt 1 1 a
a.txt 2 2 b
a.txt 3 3 c
a.txt 4 4 d
a.txt 5 5 1
a.txt 6 6 3
a.txt 7 7 5
b.txt 8 1 a
b.txt 9 2 1
「次」を追加して、NR == FNRと最初に一致したものをスキップします。
b.txtおよびa.txtで
awk 'NR==FNR{a[$0];next}{if($0 in a)print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
b.txt 8 1 a
b.txt 9 2 1
b.txtにありますが、a.txtにはありません
awk 'NR==FNR{a[$0];next}{if(!($0 in a))print FILENAME " " NR " " FNR " " $0}' a.txt b.txt
b.txt 10 3 2
b.txt 11 4 6
b.txt 12 5 7
awk 'NR==FNR{a[$0];next}!($0 in a)' a.txt b.txt
2
6
7