假设我有两个文件a.txt和b.txt。 a.txt和b.txt的内容如下:
A.TXT:
abc|def|ghi|jfkdh|dfgj|hbkjdsf|ndf|10|0|cjhk|00|098r|908re|
dfbk|sgvfd|ZD|zdf|2df|3w43f|ZZewd|11|19|fdgvdf|xz00|00|00
b.txt:
abc|def|ghi|jfkdh|dfgj|hbkjdsf|ndf|11|0|cjhk|00|098r|908re|
dfbk|sgvfd|ZD|zdf|2df|3w43f|ZZewd|22|18|fdgvdf|xz00|00|00
所以我们假设这些文件的各个字段用“|”分隔并且可以有任意数量的行。另外,假设两者都是已排序的文件,因此我们可以匹配两个文件之间的确切行。现在,我想找到8和8之间的区别。每个行的9个分别进行比较,如果它们的差异大于10,则打印行,否则从文件中删除行。
即,在给定的例子中,我将减去| 10-11 | (各自的字段编号8是来自a.txt和b.txt的1(绝对值))并且类似地对于字段编号。 9(0-0)为0,两者的差值都<10,所以我们从文件中删除这一行。
对于第二行,差异是(11-22)= 10所以我们打印这一行。(不需要检查19-18,好像任何字段值(8,9)是&gt; = 10我们打印这样的线条。
所以输出是
A.TXT:
dfbk|dfdag|sgvfd|ZD|zdf|2df|3w43f|ZZewd|11|19|fdgvdf|xz00|00|00
b.txt:
dfbk|dfdag|sgvfd|ZD|zdf|2df|3w43f|ZZewd|22|18|fdgvdf|xz00|00|00
答案 0 :(得分:3)
您可以编写执行此操作的bash shell脚本:
while true; do
read -r lineA <&3 || break
read -r lineB <&4 || break
vara_8=$(echo "$lineA" | cut -f8 -d "|")
varb_8=$(echo "$lineB" | cut -f8 -d "|")
vara_9=$(echo "$lineA" | cut -f9 -d "|")
varb_9=$(echo "$lineB" | cut -f9 -d "|")
if (( vara_8-varb_8 > 10 || vara_8-varb_8 < -10
|| vara_9-varb_9 > 10 || vara_9-varb_9 < -10 )); then
echo "$lineA" >> newA.txt
echo "$lineB" >> newB.txt
fi
done 3<a.txt 4<b.txt
答案 1 :(得分:3)
您可以使用awk执行此操作:
awk -F\| 'FNR==NR{x[FNR]=$0;eight[FNR]=$8;nine[FNR]=$9;next} {d1=eight[FNR]-$8;d2=nine[FNR]-$9;if(d1>10||d1<-10||d2>10||d2<-10){print x[FNR] >> "newa";print $0 >> "newb"}}' a.txt b.txt
<强>解释强>
-F
将字段分隔符设置为管道符号。 FNR==NR
之后的花括号中的内容仅适用于a.txt
的处理。它表示将整行保存在由行号(x[]
)索引的数组FNR
中,并保存数组eight[]
中的第八个字段,也用行号索引。同样,字段9保存在数组nine[]
中。
第二组花括号适用于处理文件b。它会计算差异d1
和d2
。如果超过10,则该行将打印到每个文件newa
和newb
。
答案 2 :(得分:0)
使用Mark Setchell提供的方法。在下面的扩展和略微修改版本中看到:
parse.awk
FNR==NR {
x[FNR] = $0
m[FNR] = $8
n[FNR] = $9
next
}
{
if(abs(m[FNR] - $8) || abs(n[FNR] - $9)) {
print x[FNR] >> "newa"
print $0 >> "newb"
}
}
像这样运行:
awk -f parse.awk a.txt b.txt
上面的方法将a.txt
读入内存。如果文件非常大,则变得不可行,并且需要进行流式解析。
可以一次完成,但这需要仔细处理来自a.txt
和b.txt
的多路复用线。一种不易出错的方法是识别相关的行号,然后将它们提取到新文件中。最后一种方法的一个例子如下所示。
首先,您需要确定匹配的行:
# Extract fields 8 and 9 from a.txt and b.txt
paste <(awk -F'|' '{print $8, $9}' OFS='\t' a.txt) \
<(awk -F'|' '{print $8, $9}' OFS='\t' b.txt) |
# Check if it the fields matche the criteria and print line number
awk '$1 - $3 > n || $3 - $1 > n || $2 - $4 > n || $4 - $2 > 10 { print NR }' n=10 > linesfile
现在我们已准备好从a.txt
和b.txt
中提取行,并且在数字排序后,我们可以使用extract.awk script proposed here(以下方便重复):
extract.awk
BEGIN {
getline n < linesfile
if(length(ERRNO)) {
print "Unable to open linesfile '" linesfile "': " ERRNO > "/dev/stderr"
exit
}
}
NR == n {
print
if(!(getline n < linesfile)) {
if(length(ERRNO))
print "Unable to open linesfile '" linesfile "': " ERRNO > "/dev/stderr"
exit
}
}
提取线条(可以并行运行):
awk -v linesfile=linesfile -f extract.awk a.txt > newa
awk -v linesfile=linesfile -f extract.awk b.txt > newb