【问题标题】:Merge text files by column: two column common and append third column form all files按列合并文本文件:两列通用并从所有文件追加第三列
【发布时间】:2018-03-16 18:01:59
【问题描述】:

试图将整个文件夹格式相同的文件合并为一个合并文件。

head File1.txt
11  116701285   204
11  116701286   209
11  116701287   209
11  116701288   208
11  116701289   209
11  116701290   208
11  116701291   208
11  116701292   210
11  116701293   209
11  116701294   213

head File2.txt
11  116701285   188
11  116701286   192
11  116701287   191
11  116701288   191
11  116701289   191
11  116701291   191
11  116701292   194
11  116701293   194
11  116701294   199

…………

head FileN.txt
11  116701285   190
11  116701286   192
11  116701287   191
11  116701288   189
11  116701289   191
11  116701290   192
11  116701291   193
11  116701292   197
11  116701293   196
11  116701294   199

所需的输出(前两列之后的列数将对应于文件数。前两列在所有文件中都相同。文件中没有标题)

11  116701285   188 204 190
11  116701286   192 209 192
11  116701287   191 209 191
11  116701288   191 208 189
11  116701289   191 209 191
11  116701290   191 0   192
11  116701291   191 208 193
11  116701292   194 210 197
11  116701293   194 209 196
11  116701294   199 213 199

如果元素条目不存在填写0。使用连接但只能做两个文件。

【问题讨论】:

  • 所以在循环中使用 join 将下一个文件附加到上一次迭代的结果中......
  • 你试过什么?我们这里的大多数人都很乐意帮助你提高你的手艺,但作为短期无偿编程人员不太乐意。在MCVE 中向我们展示您迄今为止的工作、您期望的结果和您得到的结果,我们将帮助您解决问题。从您添加的标签中,我希望看到 bash 和 awk 中的代码,以及您的代码当前产生的有问题的输出(或错误)。

标签: bash shell awk


【解决方案1】:

你可以使用这个awk:

awk '{
   k=$1 OFS $2
}
FNR == NR {
   v[++n] = k
}
{
   a[ARGIND,k] = $3
}
END {
   for(j=1; j<=n; j++) {
      printf "%s", v[j]
      for (i=1; i<ARGC; i++)
         printf "%s", OFS ((i,v[j]) in a ? a[i,v[j]] : 0)
      print ""
   }
}' File*.txt | column -t

11  116701285  204  188  190
11  116701286  209  192  192
11  116701287  209  191  191
11  116701288  208  191  189
11  116701289  209  191  191
11  116701290  208  0    192
11  116701291  208  191  193
11  116701292  210  194  197
11  116701293  209  194  196
11  116701294  213  199  199

如果您想要一个衬里,请使用:

awk '{k=$1 OFS $2} FNR==NR{v[++n]=k} {a[ARGIND,k] = $3} END{for(j=1; j<=n; j++) {printf "%s", v[j]; for (i=1; i<ARGC; i++) printf "%s", OFS ((i,v[j]) in a ? a[i,v[j]] : 0); print ""}}' File*.txt

column -t 用于表格输出。

【讨论】:

  • 完美...谢谢!
【解决方案2】:

您能否尝试关注awk,如果这对您有帮助,请告诉我。

awk 'FNR==NR{a[$1,$2]=$3;next} {a[$1,$2]=a[$1,$2]?a[$1,$2] OFS $3:$3} END{for(i in a){print i,a[i]}}' File*.txt

【讨论】:

  • 似乎正在工作...输出中没有第一列
  • $3 更改为$3+0。还将a[$1,$2]?三元替换为简单赋值a[$1,$2] OFS $3+0
  • @shams:您在预期的输出中显示了11 116701290 191 0 192,这不正确吗?
  • 问题是前两列粘贴在一起11116701290而不是11 116701290
  • @karakfa,仍然得到相同的答案。 $1 和 $2 的合并以及缺失值的空白空间而不是 0
【解决方案3】:

这对你有用:

#!/bin/bash
## Assuming all your file are named as *FileN.txt* and so on
endresult="$( awk '{print $1 "\t" $2}'  File1.txt )"
for file in F*.txt
do 

    endresult=$( paste <( echo "$endresult" ) <( awk '{ if(length($3) != 0) { print $3 }else{print 0}}'  $file ) ) 

done

#Replacing empty values for zeroes
endresult=$( echo "$endresult" | awk -v max_rows=$( echo "$endresult" | awk '{print NF}' | sort -r | head -1 ) 'BEGIN{ OFS="\t" }{ for(i=1;i < (max_rows + 1);i++) {  if(length($i) == 0 ){  $i = 0 } } ; print $0}' ) 

编辑:我从第一个文件中抓取前两列,因为你说这两列在所有文件中都是相等的。

问候!

【讨论】:

    猜你喜欢
    • 2018-02-06
    • 1970-01-01
    • 2014-10-28
    • 1970-01-01
    • 2012-05-27
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 2021-01-08
    相关资源
    最近更新 更多