如何合并具有相同标头但文件名略有不同的不同文件?

如何合并具有相同标头但文件名略有不同的不同文件?

我在合并大数据集的文件时遇到问题,如下所示。我希望你帮助我让我知道可以完成此类任务的脚本。

精细名称:fluxes_year_lat_long 我有 30 年的每日通量文件,用于超过 100 个位置(lat_long),我想合并每个点文件的第 1 年到第 30 年。

我的文件看起来像这样

文件名1:fluxes_2000_50_70

2000 1 1 5000 ....
2000 1 2 2000 ....
.
.
.
2000 12 31 5000
YYYY M D Fluxes

文件名2:fluxes_2001_50_70

2001 1 1 5000
YYYY M D Fluxes
.
.
.

一直到:

文件名30:fluxes_2030_50_70

2030 1 1 5000
YYYY M D Fluxes
.
.
.

每个文件的行数是相同的。

我希望输出合并每个点位置从 2000 年到 2030 年的每日通量,例如

输出文件:fluxes_lat_long

YYYY MM DD Fluxes value.

另外,我希望脚本读取并合并以名称fluxes_开头的文件。我很欣赏你的回复。

答案1

思考您询问给定的文件:

fluxes_2000_10_10   fluxes_2001_10_10    fluxes_2003_10_10

fluxes_2000_20_10   fluxes_2001_20_10    fluxes_2003_20_10

您为上述每个文件在纬度 10_10 处创建一个“total”文件,然后在纬度 20_10 处创建一个“total”文件。

在这种情况下:

bash$ for lat in $(ls -1 fluxes_* | sed 's/fluxes_[0-9]*_\([0-9]*_[0-9]*\)/\1/' |sort|uniq )
do 
    echo "processing $lat ..." 
    cat fluxes_[0-9]*_${lat} > fluxes_TOT_${lat} 
done 

ls -1 fluxes_* | sed 's/fluxes_[0-9]*_\([0-9]*_[0-9]*\)/\1/' | sort | uniqfor找到所有唯一的纬度 (x_y) 数字对,然后我们使用循环和cat该纬度(所有年份)的文件内容 逐步遍历它们,并将它们输出到fluxes_TOT_x_y.

答案2

我会使用sort -u fluxes_*_lat_long > Fluxes_lat_long`,这是迄今为止最简单的解决方案。

编辑:在脚本中使用

for file in $(ls -1 fluxes_20*_*_*) ; do
    export ll="$(echo $file |cut -d _ -f 3,4)"  # extract lat & long
    echo "sort -u fluxes_*_$ll"  "> fluxes_$ll" # create sort instruction
done | uniq | sh

答案3

如果我理解您的要求,您希望将一个点的所有通量数据合并fluxes_lat_long为以下格式

01 01 Fluxes total_fluxes_for_Jan_1_over_30_years
01 02 Fluxes total_fluxes_for_Jan_2_over_30_years
...

如果是这种情况,下面的 Perl 脚本应该会有所帮助:

#!/usr/bin/perl

use strict;
use warnings;

my @files = glob 'fluxes_*_*_*';
my %points;
$files[$_] =~ /_([0-9]+_[0-9]+)\Z/ and $points{$1}++ for (0..$#files);

for my $point (sort keys %points){
    my @point_files = grep { /_$point\Z/ } @files;
    my %days;
    for my $file (@point_files){
        open my $f,'<',$file or die "Failed to open file $file : $!\n";
        <$f>; #Discard the header
        while(<$f>){
            my ($year,$month,$day,$number) = split;
            $days{"$month $day"}+=$number;
         }
         close $f;
     }

     open my $of,'>',"fluxes_$point";
     for (sort by_date keys %days){
         print $of "$_ Fluxes $days{$_}\n";
     }
 }

 sub by_date{
    my ($month_a,$day_a) = split /\s*/,$a;
    my ($month_b,$day_b) = split /\s*/,$b;
    my $month_sort = $month_a <=> $month_b;
    my $day_sort = $day_a <=> $day_b;
    return $month_sort ? $month_sort : $day_sort
}

答案4

tail -qn +2将删除每个文件的标题并从第二行开始,fluxes_*将遍历以该字符串开头的所有文件,并将> fluxes_2000_2030所有数据通过管道传输到单个输出文件:

tail -qn +2 fluxes_* > fluxes_2000_2030

相关内容