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
=======================
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.