|
| 1 | +const fs = require("fs"); |
| 2 | + |
| 3 | +// Read files |
| 4 | +const [file1, file2] = process.argv.slice(2); |
| 5 | +const lines1 = fs.readFileSync(file1).toString().split('\n'); |
| 6 | +const lines2 = fs.readFileSync(file2).toString().split('\n'); |
| 7 | + |
| 8 | +// Tokenize lines in file1 for later comparison |
| 9 | +const tokenize = line => { |
| 10 | + if (line === '') { |
| 11 | + return []; |
| 12 | + } |
| 13 | + return line.split(/\s+/).filter(x => x !== '#').slice(0, 1); |
| 14 | +}; |
| 15 | +const lines1Tokens = lines1.flatMap(tokenize); |
| 16 | + |
| 17 | +// Step through the files |
| 18 | +let pos1 = 0, pos2 = 0; |
| 19 | +while (pos1 < lines1.length || pos2 < lines2.length) { |
| 20 | + |
| 21 | + const l1 = pos1 < lines1.length && lines1[pos1] || ''; |
| 22 | + const l2 = pos2 < lines2.length && lines2[pos2] || ''; |
| 23 | + |
| 24 | + // If the lines match, print l1 and skip l2 |
| 25 | + if (l1 !== '' && l1 === l2) { |
| 26 | + process.stdout.write(`${l1}\n`); |
| 27 | + pos1++; |
| 28 | + pos2++; |
| 29 | + continue; |
| 30 | + } |
| 31 | + |
| 32 | + if (pos2 < lines2.length) { |
| 33 | + // If l2 is empty, skip l2 |
| 34 | + if (l2 === '') { |
| 35 | + pos2++; |
| 36 | + continue; |
| 37 | + } |
| 38 | + |
| 39 | + const [l2token] = tokenize(l2); |
| 40 | + |
| 41 | + // If l2 token matches l1 token, print l1 |
| 42 | + if (pos1 < lines1.length && lines1Tokens[pos1] === l2token) { |
| 43 | + process.stdout.write(`${l1}\n`); |
| 44 | + pos1++; |
| 45 | + pos2++; |
| 46 | + continue; |
| 47 | + } |
| 48 | + |
| 49 | + // If l2 doesn't match any lines in file1, print l2 |
| 50 | + if (l2token && !lines1Tokens.includes(l2token)) { |
| 51 | + process.stdout.write(`${l2}\n`); |
| 52 | + } |
| 53 | + pos2++ |
| 54 | + continue; |
| 55 | + } |
| 56 | + |
| 57 | + // If we're not at the end of file1, print l1 |
| 58 | + if (pos1 < lines1.length) { |
| 59 | + if (pos1 === lines1.length - 1 && l1 === '') { |
| 60 | + // Don't print tailing newline |
| 61 | + } else { |
| 62 | + process.stdout.write(`${l1}\n`); |
| 63 | + } |
| 64 | + pos1++; |
| 65 | + } |
| 66 | +} |
0 commit comments