Home > OS >  How can I use perl to delete files matching a regex
How can I use perl to delete files matching a regex

Time:10-07

Due to a Makefile mistake, I have some fake files in my 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/
$

My attempts to delete the unwanted files with linux shell globs were complicated by special characters in the filenames. What I want is a remove command that matches against a pcre. How can I delete the files matching this perl regex: /\W\d \.\d / (example filename: '=0.1.1')?

It's been years since I touched perl, but it seems like a good tool for this small task.

CodePudding user response:

Why not just:

$ rm =*

Sometimes, shell commands are the best option.

CodePudding user response:

Fetch a wider set of files and then filter through whatever youo want

my $re = qr/\W[0-9] \.[0-9] /;  

my @files_to_del = grep { /$re/ } glob "$dir/*"; 

where that * might as well have some pre-selection, if suitable. In particular, if the = is a literal character (and not an indicator printed by the shell) then glob "=*" will fetch files starting with it, and then you can pass those through grep filter.

Or you can read the directory any other way (opendir readdir, modules like Path::Tiny, etc), and filter files.


That leading = may be an "indicator" of a file type if ls has been aliased with ls -F. This can be checked by running ls with suppressed aliases.

If that is so, the = stands for it being a socket, what in what in Perl can be tested for by the -S filetest.

Then that \W in the proposed regex may need to be changed to \W? or (?:\W|^) (to allow for no non-word characters preceding a digit), along with a test for a socket. Like

my $re = qr/\W? [0-9]  \. [0-9] /x;

my @files_to_del = grep { /$re/ and -S } glob "$dir/*"; 

CodePudding user response:

I used the following script to delete filenames matching this perl regex: /\W\d \.\d /...

my $cmd1= "ls";
my @output=`$cmd1`;
chomp @output;
foreach my $filename (@output) {
    if ($filename =~ /\W\d \.\d /) {
        my $cmd2 = "rm $filename\n";
        print "DELETING $filename\n";
        `$cmd2`;
    }
}
  • Related