правильный синтаксис для grep: ищите строку, скопируйте две строки выше и транспонируйте

В новинку (2 дня) для Linux и grep и застревают здесь. Сценарий. У меня есть данные, длящиеся больше чем 10 лет, которые я делал вручную, пока я не столкнулся с grep. Папки имеют форму /yyyy/mm/dd т.е. day1, day2 до конца месяца. Я должен искать определенную строку iteration 8. Если найдено, то я должен скопировать предыдущие 3 строки со строки где iteration 8 расположен. Затем я должен транспонировать в выходной файл. Это - то, как попытка должна достигнуть моей дилеммы. С тех пор не может транспонировать, пытаюсь разделить выводы, затем объединяются позже. Ведите меня на этом случае.

 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

Демонстрационный входной файл:

            Mean    -78.6
            rms      1615
            o-c      1612.97456

iteration 8

Демонстрационный выходной файл:

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

=======================   
3
задан 11 December 2016 в 19:06

1 ответ

Это создаст отчет за единственный месяц:

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

Сохраните его к, скажем, ~/script.pl, и назовите его передающий путь к отчетам месяца:

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

Вывод будет распечатан к терминал; можно использовать перенаправление для перенаправления его в файл:

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

Должно быть довольно легко написать сценарий множественных вызовов в сценарии Bash для создания ежегодно / 10-летние отчеты.

% 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

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

В примере все файлы в 2015/12 содержите a iteration 8 строка, следовательно строка печатается для каждого из них.

1
ответ дан 1 December 2019 в 17:35

Другие вопросы по тегам:

Похожие вопросы: