Получить полный путь к файлам в PowerShell

156

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

Я делаю что-то подобное, используя Get-ChildItem :

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

Однако он возвращает мне только имена файлов, а не весь путь.

Гаган
источник

Ответы:

232

Добавьте | select FullNameв конец строки выше. Если вам действительно нужно что-то с этим потом сделать, вам, возможно, придется передать это в цикл foreach, например:

get-childitem "C:\windows\System32" -recurse | where {$_.extension -eq ".txt"} | % {
     Write-Host $_.FullName
}
Крис Н
источник
104

Это должно работать намного быстрее, чем использование поздней фильтрации:

Get-ChildItem C:\WINDOWS\System32 -Filter *.txt -Recurse | % { $_.FullName }
Шэй Леви
источник
15
Это верно. Предостережение: эта команда фактически получает файлы типа *.txt*( -Filterиспользует подстановочные знаки CMD). Если это не то, что вам нужно, используйте -Include *.txt.
Роман Кузьмин
28

Вы также можете использовать Select-Object так:

Get-ChildItem "C:\WINDOWS\System32" *.txt -Recurse | Select-Object FullName
Имлокеш
источник
5
Обратите внимание, что Select-Objectвозвращает PSCustomObject, а не строку. Это может не сработать, если вы используете результат в качестве параметра для другой программы
Chintsu
5
Да на то, что сказал @Chintsu. Чтобы получить строки вместо PSCustomObject, используйте -ExpandProperty FullNameвместо просто FullName. Насколько я понимаю, -ExpandPropertyпараметр заставляет командлет возвращать результаты в виде указанного свойства (собственного?) Типа, а не в виде какого-то настраиваемого объекта.
doubleDown
Мне тоже нужно было время (я испортил исходный код программы и позже подумал, что мне, вероятно, следовало бы запустить для нее контроль версий, но я могу получить представление о моем первом коммите против «master», получив файлы после установки:Get-ChildItem -Path 'C:\Program Files\TheProgram' -Recurse | Where-Object -FilterScript {($_.LastWriteTime -gt '2020-03-01')} | Select-Object FullName
Нил Гай Линдберг
20

Вот более короткий:

(Get-ChildItem C:\MYDIRECTORY -Recurse).fullname > filename.txt
JustAGuy
источник
24
Вот более короткий:(gci -r c:\).fullname
Chris N
11
Вот более короткий:(ls -r c:\).fullname
Kalamane
16
Вот более короткий:(ls -r c:).fullname
Валианте
9

Если вам нужны относительные пути, вы можете просто использовать -Nameфлаг.

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

Полиморфикс
источник
6

Действительно раздражающая вещь в 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): поведение Stringification экземпляров FileInfo / Directory изменилось с версии v6.0.2 # 7132

js2010
источник
5

Попробуй это:

Get-ChildItem C:\windows\System32 -Include *.txt -Recurse | select -ExpandProperty FullName
Михаил Басюк
источник
2
Пожалуйста, добавьте немного информации о том, чем отличается ваша попытка и почему другая не сработала.
Уве Алльнер
5
Get-ChildItem -Recurse *.txt | Format-Table FullName

Это то, что я использовал. Мне кажется, это более понятно, поскольку в нем нет синтаксиса цикла.

Мандрагора
источник
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
L1ttl3J1m
источник
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, я знаю, что это не самый оптимальный подход, но мне нужно сделать это так :(
Хибер Солис
Просто добавьте $перед textfile: $textfile = $fileList[$i].FullName. Предполагая, что $iимеет числовое значение, то есть.
NostraDavid
1
gci "C:\WINDOWS\System32" -r -include .txt | select fullname
Вуонг Доан
источник
6
Не могли бы вы подробнее рассказать о своем ответе, добавив еще немного описания предлагаемого вами решения?
abarisone
1

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

Некоторым людям не по вкусу операторы направленных каналов, они предпочитают цепочку. Посмотрите несколько интересных мнений по этой теме в системе отслеживания проблем roslyn : dotnet / roslyn # 5445 .

В зависимости от случая и контекста один из этих подходов можно считать неявным (или косвенным). Например, в этом случае использование конвейера для enumerable требует специального токена $_(aka 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
@Polymorphix, вы правы, у меня он работает в Windows 10 (не уверен, какую версию я пробовал раньше). Однако то же самое верно и для -Fileпереключателя -fiв примере:-fil и -fileработает, но не работает -f. В соответствии со стилем POSIX это должно быть --file(многобуквенное) и -f(однобуквенное, если -f не зарезервировано для чего-то еще, скажем, forceswitch, тогда это может быть что-то еще, например, -lили вообще не однобуквенный вариант).
vulcan raven
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 

В моих тестах этот синтаксис прекрасно работает.

Жозуэ Саломао
источник