我的bash脚本正在调用awk脚本,该脚本很好地合并了两个文件
mapfieldfile1=1
mapfieldfile2=2
awk -v FS="t" 'BEGIN {OFS="t"}
FNR==NR{hash1['"$${mapfieldfile2}"']=$1 FS $3 FS $4 FS $5 FS $6;next}
('"$${mapfieldfile1}"' in hash1){ print $0, hash1['"$${mapfieldfile1}"']}' file2 file1
然而,我想要一个更通用的版本,我不需要硬编码我想要打印的列,我只想打印除id列之外的所有内容。将$1 FS $3 FS $4 FS $5 FS $6替换为$0"几乎"完成了工作,只是重复了id列。我一直在尝试动态创建一个类似于$1 FS $3 FS $4 FS $5 FS $6的字符串,但我在合并文件中字面上得到$1 $3 $4 $5 $6字符串,而不是扩展它们的值。此外,较小的副作用:我在中间添加了一个选项卡,并丢失了一些头,下面是代码和示例文件。我想找到我合并的解决方案,也了解我做错了什么,为什么我的变量没有扩大。
谢谢你的帮助!
mapfieldfile1=1
mapfieldfile2=2
awk -v FS="t" 'BEGIN {OFS="t";strfields=""}
FNR==NR{for(i=1;i<=NF;i++) if(i!='"${mapfieldfile2}"') {strfields=strfields" "FS" $"i};
hash1['"$${mapfieldfile2}"']=strfields;strfields="";next}
('"$${mapfieldfile1}"' in hash1){print $0, hash1['"$${mapfieldfile1}"']}' file2 file1
$cat file1
sampleid s1 s2 s3 s4
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
$cat file2
a0 sampleid a1 a2 a3 a4
a0 1 a a a a4
a0 2 b b b a4
a0 3 c c c a4
a0 5 e e e a4
$cat first_code_result.txt (good one!)
sampleid s1 s2 s3 s4 a0 a1 a2 a3 a4
1 1 1 1 1 a0 a a a a4
2 2 2 2 2 a0 b b b a4
3 3 3 3 3 a0 c c c a4
$cat second_code_result.txt
sampleid s1 s2 s3 s4 $1 $3 $4 $5 $6
1 1 1 1 1 $1 $3 $4 $5 $6
2 2 2 2 2 $1 $3 $4 $5 $6
3 3 3 3 3 $1 $3 $4 $5 $6
试试这个(未测试):
awk -v mf1="$mapfieldfile1" -v mf2="$mapfieldfile2" '
BEGIN {FS=OFS="t"}
FNR==NR{sub(/t[^t]+/,""); hash1[$mf2]=$0; next}
($mf1 in hash1){ print $0, hash1[$mf1]}
' file2 file1
不要让shell变量在awk脚本中展开,使用regexp从记录中删除字段,并弄清楚为什么你没有向我们展示的脚本正在打印$3
等,但你必须将它们包含在字符串中。你必须发布这个脚本来帮助调试它。
检查mf1 vs mf2应该出现的地方,我读你的脚本时感到困惑。
EDIT -我必须像上面那样调整它,我在使用它之前删除了$2:
$ awk -v mf1="1" -v mf2="2" '
BEGIN {FS=OFS="t"}
FNR==NR{key=$mf2; sub(/t[^t]+/,""); hash1[key]=$0; next}
($mf1 in hash1){ print $0, hash1[$mf1]}
' file2 file1
sampleid s1 s2 s3 s4 a0 a1 a2 a3 a4
1 1 1 1 1 a0 a a a a4
2 2 2 2 2 a0 b b b a4
3 3 3 3 3 a0 c c c a4
注意,上面的sub()依赖于键字段为$2,FS为选项卡。如果你需要一个更通用的解决方案,请告诉我们。
这里有一个版本,可以做你想要的任何关键字段值,并将在任何awk中工作,它只需要FS是一个选项卡或其他固定字符串(即不是regexp):
$ cat tst.awk
BEGIN { FS=OFS="t" }
NR==FNR {
key = $mf2
val = ""
nf = 0
for (i=1; i<=NF; i++) {
if (i != mf2) {
val = (nf++ ? val FS : "") $i
}
}
hash1[key] = val
next
}
$mf1 in hash1 { print $0, hash1[$mf1] }
$ awk -v mf1="1" -v mf2="2" -f tst.awk file2 file1
sampleid s1 s2 s3 s4 a0 a1 a2 a3 a4
1 1 1 1 1 a0 a a a a4
2 2 2 2 2 a0 b b b a4
3 3 3 3 3 a0 c c c a4
如果您的文件已经排序,则join
的默认输出是您想要的
$ join -t$'t' -11 -22 file1 file2
sampleid s1 s2 s3 s4 a0 a1 a2 a3 a4
1 1 1 1 1 a0 a a a a4
2 2 2 2 2 a0 b b b a4
3 3 3 3 3 a0 c c c a4
或,用column
修饰后
$ join -t$'t' -11 -22 file1 file2 | column -t
sampleid s1 s2 s3 s4 a0 a1 a2 a3 a4
1 1 1 1 1 a0 a a a a4
2 2 2 2 2 a0 b b b a4
3 3 3 3 3 a0 c c c a4