[英]How can I extract just the elements I want from a Perl array?
嘿,我想知道如何讓這段代碼工作。 基本上我想保留$filename
的行,只要它們在路徑中包含$user
:
open STDERR, ">/dev/null";
$filename=`find -H /home | grep $file`;
@filenames = split(/\n/, $filename);
for $i (@filenames) {
if ($i =~ m/$user/) {
#keep results
} else {
delete $i; # does not work.
}
}
$filename = join ("\n", @filenames);
close STDERR;
我知道你可以刪除像delete $array[index]
但我沒有這種循環的索引,我知道。
您可以用以下代碼替換循環:
@filenames = grep /$user/, @filenames;
當你使用foreach
循環時,沒有辦法做到這一點。 但是沒關系。 正確的做法是使用File :: Find來完成您的任務。
use File::Find 'find';
...
my @files;
my $wanted = sub {
return unless /\Q$file/ && /\Q$user/;
push @files, $_;
};
find({ wanted => $wanted, no_chdir => 1 }, '/home');
不要忘記使用\\Q
轉義變量以用於正則表達式。
順便說一句,將STDERR重定向到/dev/null
更好地寫為
{
local *STDERR;
open STDERR, '>', '/dev/null';
...
}
它在退出塊后恢復文件句柄。
如果你有一個支持-path
的find
,那么讓它為你做的工作, 例如 ,
#! /usr/bin/perl
use warnings;
use strict;
my $user = "gbacon";
my $file = "bash";
my $path = join " -a " => map "-path '*$_*'", $user, $file;
chomp(my @filenames = `find -H /home $path 2>/dev/null`);
print map "$_\n", @filenames;
注意列表上下文中的反引號如何從命令的輸出中返回一個行列表(包括它們的終結符,上面用chomp
刪除)。 這樣可以節省您自己split
。
輸出:
/home/gbacon/.bash_history /home/gbacon/.bashrc /home/gbacon/.bash_logout
如果要從數組中刪除項目,請使用多才多藝的splice
功能。
my @foo = qw( a b c d e f );
splice( @foo, 3, 1 ); # Remove element at index 3.
您可以使用splice
各種其他操作。 有關詳細信息,請參閱perldoc 。
至於codeholic暗示,在遍歷它與你永遠不應該修改陣列for
循環。 如果要在迭代時修改數組,請改用while
循環。
這樣做的原因是, for
在parens中計算表達式一次,並將結果列表中的每個項目映射到別名。 如果數組發生變化,指針就會搞砸,隨之而來的是混亂。
A while
每次循環都會評估條件,因此您不會遇到指向不存在的值的問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.