sintaxe adequada para o grep: pesquise uma string, copie duas linhas acima e transponha

4

Sou novo (2 dias) para Linux e grep e estou preso aqui. Cenário. Eu tenho dados com duração de mais de 10 anos que venho fazendo manualmente até me deparar com o grep. As pastas são do formato /yyyy/mm/dd , ou seja, dia1, dia2 até o final do mês. Eu preciso procurar por uma string específica iteration 8 . Se encontrado, então eu preciso copiar as 3 linhas anteriores da linha onde iteration 8 está localizado. Então eu preciso transpor o em um arquivo de saída. É assim que estou tentando alcançar meu dilema. Desde sou incapaz de transpor estou tentando dividir as saídas, em seguida, combinar mais tarde. Por favor me guie neste caso.

 for file in /filepath/snc* #adding full path
     do
      echo $file
       grep -r " Mean" $file | awk '{print  " " }'> mean.txt # to enable single columns for ease of manipulation later
       grep -r " RMS" $file | awk '{print  " " }' > rms.txt
       grep -r " o-c" $file | awk '{print  " "}' > o-c.txt
       grep -rl "iteration 8" $file > iteration.txt # to verify that the files are the correct ones
      done

paste iteration.txt o-c.txt mean.txt rms.txt > daily-summary.txt #the output file must be in this specific order
grep "iteration 8" daily-summary.txt | awk '{print  " "  " "  " "  " "  " " }' >> monthly-summary-path.txt

#grep -3 "iteration 8" daily-summary.txt  >> monthly-summary-file.txt # two lines before

rm mean.txt rms.txt std.txt

Exemplo de arquivo de entrada:

            Mean    -78.6
            rms      1615
            o-c      1612.97456

iteration 8

Arquivo de saída de amostra:

year month day o-c         mean  rms
2015   12   12  1612.97456 -78.6 1615
2015   12   11  1525.36589 -78.0 1642

=======================   
    
por user3192045 22.12.2015 / 10:59

1 resposta

1

Isso criará um relatório para um único mês:

#!/usr/bin/perl

use strict;
use warnings;

@ARGV == 1 || die($!);

my $realpath = 'realpath $ARGV[0]';
chomp($realpath);

opendir(my $dir, $realpath) || die($!);

my @files;

while(readdir($dir)) {
    -f "$realpath/$_" && push(@files, "$realpath/$_");
}

print("year\tmonth\tday\to-c\tmean\trms\n");

my @realpath_s = split("/", $realpath);

foreach my $file (sort(@files)) {
    open(my $in, $file) || die($!);

    while(<$in>) {
        if(/^\s*Mean/) {
            my @row;
            for(my $i = 0; $i < 3; $i++) {
                my @F = split(/\s/);
                push(@row, $F[2]);
                $_ = <$in>;
            }
            $_ = <$in>;
            my @F = split(/\s/);
            if($F[1] == 8) {
                $file =~ s/.*day//;
                print("$realpath_s[@realpath_s-2]\t$realpath_s[@realpath_s-1]\t$file\t$row[2]\t$row[0]\t$row[1]\n");
                last;
            }
        }
    }
}

print("\n=======================\n");

exit 0;

Salve-o em, digamos, ~/script.pl e chame-o passando o caminho para os relatórios de um mês:

perl ~/script.pl /path/to/2015/12

A saída será impressa no terminal; você pode usar um redirecionamento para redirecioná-lo para um arquivo:

perl ~/script.pl /path/to/2015/12 > ~/report_2015_12.txt

Deve ser bastante fácil escrever várias chamadas em um script Bash para criar relatórios anuais / de 10 anos.

% tree
.
├── 2015
│   └── 12
│       ├── day1
│       ├── day2
│       └── day3
└── script.pl

2 directories, 4 files
% perl script.pl 2015/12
year    month   day o-c mean    rms
2015    12  1   1612.97456  -78.6   1615
2015    12  2   1612.97456  -79.6   1615
2015    12  3   1612.97456  -80.6   1615

=======================

No exemplo, todos os arquivos em 2015/12 contêm uma linha iteration 8 , portanto, uma linha é impressa para cada um deles.

    
por kos 22.12.2015 / 15:23