我正在開發基于 Linux 的 Debian 環境(確切地說是 Proxmox 服務器),并且正在撰寫一個 perl 腳本。
我的問題是:我有一個檔案夾,里面有一些檔案,這個檔案夾中的每個檔案都有一個數字作為名稱(例如:100、501、102 ...)。可能的最小數字是 100,最大數字沒有限制。
我希望我的腳本只回傳名稱在 100 到 500 之間的檔案。所以,我這樣寫:
system(ls /the/path/to/my/files | grep -E "^[1-4][0-9]{2}|5[0]{2}");
我認為我的正則運算式和命令很好,因為當我在終端中輸入它時,它是有效的。但是一旦我執行我的腳本,我就會收到這些錯誤訊息:
String found where operator expected at backupsrvproxmox.pl line 3, near "E "^[1-4][0-9]{2}|5[0]{2}""
(Do you need to predeclare E?)
Unknown regexp modifier "/b" at backupsrvproxmox.pl line 3, at end of line
syntax error at backupsrvproxmox.pl line 3, near "E "^[1-4][0-9]{2}|5[0]{2}""
Execution of backupsrvproxmox.pl aborted due to compilation errors.
我也嘗試過 egrep 但仍然無法正常作業。
我不明白為什么錯誤訊息是關于 /b 修飾符的,因為我只使用整數而不使用字串。
所以,任何幫助都會很好!
uj5u.com熱心網友回復:
而不是使用系統工具 viasystem可以很好地在你的程式中完成這一切
my @files = grep {
my ($n) = m{.*/([0-9] )}; #/
defined $n and $n >= 100 and $n <= 500;
}
glob "/the/path/to/my/files/*"
這假設檔案名中的數字位于檔案名的開頭,從問題中提取,因此檔案名本身的子模式直接跟在/. ?
(#/右側的“注釋”只是為了關閉編輯器中錯誤和令人困惑的語法突出顯示。)
由于語法錯誤,您嘗試的命令不起作用,因為系統在您給它一堆“裸詞”時接受一個字串或字串串列,這使解釋器感到困惑以發出復雜??的錯誤訊息(大多數時間 perl 的錯誤資訊是正確的)。
但是沒有必要忍受語法細節,這可能會涉及到這一點,以及復雜和混亂(在引擎蓋下)和低效的 shell 呼叫。
?它還假設檔案不在當前目錄中——很明顯,因為路徑被傳遞給glob(而不僅僅是*當前目錄中的檔案),它回傳帶有路徑的檔案名,這就是為什么我們需要在匹配檔案名之前.*/貪婪地到達最后一個/。
但是如果我們在當前目錄中,那將無法作業,因為/檔案名中沒有。為了包括這種可能性,需要修改正則運算式,例如
my ($n) = m{ (?: .*/ | ^) ([0-9] )}x;
這匹配以數字開頭的檔案名,或者在路徑中的最后一個斜杠之后(帶有.*/子模式)或在字串的開頭(帶有^錨點)。
修飾符/x使它丟棄模式中的文字空格,因此我們可以自由地使用它們(以及換行符和#注釋!)以使混亂可能更具可讀性。然后我也使用{}for 定界符,這樣就不必/在模式中轉義(并且使用除//我們必須有之外的任何定界符m)。
uj5u.com熱心網友回復:
使用正則運算式嘗試匹配一系列數字只是一種痛苦。這是 perl;無需使用外部程式來獲取檔案串列(通常在 shell 腳本中也是一個壞主意;請參閱為什么不應該決議的輸出ls(1))!
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
sub getfiles {
my $directory = shift;
opendir my $dir, $directory or die "Unable to open $directory: $!";
my @files =
grep { /^\d $/ && $_ >= 100 && $_ <= 500 } readdir $dir;
closedir $dir;
return @files;
}
my @files = getfiles '/the/path/to/my/files/';
say "@files";
或者使用有用的Path::Tiny模塊:
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
use Path::Tiny;
# Returns a list of Path::Tiny objects, not just names.
sub getfiles {
my $dir = path($_[0]);
return grep { $_ >= 100 && $_ <= 500 } $dir->children(qr/^\d $/);
}
my @files = getfiles '/the/path/to/my/files/';
say "@files";
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/409721.html
標籤:
上一篇:Perl檢查物件是否在JSON中定義、丟失或為空的最佳方法是什么
下一篇:VBGetfiles排除
