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

How to merge specific columns from many files in one file

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

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

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

file1

1 2 3 4
2 3 4 5

file2

3 4 5 6
5 6 7 8

file 3

7 6 5 6
2 3 4 4

所需的输出文件:

2 4 6
3 6 3

呆呆的

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

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

尝试没有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 解决方案长,即使放在单行上也是如此。

这是一个简单的脚本,它说明了如何使用能够转置的 command-line 实用程序(此处 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