Perl, как извлечь номер # define'd из файла заголовка C - PullRequest
0 голосов
/ 25 августа 2018

Я ищу фрагмент Perl для вывода на терминал номера 100, содержащегося в заголовке C.

#ifndef VERSIONS_H
#define VERSIONS_H

#define __SOFTWARE_REVISION__ 100

#endif

Я могу извлечь строку #define, нономер.

#!perl -w
use warnings;
use strict;
my $line;
my $file = shift @ARGV;
open my $fh, "<", $file or die $!;
while (<$fh>) {
        print if /__SOFTWARE_REVISION__/;
}
close ($fh);

Ответы [ 2 ]

0 голосов
/ 25 августа 2018

Регулярное выражение соответствует любой строке, содержащей эту буквальную фразу, а не только там, где она определена. Вам нужно указать строку гораздо точнее, и захватить нужное число.

Код также продолжает без необходимости циклически проходить по файлу.

С некоторыми дополнительными настройками

use warnings;
use strict;
use feature qw(say);

my $file = shift @ARGV;
die "Usage: $0 filename\n" if not $file or not -f $file;

open my $fh, '<', $file or die "Can't open $file: $!";

while (<$fh>) {
    if (/^\s*#\s*define\s+__SOFTWARE_REVISION__\s+([0-9]+)/) {
        say "Software revision: $1";
        last;
    }
}
close $fh;

Если версия программного обеспечения может отличаться от целого числа, заменить [0-9]+ на \S+.

Я бы предложил поработать над учебником perlretut со ссылкой perlre под рукой.


Я предполагаю, что эта необходимость возникает в программе Perl (а не в том, что Perl является выбранным инструментом для этого).

Тем не менее, обратите внимание, что существуют другие, более системные, способы получения этой информации с помощью компилятора (см. Комментарий к gcc по rici , например).

Хотя лучше использовать Perl в сценарии Perl, чем выходить в систему, этот случай может быть одним из исключений: может быть лучше использовать внешнюю команду, а не анализировать исходные файлы задача, которая, как известно, коварна.

0 голосов
/ 25 августа 2018

Вот подход, использующий регулярное выражение для захвата номера версии, если он присутствует в строке.Обратите внимание, что круглые скобки в регулярном выражении разграничивают группу захвата, а переменная $1 используется для доступа к захвату.

#!perl -w
use warnings;
use strict;

my $file = shift @ARGV;
open my $fh, "<", $file or die $!;

while (<$fh>) {
    print "$1\n" if /^#define +__SOFTWARE_REVISION__ +(\d+)$/;
}

close $fh;

Вывод:

100

Регулярное выражение более избирательно, чем ваше, что соответствует любому экземпляру __SOFTWARE_REVISION__ в строке.Это регулярное выражение соответствует #define в начале строки, за которым следуют один или несколько пробелов, затем __SOFTWARE_REVISION__, затем один или несколько пробелов, за которыми следует одна или несколько групп захвата цифр в конце строки.

...