f1.txt
A, 77, 1, 2.0, !P , F, - ,
B, 77 , 4, 5, P, P, - ,
C, 88, 6, 7, F, P, -,
f2.txt
A, 77, 1, 2, P, F, P,
B, 77, 4, 5, F, P, P,
C, 88, 6, 7, F, P, P,
D, 99, 8, 9, P, P, F,
期望的输出
A, 77, 1, 2, P, not P(*), F, F, P, -,
B, 77, 4, 5, F, P(*), P, P, P, -,
C, 88, 6, 7, F, F, P, P, F, -,
D, 99, 8, 9, P, -, P, -, P, -,
基本上,匹配两个文件中的4列,然后合并每个文件中的备用列:匹配4列,然后f2_column5
然后f1_column5
,如果不同则添加(*)
(如果不可用)然后"-"
)
f1.txt
的#列和f2.txt
的#列不一样f1.txt
和f2.txt
f3.txt:B,77,4,5,P,P, - , 和所需的输出(对于3个输入文件 - f1.txt,f2.txt,f3.txt)
期望的输出
A, 77, 1, 2, P, not P(*), -, -, F, F, P, -, -,
B, 77, 4, 5, F, P(*), P(*), P, P, P, P, -, -,
C, 88, 6, 7, F, F, -, P, P, -, F, -, -,
D, 99, 8, 9, P, -, -, P, -, -, P, -, -,
| | |
f2.5th f2.6th f2.7th
=============================================== ========================================
如果列数小于10,我可以使用以下
awk 'FNR==NR {a[NR]=$1;
b[NR]=$2;
c[NR]=$3;
d[NR]=$4;
e[NR]=$5;
f[NR]=$6;
g[NR]=$7;
next}
{print $1,$2,$3,$4,$5,
( e[FNR]!="" ? e[FNR] : "-" ),
$6,
( f[FNR]!="" ? f[FNR] : "-" ),
$7,
( g[FNR]!="" ? g[FNR] : "-" ) }' f1.txt f2.txt
但我假设f1.txt
和f2.txt
的4列,而不是我想要的;我想看看它是否匹配。我不知道如何使用大量列以及检查(*)。
答案 0 :(得分:1)
我认为你的问题存在过于宽泛的风险,但希望这可以作为一个起点。目前,输出不太正确,但调整代码以满足您的需求应该不会太难。
对于这个长度的脚本,我认为写一个awk脚本会更好。代码可以保存到文件中并使用awk -f script.awk f1 f2
:
BEGIN { FS = "[[:space:]]*,[[:space:]]*" }
NR == FNR {
k = $1 SUBSEP int($2) SUBSEP int($3) SUBSEP int($4)
seen[k]=NF
for (i=5; i<=NF; ++i) {
a[k,i] = $i
}
next
}
{
k = $1 SUBSEP int($2) SUBSEP int($3) SUBSEP int($4)
seen[k]=seen[k]>NF?seen[k]:NF
for (i=5; i<=NF; ++i) {
b[k,i] = $i
}
}
END {
for (i in seen) {
n = split(i, c, SUBSEP)
for (j=1; j<=n; ++j)
printf "%s, ", c[j]
for (k=5; k<seen[i]; ++k)
printf "%s, %s,%s", b[i,k], a[i,k], (k<seen[i]-1?OFS:ORS)
}
}
说明:
NR==FNR
(在第一个文件中)时:
k
设置为由特殊变量SUBSEP
分隔的前四个字段组成的字符串。使用int()
将数字转换为整数值seen
会跟踪到目前为止的密钥。数组中的值设置为字段数,稍后在循环中使用a
next
记录,忽略其余任何说明k
seen
中的值(我不确定文件中的每一行是否具有相同数量的密钥?)b
seen
SUBSEP
上的键split
返回数组c
a
和b
的备用值需要做的事情:
b[i,k]
和a[i,k]
是否不同,以便添加(*)
!
替换为not
这两件事只是在END
块中添加额外逻辑的情况。