如何通过awk从一个文件中并排列的多个文件中输出数据?

如何通过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 但不幸的是,

我有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
但不幸的是,代码按行排序,您能给出提示吗


提前谢谢你!

我可能会使用类似的方法-使用
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这很奇怪,脚本在连接值时只插入一个空格。事实上,我没有那样执行它,我将代码放在一个文件中。我将编辑我的答案。