2009-06-22 47 views
5

Tôi muốn kiểm tra xem đường dẫn tệp có nằm trong thư mục đã cho hay không (hoặc một trong các thư mục con của nó), từ PowerShell.Làm cách nào để kiểm tra xem tệp có nằm trong thư mục đã cho hay không, trong PowerShell?

Ngay bây giờ tôi đang làm:

$file.StartsWith( $directory, [StringComparison]::InvariantCultureIgnoreCase) 

nhưng tôi chắc chắn có những cách tốt hơn.

Tôi có thể thực hiện $file.Directory và lặp qua tất cả .Parent giây, nhưng tôi đã hy vọng điều gì đó đơn giản hơn.

EDIT: tệp có thể không tồn tại; Tôi chỉ nhìn vào con đường.

Trả lời

0

Something thật nhanh:

14:47:28 PS>pwd 

C: \ Documents and Settings \ tôi \ Desktop

14:47:30 PS> $ path = pwd

14:48:03 PS > $ path

C: \ Documents and Settings \ tôi \ Desktop

14:48:16 PS> $ file = Get-ChildItem $ path - recurse | Trong đó {$ _. Tên -match "thisfiledoesnt.exist"}

14:50:55 PS> if ($ files) {write-host "tệp tồn tại trong đường dẫn này ở đâu đó"} else {write-host " không có nó không "} không có nó không

(tạo tập tin mới trên desktop hoặc trong một thư mục trên máy tính để bàn và đặt tên là 'thisfileexists.txt')

14:51:03 PS> $ files = Get-ChildItem $ path -recurse | Trong đó {$ _. Name -match "thisfileexists.txt"}

14:52:07 PS> if ($ files) {write-host "tệp tồn tại trong đường dẫn này ở đâu đó"} else {write-host " không có nó không "} tệp tồn tại trong đường dẫn này ở đâu đó

Việc lặp lại khóa học vẫn đang diễn ra, nhưng PS đang thực hiện việc đó cho bạn. Bạn cũng có thể cần thực thi nếu tìm kiếm các tệp hệ thống/ẩn.

+0

Tôi không quan tâm liệu tệp có tồn tại hay không, nhưng liệu đường dẫn của tệp có nằm trong thư mục hay không. Ngoài ra, định dạng của bạn không rõ ràng. –

+0

Vâng, định dạng mã ở đây không hoạt động tốt cho PS. Đây không phải là tệp PS1 đầy đủ, chỉ cần gõ vào dòng PS cmd. Câu hỏi của bạn hỏi "Làm cách nào để kiểm tra xem tệp có nằm trong thư mục đã cho hay không ..." Có vẻ như câu trả lời khác cũng đang kiểm tra tệp, như bạn đã hỏi. Tôi thấy chỉnh sửa của bạn, nhưng làm thế nào một tập tin có một đường dẫn nếu nó thậm chí không tồn tại? – Bratch

+0

Tôi nghĩ rằng tôi nhận được nó ngay bây giờ, bạn có đường dẫn tập tin này được lưu trữ ở đâu đó, và bạn muốn xem nếu một phần đường dẫn tồn tại bên dưới một số đường dẫn được chỉ định khác? – Bratch

5

Làm thế nào về một cái gì đó đơn giản như:

PS> gci . -r foo.txt 

này mặc nhiên sử dụng các tham số -filter (theo vị trí) quy định cụ thể như foo.txt bộ lọc. Bạn cũng có thể chỉ định * .txt hoặc foo? .txt. Vấn đề với StartsWith là trong khi bạn xử lý so sánh phân biệt dạng chữ, vẫn có vấn đề là cả hai và/là các dấu tách đường dẫn hợp lệ trong PowerShell.

Giả sử các tập tin có thể không tồn tại và cả $ tập tin và thư mục $ là đường dẫn tuyệt đối, bạn có thể làm điều này "PowerShell" cách:

(Split-Path $file -Parent) -replace '/','\' -eq (Get-Item $directory).FullName 

Nhưng điều đó là không lớn kể từ khi bạn vẫn phải kinh điển đường dẫn/-> \ nhưng ít nhất so sánh chuỗi PowerShell không phân biệt chữ hoa chữ thường. Một tùy chọn khác là sử dụng IO.Path để chuẩn hóa đường dẫn, ví dụ::

[io.path]::GetDirectoryName($file) -eq [io.path]::GetFullPath($directory) 

Một vấn đề với điều này là GetFullPath cũng sẽ tạo ra một đường dẫn tương đối một đường dẫn tuyệt đối dựa trên dir hiện hành của quá trình mà nhiều lần hơn không, là không giống như dir hiện tại của PowerShell. Vì vậy, chỉ cần chắc chắn rằng thư mục $ là một đường dẫn tuyệt đối ngay cả khi bạn phải chỉ định nó như "$ pwd \ $ directory".

+0

+1. Có thể chỉ định -path và -fil riêng biệt là rất thuận tiện. Tìm hiểu nó, thích nó. –

0

Một cái gì đó như thế này?

Get-ChildItem -Recurse $directory | Where-Object { $_.PSIsContainer -and ` 
    $_.FullName -match "^$($file.Parent)" } | Select-Object -First 1 
0

Từ khi phần đường có thể không tồn tại, sử dụng string.StartsWith là tốt để làm kiểu này thử nghiệm (mặc dù OrdinalIgnoreCase is a better representation of how the file system compares paths).

Thông báo trước duy nhất là các đường dẫn cần phải ở dạng chính tắc. Nếu không, các đường dẫn như C:\x\..\a\b.txtC:/a/b.txt sẽ không thực hiện được "đây là thư mục" C:\a\ ". Bạn có thể sử dụng Path.GetFullPath phương pháp tĩnh để có được tên đầy đủ của con đường trước khi bạn làm bài kiểm tra:

function Test-SubPath([string]$directory, [string]$subpath) { 
    $dPath = [IO.Path]::GetFullPath($directory) 
    $sPath = [IO.Path]::GetFullPath($subpath) 
    return $sPath.StartsWith($dPath, [StringComparison]::OrdinalIgnoreCase) 
} 

Cũng lưu ý rằng điều này không bao gồm ngăn chặn hợp lý (ví dụ như nếu bạn có \\some\network\path\ ánh xạ tới Z:\path\, thử nghiệm xem \\some\network\path\b.txt dưới Z:\ sẽ không thành công, mặc dù tệp có thể được truy cập thông qua Z:\path\b.txt). Nếu bạn cần hỗ trợ hành vi này, these questions có thể hữu ích.

0

Nếu bạn chuyển đổi chuỗi đầu vào của mình thành DirectoryInfo và FileInfo, bạn sẽ không gặp bất kỳ vấn đề gì với so sánh chuỗi.

function Test-FileInSubPath([System.IO.DirectoryInfo]$Dir,[System.IO.FileInfo]$File) 
{ 
    $File.FullName.StartsWith($Dir.FullName) 
} 
Các vấn đề liên quan