由于一個Makefile錯誤,我的 git repo 中有一些假檔案......
$ ls
=0.1.1 =4.8.0 LICENSE
=0.5.3 =5.2.0 Makefile
=0.6.1 =7.1.0 pyproject.toml
=0.6.1, all_commands.txt README_git_workflow.md
=0.8.1 CHANGES.md README.md
=1.2.0 ciscoconfparse/ requirements.txt
=1.7.0 configs/ sphinx-doc/
=2.0 CONTRIBUTING.md tests/
=2.2.0 deploy_docs.py tutorial/
=22.2.0 dev_tools/ utils/
=22.8.0 do.py
=2.7.0 examples/
$
我試過這個,但似乎可能有一些更有效的方法來完成這項任務......
# glob "*" will list all files globbed against "*"
foreach my $filename (grep { /\W\d \.\d / } glob "*") {
my $cmd1 = "rm $filename";
`$cmd1`;
}
問題:
- 我想要一個與 pcre 匹配的洗掉命令。
perl洗掉與此 perl 正則運算式匹配的檔案的更有效解決方案是什么:/\W\d \.\d /(example filename: '=0.1.1')?
uj5u.com熱心網友回復:
獲取更廣泛的檔案集,然后過濾您想要的任何內容
my @files_to_del = grep { /^\W[0-9] \.[0-9] / and not -d } glob "$dir/*";
我添加了一個錨 ( ^) 以便正則運算式只能匹配以該模式開頭的字串,否則這可能會破壞預期之外的檔案。重新考慮你到底需要什么。
總而言之(或見下面的單行?)
use warnings;
use strict;
use feature 'say';
use File::Glob ':bsd_glob'; # for better glob()
use Cwd qw(cwd); # current-working-directory
my $dir = shift // cwd; # cwd by default, or from input
my $re = qr/^\W[0-9] \.[0-9] /;
my @files_to_del = grep { /$re/ and not -d } glob "$dir/*";
say for @files_to_del; # please inspect first
#unlink or warn "Can't unlink $_: $!" for @files_to_del;
如果合適的話*,glob最好有一些預選。特別是,如果=是文字字符(而不是 shell 列印的指示符,請參見腳注)? thenglob "=*"將獲取以它開頭的檔案,然后您可以通過grep過濾器傳遞這些檔案。
我排除了由-d filetest標識的目錄,因為我們正在尋找檔案(并且不要與unlink中的一些關于目錄的可怕語言混合,感謝brian d foy評論)。
如果您需要掃描子目錄并對它們做同樣的事情,也許是遞回的——這里似乎不是這樣?File::Find::find- 然后我們可以在(或File::Find::Rule,或其他)中使用此邏輯。
或以任何其他方式讀取目錄(opendir readdir,類似的庫Path::Tiny),然后過濾。
?或者,一個快速的單行...列印(檢查)即將被吹走的東西
perl -wE'say for grep { /^\W[0-9] \.[0-9] / and not -d } glob "*"'
然后洗掉他們
perl -wE'unlink or warn "$_: $!" for grep /^\W[0-9] \.[0-9] / && !-d, glob "*"'
(我只是這樣切換到更緊湊的語法。沒必要)
如果您希望能夠將目錄傳遞給它(可選,或在當前目錄中作業)然后執行
perl -wE'$d = shift//q(.); ...' dirpath (relative path fine. optional)
然后glob "$d/*"在代碼中使用。這與上面腳本中的作業方式相同 - shift從 中提取第一個元素@ARGV,如果在命令列上將任何內容傳遞給腳本,或者如果@ARGV為空,則回傳undef,然后//(定義或)運算子獲取字串q(.)。
?如果已使用別名,則該前導=可能是檔案型別的“指示符”,可以通過使用抑制別名運行來檢查,一種方式是(或檢查)。lsls -Fls\lsalias ls
如果是這樣,則=代表它是一個套接字,在 Perl 中可以通過-Sfiletest 測驗什么。
然后,\W在提議的正則運算式中可能需要更改為\W?允許數字前沒有非單詞字符,以及對套接字的測驗。喜歡
my $re = qr/^\W? [0-9] \. [0-9] /x;
my @files_to_del = grep { /$re/ and -S } glob "$dir/*";
uj5u.com熱心網友回復:
為什么不只是:
$ rm =*
有時,shell 命令是最好的選擇。
uj5u.com熱心網友回復:
在這些情況下,我perl僅用于過濾檔案串列:
ls | perl -ne 'print if /\A\W\d \.\d /a' | xargs rm
而且,當我這樣做時,我會因為沒有使用以下擴展模式做一些更簡單的事情而感到內疚grep:
ls | grep -E '^\W\d \.\d ' | xargs rm
最終我會遇到一個有目錄的問題,所以我需要更加小心檔案串列:
find . -type f -maxdepth 1 | grep -E '^\./\W\d \.\d ' | xargs rm
或者如果我想要的話,我也需要允許rm洗掉目錄:
ls | grep -E '^\W\d \.\d ' | xargs rm -r
uj5u.com熱心網友回復:
干得好。
unlink( grep { /\W\d \.\d / && !-d } glob( "*" ) );
這匹配檔案名,并排除目錄。
uj5u.com熱心網友回復:
要洗掉與以下內容匹配的檔案名:/\W\d \.\d / pcre,請使用以下單行...
1>$fn是一個檔案名...我也洗掉了my關鍵字,因為單行不必擔心perl 詞法范圍:
perl -e 'foreach $fn (grep { /\W\d \.\d / } glob "*") {$cmd1="rm $fn";`$cmd1`;}'
2> 或者正如安迪·萊斯特(Andy Lester)回應的那樣,也許他的回答是我們可以做到的最有效的......
perl -e 'unlink(grep { /\W\d \.\d / } glob "*");'
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/513181.html
