# This program implements the UNIX comm program. # Syntax: # comm [-1] [-2] [-3] file1 file2 # Description: # Comm reads two files, which must be already sorted using # a standard ASCII collating sequence, and prints a three-column # output: lines only in file1, lines only in file2, and lines in # both files. The columns are separated by tab characters. # If file1 or file2 is a dash (-), the standard input is read. # Options: # The -1, -2, and -3 options suppress printing of the corresponding # columns. Options can be combined with a single dash. For example, # comm -12 file1 file2 # prints only lines common to the two files. function print1(line) { if (!flag1) printf(fmt1,line) } function print2(line) { if (!flag2) printf(fmt2,line) } function print3(line) { if (!flag3) printf(fmt3,line) } BEGIN { argc = 1; flag1 = flag2 = flag3 = 0; fmt1 = "%s\n"; fmt2 = "\t%s\n"; fmt3 = "\t\t%s\n"; if (ARGC == 1) { print("comm: No filenames specified"); exit(2); } # Parse options: this can run argc > ARGC, but its ok. while (ARGV[argc] ~ /^-./) { if (ARGV[argc] !~ /^-[123]+$/) { print("comm: Invalid arguments. Syntax: comm [ -123 ] file1 file2"); exit(2); } if (ARGV[argc] ~ /1/) flag1 = 1; if (ARGV[argc] ~ /2/) flag2 = 1; if (ARGV[argc] ~ /3/) flag3 = 1; argc++; } if (flag1) { fmt2 = "%s\n" } if (flag1||flag2) { fmt3 = "\t%s\n" } if (flag1&&flag2) { fmt3 = "%s\n" } # Open filenames if (argc+2 != ARGC) { print("comm: Two filenames required. Syntax: comm [ -123 ] file1 file2"); exit(2) } file1 = ARGV[argc] file2 = ARGV[argc+1] if ((stat1=(getline line1 < file1)) < 0) { print("comm: Can not open file:",ARGV[argc]); exit(2); } if ((stat2=(getline line2 < file2)) < 0) { print("comm: Can not open file:",ARGV[argc+1]); exit(2); } # Print lines until one file is exhausted while (1) { if (stat1==0 && (stat1=(getline line1 < file1)) <= 0) { break; } if (stat2==0 && (stat2=(getline line2 < file2)) <= 0) { break; } if (line1 < line2) { print1(line1); stat1 = 0; } else if (line1 > line2) { print2(line2); stat2 = 0; } else { print3(line2); stat1 = stat2 = 0; } } # Print remaining lines of the two files. if (stat1) print1(line1); while (getline line1 < file1 >0) print1(line1) if (stat2) print2(line2); while (getline line2 < file2 >0) print2(line2) }