2010-08-18 40 views
14
$a = '/etc/init/tree/errrocodr/a.txt' 

Tôi muốn trích xuất /etc/init/tree/errrocodr/ thành $dira.txt tới $file. Làm thế nào tôi có thể làm điều đó?Làm cách nào để tách đường dẫn đầy đủ thành thư mục và tên tệp?

(Chú ý: câu hỏi ban đầu giả thiết rằng bạn cần một biểu thức chính quy cho điều đó.)

+0

Bạn chưa đặt câu hỏi này tại http://stackoverflow.com/questions/3511214/how-to-support-the-searching-file-based-on-regular-expression? Bạn nên chỉnh sửa câu hỏi ban đầu của mình để làm rõ câu hỏi, thay vì đăng câu hỏi mới. – Ether

+0

@Ether, đó là một câu hỏi hoàn toàn _different_, hỏi làm thế nào để có được một danh sách các tập tin dựa trên một ký tự đại diện. Đây là cách chia nhỏ một tệp tin đơn lẻ thành các phần của nó. – paxdiablo

Trả lời

24

Chỉ cần sử dụng 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"; 

Bạn có thể thấy điều này trả lại kết quả mà bạn yêu cầu nhưng nó cũng có khả năng chụp các tiện ích mở rộng (trong phần sau ở trên):

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

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

Hoặc cách khác, có một cái nhìn tại File :: Spec-> splitpath(), mà tách ra khối lượng là tốt (nếu bạn xảy ra được trên một nền tảng có một điều như vậy). Lợi thế của một trong hai gói là chúng là tiêu chuẩn và di động. –

16

bạn không cần một regex cho điều này, bạn có thể sử dụng dirname():

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

tuy nhiên regex này sẽ làm việc:

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

+1, nhưng IMHO không nên sử dụng biến '$ a' trong ví dụ của bạn ngay cả khi OP nhầm lẫn. Nó được sử dụng cho 'sắp xếp' – dawg

0

Ví dụ:

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

Nhưng, giống như sa khác id, tốt hơn là chỉ sử dụng Basename cho việc này.

Và, BTW, tránh tốt hơn $a$b làm tên biến, vì chúng có ý nghĩa đặc biệt, đối với hàm sort.

1

Tôi nghĩ rằng một giải pháp regex là một nhu cầu hoàn toàn hợp pháp - kể từ khi googling của tôi cho chính xác mà mang lại cho tôi ở đây. Tôi muốn rút tên tệp trong nhóm thành một phần của biểu thức đối sánh lớn hơn - đây là nỗ lực của tôi:

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

dùng thử; nó hoạt động ít nhất cho tên tệp, nhưng khi bạn sửa đổi nó, nó cũng cung cấp cho bạn hướng: Bạn cũng có thể sửa đổi nó trên hệ thống UNIX cho \ thay thế nếu/hoặc sử dụng chúng cả hai với |

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

bằng cách nào đó xuyệc ngược trước 2/không được hiển thị ...

1

Sử dụng @array = split("/", $a); và sau đó $array[-1] là tên tập tin của bạn.

Các vấn đề liên quan