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`;
}
}