我有一个包含500列的文件,我需要将每列拆分成一个新文件,同时在所有文件中打印$ 1。下面是一个示例文件,我设法使用下面的bash / awk解决方案:
ID F1 F2 F4 F4
aa 1 2 3 4
bb 1 2 3 4
cc 1 2 3 4
dd 1 2 3 4
num=('1' '2' '3' '4')
for i in ${num[@]}; do awk -F "\t" -v col="$i" '{print $1,$col}' OFS="\t"
Input.txt > ${i}.txt; done
将所需的输出提供为:
1.txt
ID ID
aa aa
bb bb
cc cc
dd dd
2.txt
ID F1
aa 1
bb 1
cc 1
dd 1
....
但是,我无法跟踪哪个文件对应哪个列,因为输出文件名是字段编号而不是字段名。是否可以将字段的标题写为输出文件名的前缀?
ID.txt
ID ID
aa aa
bb bb
cc cc
dd dd
F1.txt
ID F1
aa 1
bb 1
cc 1
dd 1
答案 0 :(得分:2)
您可以在一个awk
脚本中完成所有操作。处理第一行时,将所有列标题放在一个数组中。然后,当您处理行时,您将在循环中从该数组写入文件名。
awk -F'\t' 'NR == 1 { split($0, filenames) }
{for (col = 1; col <= NF; col++) {
file= filenames[col] ".txt";
print $1, $col >> file;
close(file) } }' Input.txt
答案 1 :(得分:1)
如果我正确理解您的要求,您似乎非常接近。尝试
num=('1' '2' '3' '4')
for i in ${num[@]}; do
echo "i=$i"
awk -F "\t" -v col="$i" -v OFS="\t" '
NR==1{fName=$(col+1)".out";next}
{print $1,$(col+1) > fName}' data.txt
done
1>cat F1.out
aa 1
bb 1
cc 1
dd 1
. . . .
1>cat F4.out
aa 4
bb 4
cc 4
dd 4
修改强>
如果您需要保留示例输出中显示的标题,请删除;next
。
修改2
如果您有多个具有相同名称的列,则可以使用>> fName
将数据附加到同一文件。用这种技术警告一句话。当您使用> fName
时,此&#34;重新启动&#34;每次重新运行脚本时的文件。但是在使用>>
时,每次运行脚本时都会附加到每个文件。这可能会导致下游流程出现问题;-) ...因此,您需要添加清理以前运行脚本的代码。
在这里,我们依赖于awk
也可以使用> fName
将输出写入文件的事实(其中fName
已被定义为col的值( Num)+1(跳过第一列值)。
而且,如果你每天要做几千次这样的话,那么值得进一步优化上面的评论,让awk
一次读取文件并创建内部循环的所有输出。但是如果你只需要做几次,那么你就可以使用unix / linux的工具将任务分解为可管理的部分&#39;非常合适。
IHTH