如何通过awk从一个文件中并排列的多个文件中输出数据?
我有30个文件,叫做UE1.dat,UE2.dat。。。。每列中有4列。下面给出了UE1.dat和UE2.dat的柱结构示例 UE1.dat如何通过awk从一个文件中并排列的多个文件中输出数据?,awk,multiple-columns,Awk,Multiple Columns,我有30个文件,叫做UE1.dat,UE2.dat。。。。每列中有4列。下面给出了UE1.dat和UE2.dat的柱结构示例 UE1.dat 1 4 2 1 2 2 3 3 3 2 4 4 4 4 4 2 UE2.dat 2 6 8 7 4 4 9 6 7 1 1 2 9 3 3 3 因此,我尝试了以下代码: for((i=1;i UE_all.dat 要仅从每个文件中获取第一列并将其写入单个文件和并排的列,下面给出了所需的输出 1 2 2 4 3 7 4 9 但不幸的是,
1 4 2 1
2 2 3 3
3 2 4 4
4 4 4 2
UE2.dat
2 6 8 7
4 4 9 6
7 1 1 2
9 3 3 3
因此,我尝试了以下代码:
for((i=1;i UE_all.dat
要仅从每个文件中获取第一列并将其写入单个文件和并排的列,下面给出了所需的输出
1 2
2 4
3 7
4 9
但不幸的是,代码按行排序,您能给出提示吗
提前谢谢你!我可能会使用类似的方法-使用
perl
而不是awk
,因为我更喜欢处理数据结构。在这种情况下,我们使用二维数组,将每个文件的第一列插入数组的新列中,然后打印整个内容
#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;
my $num_files = 2;
my @rows;
my $count = 0;
my $max = 0;
for my $filenum ( 1..$num_files ) {
open ( my $input, "<", "UE${filenum}.dat" ) or die $!;
while ( <$input> ) {
my @fields = split;
push ( @{$rows[$filenum]}, $fields[0] );
$count++;
}
close ( $input );
if ( $count > $max ) { $max = $count };
}
print Dumper \@rows;
for ( 0..$count ) {
foreach my $filenum ( 1..$num_files ) {
print shift @{$rows[$filenum]} || ''," ";
}
print "\n";
}
!/usr/bin/env perl
严格使用;
使用警告;
使用数据::转储程序;
我的$num_文件=2;
我的@行;
我的$count=0;
我的$max=0;
对于我的$filenum(1..$num\u文件){
在awk中打开(我的$input,“”,您可以这样做:
1) 将此代码放入名为“从多个文件输出数据”的文件中。awk
:
BEGIN {
# All the input files are processed in one run.
# filenumber counts the number of input files.
filenumber = 1
}
{
# FNR is the input record number in the current input file.
# Concatenate the value of the first column in the corresponding
# line in the output.
output[FNR] = output[FNR] " " $1
# FNR == 1 means we are processing a new file.
if (FNR == 1) {
++filenumber
}
}
END {
# print the output
for (i=1; i<=FNR; i++)
printf("%s\n", output[i])
}
开始{
#所有输入文件都在一次运行中处理。
#filenumber统计输入文件的数量。
filenumber=1
}
{
#FNR是当前输入文件中的输入记录编号。
#将对应字段中第一列的值连接在一起
#输出中的行。
输出[FNR]=输出[FNR]“”$1
#FNR==1表示我们正在处理一个新文件。
如果(FNR==1){
++文件号
}
}
结束{
#打印输出
对于(i=1;i我的解是
gawk 'BEGINFILE{f++}{print FNR,f,$1}' UE* | sort -nk 1,2 | cut -d" " -f3 | xargs -L $(ls UE*.dat | wc -l)
这就是我如何做到的…我使用gawk
对行和文件进行编号,然后按行号排序,然后按文件排序,只需使用sort
并删除文件和行号。因此
gawk 'BEGINFILE{f++}{print FNR,f,$1}' UE*
1 1 1 # line 1 file 1 is 1
2 1 2 # line 2 file 1 is 2
3 1 3 # line 3 file 1 is 3
4 1 4 # line 4 file 1 is 4
1 2 2 # line 1 file 2 is 2
2 2 4 # line 2 file 2 is 4
3 2 7 # line 3 file 2 is 7
4 2 9 # line 4 file 2 is 9
然后像这样使用排序
将文件1的第一行放在文件2的第一行之后,文件n的第一行,文件1的第二行,文件2的第二行,文件n的第二行。然后得到第三列:
gawk 'BEGINFILE{f++}{print FNR,f,$1}' UE* | sort -nk 1,2 | cut -d" " -f3
1
2
2
4
3
7
4
9
然后用xargs
gawk 'BEGINFILE{f++}{print FNR,f,$1}' UE* | sort -nk 1,2 | cut -d" " -f3 | xargs -L2
1 2
2 4
3 7
4 9
结尾处的-L2
必须与文件数匹配,即在您的情况下为-L30
。使用awk
关联数组将所有列连接到一个文件中:
# use a wildcard to get all the files (could also use a for-loop)
# add each new row to the array using line number as an index
# at the end of reading all files, go through each index (will be 1-4 in
# your example) and print index, and then the fully concatenated rows
awk '{a[FNR] = a[FNR]" "$0}END{ for (i in a) print i, a[i] | "sort -k1n"}' allfiles*
对于您的输出-您每次都在第一列之后吗?它应该如何查找其他文件-30列宽,全部来自每个文件的“第1列”?它是否必须是awk
?不,不必是awk,但我在这种情况下使用了它。我刚刚编辑了问题,因此您可以在那里检查所需的输出。谢谢!它给了我:不能在./script第24行使用未定义的值作为数组引用??我看不到第24行有任何不一致之处。啊,是的,对不起,perl从零开始数组。所以你可能需要;@columns[1..30]
(答案编辑)对不起,再次编辑-希望这一次更好一些。这次不行:),它只打印前三列,它们之间有奇怪的空格。但是以前的版本可以工作:)这是输出的第一行:$VAR1=[undf,[也可以,但不同列之间有一些奇怪的选项卡。谢谢!@TrifonGetsov这很奇怪,脚本在连接值时只插入一个空格。事实上,我没有那样执行它,我将代码放在一个文件中。我将编辑我的答案。