Awk:从许多不同的文件中提取不同的列

时间:2012-10-05 12:01:03

标签: file awk

文件示例

I have a 3-10 amount of files with:

 - different number of columns
 - same number of rows
 - inconsistent spacing (sometimes one space, other tabs, sometimes many spaces) **within** the very files like the below


>      0    55.4      9.556E+09   33
>      1     1.3      5.345E+03    1
>        ........
>     33   134.4      5.345E+04  932
>
       ........

我需要从file1获取列(比如说)1,从file2获取第3列,从file3获取第7列,从file4获取第1列,并将它们并排放入单个文件中。

试用1:无效

paste <(cut -d[see below] -f1 file1) <(cut -d[see below] -f3 file2) [...]
     

分隔符为''或为空。

试用2:使用2个文件但不使用多个文件

awk '{
     a1=$1;b1=$4;
     getline <"D2/file1.txt";
     print a1,$1,b1,$4
}' D1/file1.txt >D3/file1.txt

现在更一般的问题:

  

如何从许多不同的文件中提取不同的列?

3 个答案:

答案 0 :(得分:16)

paste / cut次尝试中,将cut替换为awk

$ paste <(awk '{print $1}' file1 ) <(awk '{print $3}' file2 ) <(awk '{print $7}' file3) <(awk '{print $1}' file4)

答案 1 :(得分:7)

假设您的每个文件都有相同的行数,这是使用GNU awk的一种方式。像:

一样运行
awk -f script.awk file1.txt file2.txt file3.txt file4.txt

script.awk的内容:

FILENAME == ARGV[1] { one[FNR]=$1 }
FILENAME == ARGV[2] { two[FNR]=$3 }
FILENAME == ARGV[3] { three[FNR]=$7 }
FILENAME == ARGV[4] { four[FNR]=$1 }

END {
    for (i=1; i<=length(one); i++) {
        print one[i], two[i], three[i], four[i]
    }
}

注意:

默认情况下,awk会分隔空格上的列。这包括制表符和空格,以及任何数量的这些。这使得awk适用于间距不一致的文件。如果您愿意,还可以扩展上面的代码以包含更多文件。

答案 2 :(得分:1)

cutpaste的组合应该有效:

$ cat f1
foo
bar
baz
$ cat f2
1 2 3
4 5 6
7 8 9
$ cat f3
a b c d
e f g h
i j k l
$ paste -d' ' <(cut -f1 f1) <(cut -d' ' -f2 f2) <(cut -d' ' -f3 f3)
foo 2 c
bar 5 g
baz 8 k

修改:这也适用于标签:

$ cat f4
a       b       c       d
e       f       g       h
i       j       k       l
$ paste -d' ' <(cut -f1 f1) <(cut -d' ' -f2 f2) <(cut -f3 f4)   
foo 2 c
bar 5 g
baz 8 k