如何合并一个文件中许多文件的特定列

时间:2015-12-30 06:11:15

标签: bash file csv awk paste

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

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

它附加了所有内容,我无法弄清楚如何应用awk '{print $2}'。任何人都可以建议如何处理这样的任务? 示例输入:

  

文件1

1 2 3 4
2 3 4 5
  

file2的

3 4 5 6
5 6 7 8
  

文件3

7 6 5 6
2 3 4 4

所需的输出文件:

2 4 6
3 6 3

4 个答案:

答案 0 :(得分:4)

gawk

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

答案 1 :(得分:1)

尝试不使用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解决方案更长,即使放在一条线上也是如此。

答案 2 :(得分:1)

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

#!/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

答案 3 :(得分:0)

如果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