簡體   English   中英

Linux Perl 腳本中的 grep 命令不起作用

[英]Linux grep command in Perl script not working

我有一個 grep 命令,它適用於 Linux 命令提示符: grep -Po 'rand_num=\K[^ ]*' log.txt在我的rand_num=中打印后的編號文件。 但我在 perl 腳本中需要這個命令。 我試過了

my $rand_number;
$rand_number = system("grep -Po 'rand_num=\K[^ ]*' log.txt");
print "Random number = $rand_number";

但它不起作用。 我試過$rand_number = `grep -Po 'rand_num=\K[^ ]*' log.txt`; 但這也沒有用

有人可以告訴這里有什么錯誤以及它是如何工作的嗎?

提前致謝。

你發現自己陷入了引用地獄的困境。 Perl 將\K視為轉義序列,並在實際字符串system中刪除反斜杠。 如果需要,您可以雙重轉義反斜杠

system("grep -Po 'rand_num=\\K[^ ]*' log.txt");

或者您可以使用 Perl 的無數種方法之一來編寫一個完全禁止反斜杠擴展的字符串。

system q(grep -Po 'rand_num=\K[^ ]*' log.txt);

這可能看起來很奇怪,如果您的編輯器不是為 Perl 設計的,它也可能無法理解(老實說,我很驚訝 StackOverflow 的代碼熒光筆能正確處理它)。 但是q(...)等價於'...' ,只是您可以在前者中使用單引號。

一旦進入 Perl 腳本,就無需將 go 輸出到系統以運行外部命令(使用 Perl 的正則表達式)——因為 Z0114AD06D728F1834E36FE1A39574EF4 可以做得很好。 而且真的更好。

這里有一些方法可以做到這一點。

打開一個文件並逐行讀取,從每一行獲取所需的短語

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

my @random_numbers;
while (<$fh>) { 
    push @random_numbers, /rand_num=(\S+)/g;
}
close $fh;
say for @random_numbers;

或一次讀取所有行並將它們通過各種過濾器

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

my @random_numbers = map { /rand_num=(\S+)/g } <$fh>;

close $fh;
say for @random_numbers;

我使用map從每一行中提取短語,因為grep將返回滿足條件的整行。 如果沒有匹配,則返回一個空列表,從map中“消失”到整個返回列表中,或者如果沒有任何匹配項,則進入一個未初始化的數組。 這樣map充當過濾器。

上面從每行的所有rand_num=NUM中捕獲(假定的 )數字,如果一行上可以有多個。 If 還假定文件名$file已以某種方式讀入腳本。

或者,使用“null”文件句柄(不需要文件名)

my @random_numbers;
while (<>) { ... }                    # same block as in first example

#  OR 

my @random_numbers = map { ... } <>;  # same block as in second example

如果在命令行上使用該文件名調用腳本,則script.pl file

這是因為“魔法”菱形運算符( <> ) 逐行讀取在命令行上提交的文件。 所有這些——如果腳本作為script.pl file1 file2...它將通過所有這些文件執行上述操作。

也可以將整個文件讀入一個字符串(“slurp”它),然后使用它。 當感興趣的模式分布在多條線上時,這很有幫助。 也使用一個庫,這里是Path::Tiny

use Path::Tiny;  # path()

my @rn = path($file)->slurp =~ /.../g;  # same regex as before

現在正則表達式匹配應用於slurp方法返回的字符串,該字符串包含整個文件。 由於它是在列表上下文中完成的,通過“列表”分配強加於正則表達式,所有匹配項都在分配給@rn的列表中返回。

我大膽假設您的(每個)腳本以

use warnings;
use strict;

對於功能say ,我們還需要use feature 'say'; use包含它或其他大型框架的 Perl 版本。


問題中的正則表達式匹配rand_num=之后的所有非空白字符。 如果絕對確定(呵呵)這些只能是預期的數字,那就這樣吧。

否則,可能會更加小心並使用僅匹配實際數字的模式。 或者,如上所述捕獲,然后檢查它確實是一個數字,使用Scalar::Util中的looks_like_number

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM