web-dev-qa-db-fra.com

syntaxe correcte pour grep: rechercher une chaîne, copier deux lignes ci-dessus et transposer

Je suis nouveau (2 jours) sur Linux et grep et je suis coincé ici. Scénario. J'ai des données d'une durée de plus de 10 ans que je faisais manuellement jusqu'à ce que je tombe sur grep. Les dossiers sont de la forme /yyyy/mm/dd c'est-à-dire jour1, jour2 jusqu'à la fin du mois. Je dois rechercher une chaîne spécifique iteration 8. Si trouvé, alors je dois copier les 3 lignes précédentes de la ligne où se trouve iteration 8. Ensuite, je dois transposer le dans un fichier de sortie. Voici comment je tente de résoudre mon dilemme. Étant donné que je suis incapable de transposer, je tente de scinder les sorties, puis de les combiner plus tard. S'il vous plaît guidez-moi sur ce cas.

 for file in /filepath/snc* #adding full path
     do
      echo $file
       grep -r " Mean" $file | awk '{print $1 " " $2}'> mean.txt # to enable single columns for ease of manipulation later
       grep -r " RMS" $file | awk '{print $1 " " $2}' > rms.txt
       grep -r " o-c" $file | awk '{print $3 " "$4}' > 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 $3 " " $4 " " $5 " " $6 " " $7 " " $8}' >> 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

Exemple de fichier d'entrée:

            Mean    -78.6
            rms      1615
            o-c      1612.97456

iteration 8

Exemple de fichier de sortie:

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

=======================   
3
user3192045

Cela créera un rapport pour un seul mois:

#!/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;

Enregistrez-le dans, par exemple, ~/script.pl, et appelez-le en transmettant le chemin d'accès aux rapports d'un mois:

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

La sortie sera imprimée sur le terminal; vous pouvez utiliser une redirection pour le rediriger vers un fichier:

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

Il devrait être assez facile de scripter plusieurs appels dans un script Bash pour créer des rapports annuels/10 ans.

% 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

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

Dans l'exemple, tous les fichiers de 2015/12 contiennent une ligne iteration 8, une ligne est donc imprimée pour chacun d'entre eux.

1
kos