Uzyskaj pełną ścieżkę do plików w programie PowerShell

145

Muszę pobrać wszystkie pliki, w tym pliki obecne w podfolderach, które należą do określonego typu.

Robię coś takiego, używając Get-ChildItem :

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

Jednak zwraca mi tylko nazwy plików, a nie całą ścieżkę.

Gagan
źródło

Odpowiedzi:

219

Dodaj | select FullNamena końcu linii powyżej. Jeśli chcesz coś z tym zrobić później, być może będziesz musiał potokować to do pętli foreach, na przykład:

get-childitem "C:\windows\System32" -recurse | where {$_.extension -eq ".txt"} | % {
     Write-Host $_.FullName
}
Chris N.
źródło
101

Powinno to działać znacznie szybciej niż używanie późnego filtrowania:

Get-ChildItem C:\WINDOWS\System32 -Filter *.txt -Recurse | % { $_.FullName }
Shay Levy
źródło
14
To prawda. Uwaga: to polecenie faktycznie pobiera pliki takie jak *.txt*( -Filterużywa symboli wieloznacznych CMD). Jeśli tego nie chcesz, użyj -Include *.txt.
Roman Kuzmin
26

Możesz także użyć Select-Object w następujący sposób:

Get-ChildItem "C:\WINDOWS\System32" *.txt -Recurse | Select-Object FullName
imlokesh
źródło
5
Zwróć uwagę, że Select-Objectzwraca PSCustomObject, a nie ciąg. Może to nie zadziałać, jeśli użyjesz wyniku jako parametru dla innego programu
Chintsu
5
Tak, na to, co powiedział @Chintsu. Aby otrzymać ciągi zamiast PSCustomObject, użyj -ExpandProperty FullNamezamiast po prostu FullName. O ile rozumiem, -ExpandPropertyparametr powoduje, że polecenie cmdlet zwraca wyniki jako typ określonej właściwości (natywny?) Zamiast jako obiekt niestandardowy.
doubleDown
Potrzebowałem też czasu (pomieszałem ze źródłem programu i pomyślałem później, że prawdopodobnie powinienem był rozpocząć kontrolę źródła na nim, ale mogę uzyskać pojęcie o moim pierwszym zatwierdzeniu przeciwko "master", pobierając pliki od czasu instalacji:Get-ChildItem -Path 'C:\Program Files\TheProgram' -Recurse | Where-Object -FilterScript {($_.LastWriteTime -gt '2020-03-01')} | Select-Object FullName
Neil Guy Lindberg
19

Oto krótszy:

(Get-ChildItem C:\MYDIRECTORY -Recurse).fullname > filename.txt
JustAGuy
źródło
23
Oto krótszy:(gci -r c:\).fullname
Chris N,
11
Oto krótszy:(ls -r c:\).fullname
Kalamane
15
Oto krótszy:(ls -r c:).fullname
Valiante
9

Jeśli ścieżki względne są tym, czego potrzebujesz, możesz po prostu użyć -Nameflagi.

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

Polimorphix
źródło
5
Get-ChildItem -Recurse *.txt | Format-Table FullName

To jest to, czego użyłem. Wydaje mi się, że jest to bardziej zrozumiałe, ponieważ nie zawiera żadnej składni pętli.

Mandragora
źródło
5

Naprawdę irytujące w PS 5, gdzie $ _ nie będzie pełną ścieżką dla wszystkich. To są ciągowe wersje obiektów FileInfo i DirectoryInfo. Z jakiegoś powodu znak wieloznaczny w ścieżce naprawia to lub użyj Powershell 6 lub 7. Możesz również potokować, aby uzyskać element w środku.

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

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

Wydaje się, że był to problem z .Net, który został rozwiązany w .Net Core (Powershell 7): Zachowanie ciągów znaków dla instancji FileInfo / Directory zmieniło się od wersji 6.0.2 # 7132

js2010
źródło
4

To zadziałało dla mnie i tworzy listę nazwisk:

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

Znalazłem to, używając get-member -membertype propertiesniezwykle użytecznego polecenia. większość opcji, które daje, jest zakończona znakiem .<thing>, jak fullnametutaj. Możesz trzymać to samo polecenie;

  | get-member -membertype properties 

na końcu dowolnego polecenia, aby uzyskać więcej informacji o tym, co możesz z nimi zrobić i jak uzyskać do nich dostęp:

get-childitem -path 10* -include '*.JPG' -recurse | get-member -membertype properties
L1ttl3J1m
źródło
3

Spróbuj tego:

Get-ChildItem C:\windows\System32 -Include *.txt -Recurse | select -ExpandProperty FullName
Mykhailo Basiuk
źródło
2
Dodaj trochę informacji o tym, co różni się od twojej próby i dlaczego druga nie zadziałała.
Uwe Allner
2

Dlaczego nikt jeszcze nie używał pętli foreach? Zaletą jest to, że możesz łatwo nazwać swoją zmienną:

# 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
}
NostraDavid
źródło
jak mogę uzyskać indywidualną ścieżkę do pliku tekstowego bez używania foreach textfile w fileList? coś w rodzaju textfile = $ fileList [$ i] .fullname, wiem, że nie jest to najbardziej optymalne podejście, ale muszę to zrobić w ten sposób :(
Heber Solis
Wystarczy dodać $przed textfile: $textfile = $fileList[$i].FullName. $iTo znaczy, zakładając, że ma wartość liczbową.
NostraDavid
1
gci "C:\WINDOWS\System32" -r -include .txt | select fullname
Vuong Doan
źródło
6
Czy mógłbyś bardziej szczegółowo opisać swoją odpowiedź, dodając więcej opisu rozwiązania, które oferujesz?
abarisone
1

[alternatywna składnia]

Niektórym osobom operatorzy rur kierunkowych nie są w ich guście, ale wolą łańcuchy. Zobacz kilka interesujących opinii na ten temat udostępnionych w narzędziu do śledzenia problemów Roslyn: dotnet / roslyn # 5445 .

W zależności od przypadku i kontekstu, jedno z tych podejść można uznać za ukryte (lub pośrednie). Na przykład w tym przypadku użycie potoku przeciwko enumerable wymaga specjalnego tokena $_(aka PowerShell's "THIS" token) może wydawać się niektórym niesmaczne.

Dla takich gości jest bardziej zwięzły, prosty sposób na zrobienie tego z łańcuchem kropek :

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

(<rant> Zauważ, że PowerShell za argumenty polecenia parser akceptuje częściowe nazwy parametrów Więc oprócz. -recursive; -recursiv, -recursi, -recurs, -recur, -recu, -reci -resą akceptowane, ale niestety nie -r.. który jest jedynym właściwym wyborem, który ma sens z pojedynczego -znaku (jeśli mamy przejdź przez konwencje POSIXy UNIXy)! </rant>)

wulkaniczny kruk
źródło
1
Uwaga do rant: -rkrótka forma -Recurseprac jest dla mnie dobra.
Polymorphix
@Polymorphix, masz rację, działa dla mnie na Windows 10 (nie jestem pewien, którą wersję próbowałem wcześniej). Jednak to samo dotyczy -Fileprzełącznika -fiw przykładzie: -fili -filedziała, ale nie -f. Przechodząc do stylu POSIX, powinno to być --file(wieloliterowe) i -f(jednoliterowe, chyba że -f jest zarezerwowane dla czegoś innego, powiedzmy forceprzełącznik, wtedy może to być coś innego, jak -lopcja jednoliterowa lub nie mieć jej wcale).
vulcan raven
1

Używam poniższego skryptu, aby rozszerzyć całą ścieżkę folderu:

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

Pełna ścieżka folderu nie nadchodzi. Po 113 znakach nadchodzi:

Example - C:\ProgramData\Microsoft\Windows\DeviceMetadataCache\dmrccache\en-US\ec4d5fdd-aa12-400f-83e2-7b0ea6023eb7\Windows...
Ankit Gupta
źródło
0

Użyłem tego polecenia do wyszukania plików „.xlm” w „C: \ Temp”, a wynik wypisuje ścieżkę pełnej nazwy w pliku „result.txt”:

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

W moich testach ta składnia działa pięknie.

Josué Salomão
źródło