Я использую grep, чтобы вернуть значение для первого найденного ИМЯ (которое может варьироваться от случая к случаю) и найти найденное значение ИМЯ. Кроме того, хотелось бы, чтобы выходной текст был только после последнего «/».
Пример файла, содержащего
NAME = abc123
abc123 = /path/to/x456
Ожидаемый результат:
x456
Код:
my $name = qx(grep -oP -m 1 "NAME = \\K(.*)" $file);
my $value = qx(grep -oP -m 1 "${name} = \\K(.*)" $file);
Использование qx
было бы сложным.
use File::Basename qw( basename );
use String::ShellQuote qw( shell_quote );
my $file_qfn = "...";
my $name;
{
my @cmd = ( "grep", "-oP", "-m", "1", '^NAME\s+=\s+\K(.*)', $file_qfn );
my $cmd = shell_quote( @cmd );
$name = qx($cmd);
die "Can't spawn shell: $!\n" if $? == -1;
die "Shell killed by signal ".( $? & 0x7F )."\n" ) if $? & 0x7F;
die "Shell exited with error ".( $? >> 8 )."\n" ) if $? >> 8;
chomp( $name );
}
my $value;
{
my $name_pat = quotemeta( $name );
my @cmd = ( "grep", "-oP", "-m", "1", "^$name_pat\\s+=\\s+\\K(.*)", $file_qfn );
my $cmd = shell_quote( @cmd );
$value = qx($cmd);
die "Can't spawn shell: $!\n" if $? == -1;
die "Shell killed by signal ".( $? & 0x7F )."\n" ) if $? & 0x7F;
die "Shell exited with error ".( $? >> 8 )."\n" ) if $? >> 8;
chomp( $value );
}
my $base = basename( $value );
Мы можем избежать оболочки и упростить вещи, используя capturex
.
use File::Basename qw( basename );
use IPC::System::Simple qw( capturex );
my $file_qfn = "...";
my $name;
{
my @cmd = ( "grep", "-oP", "-m", "1", '^NAME\s+=\s+\K(.*)', $file_qfn );
$name = capturex( @cmd );
chomp( $name );
}
my $value;
{
my $name_pat = quotemeta( $name );
my @cmd = ( "grep", "-oP", "-m", "1", "^$name_pat\\s+=\\s+\\K(.*)", $file_qfn );
$value = capturex( @cmd );
chomp( $value );
}
my $base = basename( $value );
Но я думаю, что идея создавать детей для этой задачи неприятна.
use File::Basename qw( basename );
use File::Slurper qw( read_text );
my $file_qfn = "...";
my $file = read_text( $file_qfn );
my ( $name ) = $file =~ /^NAME\s+=\s+\K(.*)/m
or die( "Can't find `NAME` field\n" );
my ( $value ) = $file =~ /^\Q$name\E\s+=\s+\K(.*)/m
or die( "Can't find `$name` field\n" );
my $base = basename( $value );
На самом деле я бы использовал что-то вроде следующего:
use File::Basename qw( basename );
my $file_qfn = "...";
open( my $fh, '<', $file_qfn )
or die( "Can't open file \"$file_qfn \": $!\n" );
my %data;
while ( <$fh> ) {
chomp;
my ( $k, $v ) = split( /\s+=\s+/, $_, 2 );
$data{ $k } = $v;
}
defined( my $name = $data{ NAME } )
or die( "Can't find `NAME` field\n" );
defined( my $value = $data{ $name } )
or die( "Can't find `$name` field\n" );
my $base = basename( $value );
Привет, второе предложение кажется мне проще, и оно работает хорошо.
Зачем использовать систему
grep
, если она находится внутри программы Perl? Откройте файл, прочитайте его и извлеките то, что вам нужно, с помощью Perl в программе Perl. Вы знаете, как открыть и прочитать файл с помощью Perl?