Отримайте повний шлях до файлів у PowerShell


147

Мені потрібно отримати всі файли, включаючи файли, наявні в підпапках, що належать до певного типу.

Я роблю щось подібне, використовуючи Get-ChildItem :

Get-ChildItem "C:\windows\System32" -Recurse | where {$_.extension -eq ".txt"}

Однак повертає мені лише імена файлів, а не весь шлях.

Відповіді:


220

Додайте | select FullNameдо кінця рядка вище. Якщо вам потрібно зробити щось із цим згодом, можливо, вам доведеться передати це в петлю переднього плану, як-от так:

get-childitem "C:\windows\System32" -recurse | where {$_.extension -eq ".txt"} | % {
     Write-Host $_.FullName
}

101

Це має працювати набагато швидше, ніж використання пізньої фільтрації:

Get-ChildItem C:\WINDOWS\System32 -Filter *.txt -Recurse | % { $_.FullName }

14
Це правда. Застереження: ця команда фактично отримує файли на зразок *.txt*( -Filterвикористовує підстановку CMD). Якщо це не те, що ви хочете, то використовуйте -Include *.txt.
Роман Кузьмін

26

Ви також можете використовувати Select-Object так:

Get-ChildItem "C:\WINDOWS\System32" *.txt -Recurse | Select-Object FullName

5
Зауважте, що Select-Objectповертає PSCustomObject, а не рядок. Це може не працювати, якщо ви використовуєте результат як параметр для іншої програми
Chintsu,

5
Так, на що сказав @Chintsu. Щоб отримати рядки замість PSCustomObject, використовуйте -ExpandProperty FullNameпросто FullName. Наскільки я розумію, -ExpandPropertyпараметр командлет змушує повертати результати як тип вказаного властивості (нативної?) Замість як якийсь спеціальний об'єкт.
подвійнеDown

Мені також потрібен був час (я заплутався з джерелом програми і пізніше подумав, що, мабуть, я мав би почати керувати ним джерелом, але я можу отримати уявлення про своє перше вчинення проти "майстра", отримавши файли після встановлення:Get-ChildItem -Path 'C:\Program Files\TheProgram' -Recurse | Where-Object -FilterScript {($_.LastWriteTime -gt '2020-03-01')} | Select-Object FullName
Ніл Гай Ліндберг


9

Якщо відносні шляхи - це те, що ви хочете, ви можете просто використати -Nameпрапор.

Get-ChildItem "C:\windows\System32" -Recurse -Filter *.txt -Name


5
Get-ChildItem -Recurse *.txt | Format-Table FullName

Саме цим я і користувався. Я вважаю, що це зрозуміліше, оскільки він не містить синтаксису циклу.


5

Дійсно дратівлива річ в PS 5, де $ _ не буде повним шляхом в межах foreach. Це рядкові версії об'єктів FileInfo та DirectoryInfo. Чомусь підкреслюється підстановочний знак на шляху, або скористайтеся Powershell 6 або 7. Ви також можете передати "get-item" посередині.

Get-ChildItem -path C:\WINDOWS\System32\*.txt -Recurse | foreach { "$_" }

Get-ChildItem -path C:\WINDOWS\System32 -Recurse | get-item | foreach { "$_" }

Це, здається, виникла проблема з .Net, яку вирішили в .Net Core (Powershell 7): порядок строфіфікації екземплярів FileInfo / Directory змінився з моменту v6.0.2 # 7132


4

Це працювало для мене і створює список імен:

$Thisfile=(get-childitem -path 10* -include '*.JPG' -recurse).fullname

Я знайшов це за допомогою get-member -membertype propertiesнеймовірно корисної команди. Більшість варіантів, які він надає вам, додаються з .<thing>, як fullnameі тут. Ви можете дотримуватися тієї ж команди;

  | get-member -membertype properties 

в кінці будь-якої команди, щоб отримати більше інформації про те, що ви можете зробити з ними та як отримати доступ до них:

get-childitem -path 10* -include '*.JPG' -recurse | get-member -membertype properties

3

Спробуйте це:

Get-ChildItem C:\windows\System32 -Include *.txt -Recurse | select -ExpandProperty FullName

2
Будь ласка, додайте трохи інформації про те, що відрізняється від вашої спроби та чому інша не вийшла.
Uwe Allner

2

Чому ще ніхто не використовував цикл foreach? Професійна полягає в тому, що ви можете легко назвати свою змінну:

# Note that I'm pretty explicit here. This would work as well as the line after:
# Get-ChildItem -Recurse C:\windows\System32\*.txt
$fileList = Get-ChildItem -Recurse -Path C:\windows\System32 -Include *.txt
foreach ($textfile in $fileList) {
    # This includes the filename ;)
    $filePath = $textfile.fullname
    # You can replace the next line with whatever you want to.
    Write-Output $filePath
}

як я можу отримати індивідуальний файловий шлях текстового файлу без використання текстового файлу foreach у fileList? щось на зразок textfile = $ fileList [$ i] .fullname, я знаю, це не найоптимальніший підхід, але мені потрібно зробити так :(
Heber Solis

Просто додайте $перед textfile: $textfile = $fileList[$i].FullName. Припущення $iмає числове значення, тобто.
NostraDavid

1
gci "C:\WINDOWS\System32" -r -include .txt | select fullname

6
Чи можете ви детальніше розглянути свою відповідь, додавши трохи більше опису про рішення, яке ви надаєте?
абарізон

1

[альтернативний синтаксис]

Для деяких людей оператори трубопровідних труб - це не їх смак, але вони, скоріше, віддають перевагу ланцюгу. Дивіться деякі цікаві думки з цього питання спільно в рослини відстеження проблем: DotNet / Рослин # 5445 .

Виходячи з випадку та контексту, один із таких підходів можна вважати неявним (або непрямим). Наприклад, у цьому випадку використання труби проти перелічених потребує спеціальних маркерів $_(ака PowerShell's "THIS" token) для деяких може виявитися неприємним.

Для таких хлопців ось більш стислий, прямолінійний спосіб зробити це за допомогою ланцюгових точок :

(gci . -re -fi *.txt).FullName

(<Пихата> Зверніть увагу , що PowerShell в командні аргументи парсер приймає часткові імена параметрів Таким чином , на додаток до. -recursive, -recursiv, -recursi, -recurs, -recur, -recu, -recІ -reприймаються, але , на жаль , НЕ -r.. , який є єдино правильним вибором , який має сенс з одного -символу (якщо ми йдіть за POSIXy UNIXy умовами)! </rant>)


1
Зауважте, що -rкоротка форма: -Recurseмені коротка форма працює чудово.
Поліморфікс

@Polymorphix, ви праві, він працює для мене в Windows 10 (не впевнений, яку версію я намагався раніше). Однак це справедливо і з -Fileперемикачем -fiу вибірці: -filі-file працює, але ні -f. Переходячи за стилем POSIX, це має бути --file(багато літер) та -f(однобуквене, якщо тільки -f не зарезервовано для чогось іншого, скажімо forceперемикач, то це може бути щось інше, як -lабо взагалі немає однолітерного варіанту).
вулкан ворон

1

Я використовую нижче сценарій, щоб отримати весь шлях до папки:

Get-ChildItem -path "C:\" -Recurse -Directory -Force -ErrorAction SilentlyContinue | Select-Object FullName | Out-File "Folder_List.csv"

Повний шлях до папки не надходить. Після 113 символів, йде:

Example - C:\ProgramData\Microsoft\Windows\DeviceMetadataCache\dmrccache\en-US\ec4d5fdd-aa12-400f-83e2-7b0ea6023eb7\Windows...

0

Я використовував цю команду рядка для пошуку файлів ".xlm" у "C: \ Temp", а результат друку повного імені у файлі "result.txt":

(Get-ChildItem "C:\Temp" -Recurse | where {$_.extension -eq ".xml"} ).fullname > result.txt 

У моїх тестах цей синтаксис працює для мене прекрасно.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.