How to Process Multiple Files Using NR and FNR in awk on Linux

When you are executing a massive data reconciliation task within a Linux terminal (e.g., comparing a master database file against a daily transaction file), feeding both files into an awk pipeline simultaneously will cause catastrophic logic failures unless you explicitly instruct the engine how to track its geometric location. To force awk to mathematically differentiate between File 1 and File 2, you must deploy the NR and FNR system variables.

Executing the Multi-File Matrix

The GNU awk architecture utilizes two absolute record counters to track its progression through a data stream.

  • NR (Number of Records): The absolute, cumulative total of lines read. If File 1 has 10 lines and File 2 has 5 lines, NR will count from 1 to 15 continuously.
  • FNR (File Number of Records): The local, geometric line count for the currently active file. When awk finishes File 1 and jumps to File 2, the FNR counter violently resets to 1.

Deploying the Comparison Vector

By comparing NR against FNR, you create a flawless Boolean logic gate. If NR == FNR, you are mathematically guaranteed to be processing the very first file. If NR != FNR, you are processing the second (or third) file.

Imagine you have a Master List of IDs (master.txt) and a Daily List (daily.txt). You must identify which Daily IDs do not exist in the Master List.

To execute the cross-referencing vector, analyze this precise command:

awk 'NR == FNR { master_array[$1] = 1; next } !($1 in master_array) { print "Unauthorized Node Detected:", $1 }' master.txt daily.txt

Analyzing the Reconciliation Calculus

The exact millisecond you execute this script, the awk engine intercepts the payload.

  • The engine opens the absolute first file: master.txt.
  • It reads line 1. NR is 1, and FNR is 1. The gate NR == FNR evaluates True.
  • It executes the block: master_array[$1] = 1. It rips the ID from column 1 and uses it as a geometric key in a new associative array, locking the Master List into active RAM. The next command aborts the rest of the script and jumps to the next line.
  • This loop repeats until master.txt is completely consumed.
  • The engine opens the second file: daily.txt.
  • It reads line 1 of the new file. NR continues incrementing (e.g., 501), but FNR violently resets to 1.
  • The gate NR == FNR (501 == 1) evaluates False. The engine bypasses the array-loading block entirely.
  • It hits the second block: !($1 in master_array). The engine mathematically checks if the Daily ID exists in the RAM array. If the Boolean evaluation is False (the ID is missing), it executes the print command, successfully isolating the rogue data node.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.