76 lines
1.8 KiB
JavaScript
76 lines
1.8 KiB
JavaScript
async function readLines(ctx, path) {
|
|
const b4 = ctx.b4a
|
|
if (path === '-') return bareStdin(ctx).split('\n')
|
|
const b = await ctx.vfs.readFile(path)
|
|
if (!b) return null
|
|
return b4.toString(b).split('\n')
|
|
}
|
|
|
|
async function run(ctx, argv) {
|
|
let c1 = true
|
|
let c2 = true
|
|
let c3 = true
|
|
const paths = []
|
|
for (let i = 1; i < argv.length; i++) {
|
|
const a = argv[i]
|
|
if (a === '-h' || a === '--help') {
|
|
ctx.console.log(
|
|
'usage: comm [-123] FILE1 FILE2\nCompare sorted files; columns: only FILE1, only FILE2, both.'
|
|
)
|
|
return
|
|
}
|
|
if (a === '-1') c1 = false
|
|
else if (a === '-2') c2 = false
|
|
else if (a === '-3') c3 = false
|
|
else if (a.startsWith('-')) {
|
|
ctx.console.error('comm: unsupported option ' + a)
|
|
ctx.exitCode = 1
|
|
return
|
|
} else paths.push(a)
|
|
}
|
|
if (paths.length !== 2) {
|
|
ctx.console.error('usage: comm [-123] FILE1 FILE2')
|
|
ctx.exitCode = 1
|
|
return
|
|
}
|
|
const A = await readLines(ctx, paths[0])
|
|
const B = await readLines(ctx, paths[1])
|
|
if (!A || !B) {
|
|
ctx.console.error('comm: missing input file')
|
|
ctx.exitCode = 1
|
|
return
|
|
}
|
|
const trimNl = (arr) => {
|
|
if (arr.length && arr[arr.length - 1] === '') arr.pop()
|
|
return arr
|
|
}
|
|
const a = trimNl(A.slice())
|
|
const b = trimNl(B.slice())
|
|
let i = 0
|
|
let j = 0
|
|
while (i < a.length || j < b.length) {
|
|
if (i >= a.length) {
|
|
if (c2) ctx.console.log('\t' + b[j])
|
|
j++
|
|
continue
|
|
}
|
|
if (j >= b.length) {
|
|
if (c1) ctx.console.log(a[i])
|
|
i++
|
|
continue
|
|
}
|
|
const cmp = a[i].localeCompare(b[j])
|
|
if (cmp < 0) {
|
|
if (c1) ctx.console.log(a[i])
|
|
i++
|
|
} else if (cmp > 0) {
|
|
if (c2) ctx.console.log('\t' + b[j])
|
|
j++
|
|
} else {
|
|
if (c3) ctx.console.log('\t\t' + a[i])
|
|
i++
|
|
j++
|
|
}
|
|
}
|
|
}
|