#!/usr/bin/awk -f
# main body
NR == 1 {
copyRecordTo(veryold)
next
}
{
if (inSameGroup()) {
copyRecordTo(old)
} else {
makeRangeForField(NF - 1)
makeRangeForField(NF)
nicePrint()
copyRecordTo(veryold)
}
}
END {
makeRangeForField(NF - 1)
makeRangeForField(NF)
nicePrint()
}
# functions
function copyRecordTo(line) {
for (i = 1; i <= NF; ++i) line[i] = $i
}
function nicePrint() {
for (i = 1; i <= NF; ++i) {
i == NF - 1 ? fmt = "%s\t\t" : fmt = "%s\t"
printf(fmt, old[i])
}
printf("\n")
}
function makeRangeForField(f) {
if (old[f] != veryold[f])
old[f] = veryold[f]":"old[f]
}
function inSameGroup() {
b = 1
for (i = 1; i <= NF - 2; ++i)
b *= $i == veryold[i]
return b == 1
}
原答案
下列awk脚本几乎生成您正在寻找的内容。
本质上,该脚本执行以下操作:
商店在veryold仅第 7 个和/或第 8 个字段不同的每组行的第一行
商店在old最后读取的行
“布尔”b用于检查何时超过最后一行
当这种情况发生时,最后两个字段veryold与那些加入old with a :如果它们不同,则介于两者之间,并且old被打印
多一个选项卡\t用于最后两个字段之间以提高可读性
另外两点:
NR == 1是一种必须初始化的特殊情况veryold only
读取最后一行后END处理存储在中的最后一行的特殊情况old
#!/usr/bin/awk -f
NR == 1 {
for (i = 2; i <= NF; ++i) {
veryold[i] = $i
}
next
}
{
b = 1
for (i = 2; i <= NF - 2; ++i) {
b *= $i == veryold[i]
}
if (b == 1) {
for (i = 1; i <= NF; ++i) {
old[i] = $i
}
} else {
if (old[NF - 1] != veryold[NF - 1]) {
old[NF - 1] = veryold[NF - 1]":"old[NF - 1]
}
if (old[NF] != veryold[NF]) {
old[NF] = veryold[NF]":"old[NF]
}
for (i = 1; i <= NF; ++i) {
if (i == NF - 1) {
fmt = "%s\t\t"
} else {
fmt = "%s\t"
}
printf(fmt, old[i])
}
printf("\n")
for (i = 2; i <= NF; ++i) {
veryold[i] = $i
}
}
}
END {
if (old[NF - 1] != veryold[NF - 1]) {
old[NF - 1] = veryold[NF - 1]":"old[NF - 1]
}
if (old[NF] != veryold[NF]) {
old[NF] = veryold[NF]":"old[NF]
}
for (i = 1; i <= NF; ++i) {
if (i == NF - 1) {
fmt = "%s\t\t"
} else {
fmt = "%s\t"
}
printf(fmt, old[i])
}
}