Как я могу выделить полный путь в каталог и имя файла?

$a = '/etc/init/tree/errrocodr/a.txt'

Я хочу извлечь /etc/init/tree/errrocodr/ в $dir и a.txt в $file. Как я могу это сделать?

(Примечание редактора: исходный вопрос предполагал, что для этого вам нужно регулярное выражение.)

Ответ 1

Просто используйте Basename:

use File::Basename;
$fullspec = "/etc/init/tree/errrocodr/a.txt";

my($file, $dir, $ext) = fileparse($fullspec);
print "Directory: " . $dir . "\n";
print "File:      " . $file . "\n";
print "Suffix:    " . $ext . "\n\n";

my($file, $dir, $ext) = fileparse($fullspec, qr/\.[^.]*/);
print "Directory: " . $dir . "\n";
print "File:      " . $file . "\n";
print "Suffix:    " . $ext . "\n";

Вы можете увидеть, что это возвращает запрошенные вами результаты, но также способно также захватить расширения (в последнем разделе выше):

Directory: /etc/init/tree/errrocodr/
File:      a.txt
Suffix:

Directory: /etc/init/tree/errrocodr/
File:      a
Suffix:    .txt

Ответ 2

для этого вам не нужно регулярное выражение, вы можете использовать dirname():

use File::Basename;
my $dir = dirname($a)

однако это регулярное выражение будет работать:

my $dir = $a
$dir =~ s/(.*)\/.*$/$1/

Ответ 3

Я думаю, что решение регулярных выражений является совершенно законной потребностью - так как мой поисковик для этого привел меня сюда. Я хочу вытащить имя файла в группе, которая является частью выражения большего соответствия - вот моя попытка:

~> echo "/a/b/c/d" | perl -ne '/(?<dir>\/(\w+\/)*)(?<file>\w+)/ && print "dir $+{dir}  file $+{file}\n";'
dir /a/b/c/  file d

Ответ 4

Используйте @array = split("/", $a); а затем $array[-1] - ваше имя файла.

Ответ 5

Например:

    $a =~ m#^(.*?)([^/]*)$#;
   ($dir,$file)  = ($1,$2);

Но, как сказал другой, лучше использовать Basename для этого.

И, BTW, лучше избегайте $a и $b в качестве имен переменных, поскольку они имеют особое значение для функции sort.

Ответ 6

попробуйте это; он работает хотя бы для имени файла, но когда вы его изменяете, он также дает вам направление: Вы также можете изменить его в UNIX-системах для\вместо if/или использовать их как с |

$filename = ~ s/(^.*/)//g;

как-то обратная косая черта перед 2-й/не отображается...

Ответ 7

Возможно, это сработает:

@^(.+/)/([^/]+)[email protected]