Obter o caminho completo dos arquivos no PowerShell

146

Preciso obter todos os arquivos, incluindo os presentes nas subpastas que pertencem a um tipo específico.

Estou fazendo algo parecido com isto, usando Get-ChildItem :

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

No entanto, ele está apenas retornando os nomes dos arquivos e não o caminho inteiro.

Gagan
fonte

Respostas:

220

Adicione | select FullNameno final da sua linha acima. Se você realmente precisar fazer algo com isso posteriormente, talvez seja necessário inseri-lo em um loop foreach, da seguinte maneira:

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

Isso deve ter um desempenho muito mais rápido do que usar a filtragem tardia:

Get-ChildItem C:\WINDOWS\System32 -Filter *.txt -Recurse | % { $_.FullName }
Shay Levy
fonte
14
Isso é verdade. Uma ressalva: esse comando realmente obtém arquivos como *.txt*( -Filterusa curingas CMD). Se não é isso que você deseja, use -Include *.txt.
Roman Kuzmin
26

Você também pode usar Select-Object da seguinte maneira:

Get-ChildItem "C:\WINDOWS\System32" *.txt -Recurse | Select-Object FullName
imlokesh
fonte
5
Observe que Select-Objectretorna PSCustomObject, não uma sequência. Talvez não funcione se você usar o resultado como parâmetro para outro programa
Chintsu
5
Sim ao que o @Chintsu disse. Para obter strings em vez de PSCustomObject, use em -ExpandProperty FullNamevez de simplesmente FullName. Pelo que entendi, o -ExpandPropertyparâmetro faz com que o cmdlet retorne os resultados como o tipo de propriedade especificado (nativo?), Em vez de como um objeto personalizado.
doubleDown 22/02
Eu também precisava de tempo (mexi com a fonte de um programa e pensei mais tarde que provavelmente deveria ter iniciado o controle de fonte, mas posso ter uma idéia do meu primeiro commit contra o "mestre", obtendo arquivos desde a instalação:Get-ChildItem -Path 'C:\Program Files\TheProgram' -Recurse | Where-Object -FilterScript {($_.LastWriteTime -gt '2020-03-01')} | Select-Object FullName
Neil Guy Lindberg
19

Aqui está um mais curto:

(Get-ChildItem C:\MYDIRECTORY -Recurse).fullname > filename.txt
JustAGuy
fonte
23
Aqui está um mais curto:(gci -r c:\).fullname
Chris N
11
Aqui está um mais curto:(ls -r c:\).fullname
Kalamane
15
Aqui está uma mais curta:(ls -r c:).fullname
Valiante
9

Se os caminhos relativos forem o que você deseja, basta usar o -Namesinalizador.

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

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

Isso é o que eu usei. Eu sinto que é mais compreensível, pois não contém nenhuma sintaxe de loop.

Mandrágora
fonte
5

Coisa realmente irritante no PS 5, onde $ _ não será o caminho completo dentro do foreach. Essas são as versões de string dos objetos FileInfo e DirectoryInfo. Por algum motivo, um curinga no caminho o corrige ou use o PowerShell 6 ou 7. Você também pode canalizar para obter o item no meio.

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

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

Parece ter sido um problema com o .Net que foi resolvido no .Net Core (Powershell 7): O comportamento de stringification das instâncias FileInfo / Directory mudou desde a v6.0.2 # 7132

js2010
fonte
4

Isso funcionou para mim e produz uma lista de nomes:

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

Eu achei isso usando get-member -membertype properties, um comando incrivelmente útil. a maioria das opções que você fornece é anexada com um .<thing>, como fullnameestá aqui. Você pode manter o mesmo comando;

  | get-member -membertype properties 

no final de qualquer comando, para obter mais informações sobre o que você pode fazer com eles e como acessá-los:

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

Tente o seguinte:

Get-ChildItem C:\windows\System32 -Include *.txt -Recurse | select -ExpandProperty FullName
Mykhailo Basiuk
fonte
2
Adicione um pouco de informação sobre o que é diferente com sua tentativa e por que o outro não funcionou.
precisa saber é o seguinte
2

Por que ninguém usou o loop foreach ainda? Um profissional aqui é que você pode facilmente nomear sua variável:

# 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
fonte
como posso obter o caminho do arquivo individual de um arquivo de texto sem usar o foreach em fileList? algo como textfile = $ fileList [$ i] .fullname, eu sei que não é a abordagem mais ideal, mas preciso fazer desta maneira :(
Heber Solis
Basta adicionar um $em frente textfile: $textfile = $fileList[$i].FullName. Supondo que $itenha um valor numérico, ou seja.
NostraDavid 5/06
1
gci "C:\WINDOWS\System32" -r -include .txt | select fullname
Vuong Doan
fonte
6
Você poderia elaborar mais sua resposta adicionando um pouco mais de descrição sobre a solução que você fornece?
Abarisone
1

[sintaxe alternativa]

Para algumas pessoas, os operadores de tubos direcionais não são do seu gosto, mas preferem encadear. Veja algumas opiniões interessantes sobre esse tópico compartilhadas no roslyn issue tracker: dotnet / roslyn # 5445 .

Com base no caso e no contexto, uma dessas abordagens pode ser considerada implícita (ou indireta). Por exemplo, nesse caso, o uso de pipe contra enumerável requer um token especial $_(aka PowerShell's "THIS" token) pode parecer desagradável para alguns.

Para esses tipos, aqui está uma maneira mais concisa e direta de fazer isso com encadeamento de pontos :

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

(<rant> Note que parser argumentos do comando do PowerShell aceita os nomes dos parâmetros parciais Assim, além de. -recursive; -recursiv, -recursi, -recurs, -recur, -recu, -rece -resão aceitos, mas infelizmente não -r.. que é a única escolha correta que faz sentido com um único -caractere (se siga as convenções do POSIXy UNIXy)! </rant>)

corvo vulcano
fonte
1
Nota para o discurso retórico: a -rforma abreviada de -Recursefunciona bem para mim.
Polymorphix
@ Polymorphix, você está certo, está funcionando para mim no Windows 10 (não tenho certeza de qual versão eu estava tentando anteriormente). No entanto, o mesmo vale para o -Fileswitch -fida amostra: -file -filefunciona, mas não -f. Seguindo o estilo POSIX, deve ser --file(várias letras) e -f(uma letra), a menos que -f seja reservado para outra coisa, digamos forceswitch, então pode ser outra coisa parecida -lou nenhuma opção de letra única).
quer
1

Estou usando o script abaixo para extrair todo o caminho da pasta:

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

O caminho completo da pasta não está chegando. Após 113 caracteres, está chegando:

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

Eu usei este comando de linha para pesquisar arquivos ".xlm" em "C: \ Temp" e o resultado imprime o caminho do nome completo no arquivo "result.txt":

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

Nos meus testes, essa sintaxe funciona muito bem para mim.

Josué Salomão
fonte