Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

glob does not recognize filename with square brackets

Tags:

perl

I have a folder, its name is:

drwxr-xr-x.  2 user user       4096 Aug  2 18:30 folder name [www.website.com]

but when I use the glob like this:

my @files = glob ("/home/user/Downloads/folder name [www.website.com]/*");
print "@files\n";

it does not list the files in the directory, the result is the following:

/home/user/Downloads/folder name

I have tried escaping the whitespaces and the square brackets like this:

/home/user/Downloads/folder\ name\ \[www.website.com\]

But the result is the same, What could be my mistake or What could do to improve my code?

Thanks in advance

like image 851
Davico Avatar asked Sep 25 '13 15:09

Davico


2 Answers

The builtin glob function splits patterns at whitespace. So you are doing something equivalent to

my @files = (
  glob("/home/user/Downloads/folder"),
  glob("name"),
  glob("[www.website.com]/*"),
);

Escaping the whitespace and the brackets would be one option. But it is better to use the core File::Glob module for finer control:

use File::Glob ':bsd_glob';

my @files = bsd_glob("/home/user/Downloads/folder name \\[www.website.com\\]/*");

Now, only the brackets need to be escaped. This also overrides the builtin glob, so you don't actually have to change your code except for that one import (and of course, the pattern).

like image 113
amon Avatar answered Nov 18 '22 20:11

amon


Spaces and square brackers are special in glob patterns. To match

/home/user/Downloads/folder name [www.website.com]

you need

/home/user/Downloads/folder\ name\ \[www.website.com\]

So the full pattern is

/home/user/Downloads/folder\ name\ \[www.website.com\]/*

To build that string, you could use the string literal

"/home/user/Downloads/folder\\ name\\ \\[www.website.com\\]/*"

Test:

$ perl -E'say for glob "/home/eric/Downloads/folder\\ name\\ \\[www.website.com\\]/*"'
/home/eric/Downloads/folder name [www.website.com]/foo

Note that spaces cannot be escape in Windows. You'd have to use File::Glob's bsd_glob. (It's calls the same function as glob, but with different flags.)

use File::Glob qw( bsd_glob );
say for bsd_glob("C:\\Program Files\\*");
like image 34
ikegami Avatar answered Nov 18 '22 20:11

ikegami