헤더는 동일하지만 파일 이름이 약간 다른 여러 파일을 병합하는 방법은 무엇입니까?

헤더는 동일하지만 파일 이름이 약간 다른 여러 파일을 병합하는 방법은 무엇입니까?

아래와 같이 대용량 데이터 세트의 파일을 병합하는 데 문제가 있습니다. 나는 당신이 나를 도와주고 그러한 작업을 수행할 수 있는 스크립트에 대해 알려주기를 바랍니다.

좋은 이름: fluxes_year_lat_long 저는 100개 이상의 위치(lat_long)에 대해 30년간의 일일 Flux 파일을 가지고 있으며 각 포인트 파일의 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에 "전체" 파일을 만든 다음 위도 20_10에 "전체" 파일을 만듭니다.

이 경우:

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

저는 _lat_long > Fluxes_lat_long`을 사용하겠습니다 sort -u fluxes_*. 이는 가장 간단한 솔루션입니다.

편집: 스크립트에 사용됨

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

관련 정보