如何将多个文件中的特定列合并到一个文件中
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
我在一个目录中有 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