【问题标题】:Awk: extract different columns from many different filesawk:从许多不同的文件中提取不同的列
【发布时间】:2012-09-26 14:02:41
【问题描述】:

文件示例

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

现在更一般的问题:

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

【问题讨论】:

  • 如何使用cut 和paste 不起作用?
  • 我认为这是因为 cut 假设间距是恒定的。我将数据格式化为不同的间距,以便使每列左侧的数字对齐。如果一个数字有更多的数字,那么它左边的空格就会更少。

标签: file awk


【解决方案1】:

在您的 paste / cut 尝试中,将 cut 替换为 awk:

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

【讨论】:

  • 粘贴
  • 这正是我需要的,又快又简单。干杯!
  • 是否可以将其推广到任意数量的输入文件(例如来自 for 循环)?
【解决方案2】:

假设您的每个文件都有相同的行数,这是使用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 非常适合间距不一致的文件。如果您愿意,还可以扩展上述代码以包含更多文件。

【讨论】:

  • +1 对标题的真实回答。也可能是我的问题here 的最佳答案。
【解决方案3】:

cut 和 paste 的组合应该可以工作:

$ 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

【讨论】:

  • 该示例有效,但仅适用于一致的间距...我的问题含糊不清,抱歉。我的意思是文件本身的间距不一致。
猜你喜欢
  • 2021-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-23
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
相关资源
最近更新 更多