【问题标题】:How to merge specific columns from many files in one file如何将多个文件中的特定列合并到一个文件中
【发布时间】:2016-04-04 02:20:00
【问题描述】:

我在一个目录中有 100 多个制表符分隔文件,我想将每个文件的第二列合并到一个文件中。 我试图像这样使用paste

paste -d" " *.tsv >> result.tsv

它附加了所有内容,我不知道如何将awk '{print $2}' 应用于它。谁能建议如何处理这样的任务? 示例输入:

文件1

1 2 3 4
2 3 4 5

文件2

3 4 5 6
5 6 7 8

文件 3

7 6 5 6
2 3 4 4

所需的输出文件:

2 4 6
3 6 3

【问题讨论】:

  • paste file1 file2 file3 | awk '{ print $2 " " $6 " " $10 }'
  • 我需要通用的通配符解决方案,所以我可以申请任意数量的文件
  • 所有文件都有4列吗?
  • 所有文件都有9列,我简化了例子
  • paste file1 file2 file3 | awk '{for(i=2i<=NF;i+=9) printf "%s ", $i; print ""}' ?

标签: bash file csv awk paste


【解决方案1】:

呆呆

awk '{a[FNR]=a[FNR]?a[FNR]" "$2:$2}END{for(i=1;i<=length(a);i++)print a[i]}' *

【讨论】:

  • 它说无效选项-v
  • 警告:这不会总是正常工作,例如如果其中一个文件的行数少于后续文件的行数,或者 $2 有时为空白。这种方法也无法扩展以处理比命令行更多的路径名规范。
【解决方案2】:

如果 python 对您有好处,那么您可以将此脚本用于任意数量的文件:

#! /usr/bin/env python

# invoke with column nr to extract as first parameter followed by
# filenames. The files should all have the same number of rows

import sys

col = int(sys.argv[1])
res = {}

for file_name in sys.argv[2:]:
    for line_nr, line in enumerate(open(file_name)):
        res.setdefault(line_nr, []).append(line.split('\t')[col-1])

for line_nr in sorted(res):
    print '\t'.join(res[line_nr])

注意:Unix-StackExchange 论坛上有人建议的脚本。

这里也有另一个解决方案Link

【讨论】:

  • python 不错,但该脚本将特定文件名作为第二个参数,并且不会将结果保存到一个文件中
【解决方案3】:

尝试没有awk的解决方案:

rm -f r.tsv
for i in *.tsv; do
    if [[ -f r.tsv ]]; then
        paste r.tsv <(cut -f 2 "$i") > tmp.txt
    else
        cut -f 2 "$i" > tmp.txt
    fi
    mv tmp.txt r.tsv
 done

它比awk 解决方案更长,即使放在一行中也是如此。

【讨论】:

    【解决方案4】:

    这是一个简单的脚本,它说明了如何使用能够转置的命令行实用程序(此处为 datamash)将每个可能大量文件中的特定列粘贴在一起。

    #!/bin/bash
    # requires datamash
    TMP=$(mktemp /tmp/reshape.XXX)
    
    for file
    do
      cut -f 2 < "$file" |  tr '\n' '\t' >> $TMP
      echo >> $TMP
    done
    
    # -W means: Use whitespace (one or more spaces and/or tabs) 
    # for field delimiters; the output will have tab-separated values
    datamash --no-strict -W transpose < $TMP
    
    /bin/rm $TMP
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多