【问题标题】:Add every 3rd column of different files into one file将不同文件的每 3 列添加到一个文件中
【发布时间】:2022-01-17 15:09:09
【问题描述】:

我是awk新手,希望有人能帮忙

我有 55 个文本文件(在 TAB 中并且有类似的以 .txt 结尾的命名),所有文件正好包含 55 行和 4 列。没有缺少行或列。唯一的区别是文件中的值。它们看起来类似于下面的(现在只包含 4 行和 3 个文件)

Row1    355 389 623
Row2    58  906 1373
Row3    338 3   30
Row4    2   976 0
Row1    543 31  6642
Row2    0   0   453
Row3    45  5   42
Row4    425 12  8
Row1    452 6   352
Row2    765 21  54
Row3    0   45  999
Row4    451 765 3

我想将第一列添加一次(名称),然后将所有文件中的第三列添加到一个中。 编辑:如果可能的话,文件名输出应该是这样的:

        1.txt 2.txt 3.txt
Row1    389 31  6
Row2    905 0   21
Row3    3   5   45
Row4    976 12  765

我试过这个代码

paste * | awk 'FNR==NR{a[FNR]=$1; next} {print a[FNR],$3}' *.txt > output.txt | column -t

但是,它只添加前 2 个文件的值。其他文件中的值不存在。我能做些什么?谢谢!

【问题讨论】:

  • 您的输入文件中使用了什么分隔符?它是 TAB 吗?
  • 是的,这些文件是 TAB 文件!
  • edit 您的问题提供minimal reproducible example 简洁、可测试的样本输入(例如,3 个文件,每行 4 行,每列 4 列)以及给定输入的预期输出,以便清楚地展示您的要求并为我们提供一些可以复制/粘贴以进行测试的内容。
  • 谢谢 Ed,我改了。这些文件具有相似的命名,但都列在一个文件夹中。因此,我猜像 *.txt 这样的东西应该没问题?所有文件的行号和列号完全相同,只是其中的值不同

标签: bash awk paste


【解决方案1】:

你可以试试这个 awk:

awk -F '\t' '
FNR==NR {table[FNR] = $1}
{table[FNR] = table[FNR] "\t" $3}

END {
    for (i=1; i<=FNR; i++) {
        print table[i]
    }
}' *

FNR 的最后一个(第 55 个)值用于打印数组,因此如果文件的行数不同,您需要解决这个问题。

如果你想使用paste,可能是这样的:

paste * |
awk '
{
    printf "%s", $1
    for (i=3; i<55*4; i+=4) {
        printf "\t%s", $i
    }
    printf "\n"
}'

55*4 是文件数乘以列数。硬编码。如有必要,有多种计算方法。

【讨论】:

  • print ""printf "\n" 更好,因为它只使用ORS 具有的任何值,而不是硬编码您希望将ORS 设置为("\n") 的字符串。另外,不要使用55*4,而是使用NF
【解决方案2】:

假设:

  • 输入/输出字段分隔符为&lt;TAB&gt;
  • 所有输入文件都包含相同的行数
  • 所有行至少有 3 列
  • 无需对输入文件进行排序(即,Row1 始终位于第 1 行,Row2 始终位于第 2 行等)
  • *.txt 将扩展为所需顺序的文件列表(例如,1.txt12.txt3.txt 等);否则 OP 可能需要先对文件名进行预排序,然后再将它们提供给建议的解决方案

一个awk想法:

awk '
BEGIN   { FS=OFS="\t" }                           # input/output field delimiter is <TAB>

FNR==1  { lines[0]=lines[0] OFS FILENAME }        # append filename to "header" record

FNR==NR { lines[FNR]=$1 }                         # save the "RowN" string

        { lines[FNR]=lines[FNR] OFS $3 }          # append field #3 to the line

END     { for (i=0;i<=FNR;i++)                    # loop through the line numbers ...
              print lines[i]                      # printing each line to stdout
        }
' *.txt

假设 3 个示例输入文件被命名为 {1..3}.txt,此 awk 脚本生成:

        1.txt   2.txt   3.txt
Row1    389     31      6
Row2    906     0       21
Row3    3       5       45
Row4    976     12      765

【讨论】:

  • 谢谢马克!效果很好!!!
  • 另外,感谢每一行的解释。很有帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-03
  • 2013-06-10
  • 1970-01-01
  • 2016-11-09
  • 2013-11-19
  • 1970-01-01
相关资源
最近更新 更多