PowerShell: renomeia / exclui arquivos em uma pasta que pode aparecer em locais diferentes na hierarquia de arquivos

1

Atualmente, estamos tentando descobrir uma maneira de renomear arquivos PDF em uma determinada pasta ( /root ) que estão direta ou indiretamente dentro de uma pasta purchases que está direta ou indiretamente dentro da pasta /root . Eu gostaria de conseguir isso com o PowerShell, mas não posso ir além dos exemplos que encontrei nos vários tópicos que estão por aí.

Por exemplo, com essa estrutura de diretório:

/root/<subfolder1>/purchases/invoice1.pdf
/root/<subfolder1>/order.pdf
/root/<subfolder2>/purchases/invoice2.pdf

A intenção é apenas renomear ou excluir os arquivos PDF que residem nas pastas "compras". Os arquivos PDF em qualquer outra pasta não devem ser tocados.

Os nomes <subfolderX> são desconhecidos (ou seja, podem ser qualquer coisa, por exemplo, "a" ou "b").

O script precisa percorrer todas as pastas de forma recursiva.

Qualquer orientação para alcançar isso seria apreciada.

    
por loewie1984 17.09.2018 / 15:28

3 respostas

2

Resposta curta

Para exibir os nomes dos arquivos PDF direta ou indiretamente contidos em um subdiretório direto ou indireto de d:\root denominado purchases , você pode usar:

gci -Directory -Recurse d:\root\purchases | % { gci -Recurse "$_\*.pdf" } | % FullName

Breve explicação: o comando recursivamente localiza todos os subdiretórios diretos e indiretos de d:\root denominado purchases , depois recursivamente localiza todos os arquivos PDF em cada um desses subdiretórios e retorna o caminho completo de cada um desses arquivos PDF.

Outros casos de uso

Para remover esses arquivos PDF:

gci -Directory -Recurse d:\root\purchases | % { gci -Recurse "$_\*.pdf" } | ri

Para renomear esses arquivos PDF (por exemplo, adicionando um prefixo e um sufixo ao nome base):

gci -Directory -Recurse d:\root\purchases | % { gci -Recurse "$_\*.pdf" } | % { rni $_ "pref-$($_.BaseName)-suff.pdf" }

Para remover os diretórios purchases juntamente com todo o conteúdo:

gci -Directory -Recurse d:\root\purchases | ri -Recurse

Explicação detalhada

  • gci é um alias para Get-ChildItem .
  • gci -Directory -Recurse d:\root\purchases retorna todos os diretórios ( -Directory ) cujo nome é purchases que são subpastas diretas ou indiretas ( -Recurse ) de d:\root\ . Em outras palavras, ele retornaria d:\root\purchases (se existisse), bem como d:\root\b\c\purchases e d:\root\a\purchases . Isso não é muito intuitivo e não parece ser explicado no documentação , mas é o comportamento atual (a partir do PowerShell 6).
  • % é um alias para ForEach-Object . Ele executa um bloco de script (entre chaves ( {} ) para cada objeto no pipeline.
  • gci -Recurse "$_\*.pdf" recupera a lista de arquivos PDF que estão (direta ou indiretamente) contidos nos diretórios purchases encontrados anteriormente.
  • % FullName é usado apenas para exibir o caminho desses arquivos PDF.
  • ri é um alias para Remove-Item . Ele remove a lista de arquivos PDF anteriormente calculada (porque o parâmetro -Path do comando Remove-Item aceita entrada de pipeline).
  • ri -Recurse permite remover a lista de diretórios purchases anteriormente computados, juntamente com o conteúdo deles.
  • rni $_ "pref-$($_.BaseName)-suff.pdf" adiciona um prefixo ( pref- ) e um sufixo ( -suff ) ao nome base $_.BaseName do arquivo atual no pipeline (por exemplo, cada um dos arquivos PDF que estamos procurando). O nome base de um arquivo é o nome do arquivo sem sua extensão e rni é um alias para Renomear-Item .

Testando esta solução (online ou localmente)

O mais fácil é para tentar esta solução online .

Caso contrário, você pode criar uma estrutura de diretório de exemplo em uma test pasta do diretório de trabalho atual , com o seguinte trecho ( tenha cuidado : altere .\test para outra coisa se você já tiver uma pasta test no diretório atual):

mkdir -ErrorAction SilentlyContinue .\test\a\purchases, .\test\a\e\, .\test\b\c\purchases\
Out-File .\test\a\purchases\invoice1.pdf
Out-File .\test\a\order1.pdf
Out-File .\test\a\e\order2.pdf
Out-File .\test\b\c\purchases\invoice2.pdf
Out-File .\test\b\c\purchases\invoice3.pdf

Para visualizar todos os arquivos nessa estrutura de diretório, você pode usar:

gci -Recurse -File .\test | % FullName

Qual seria o retorno de algo como:

D:\test\a\order1.pdf
D:\test\a\e\order2.pdf
D:\test\a\purchases\prefix-invoice1-suffix.pdf
D:\test\b\c\purchases\prefix-invoice2-suffix.pdf
D:\test\b\c\purchases\prefix-invoice3-suffix.pdf

(Onde D: é substituído pelo seu diretório de trabalho atual.)

Executar o comando fornecido como resposta ( gci -Directory -Recurse .\test\purchases | % { gci -Recurse "$_\*.pdf" } | % FullName ) exibirá os arquivos que precisam ser removidos ou excluídos:

D:\test\a\purchases\invoice1.pdf
D:\test\b\c\purchases\invoice2.pdf
D:\test\b\c\purchases\invoice3.pdf

Para limpar após o seu teste:

rm -Recurse .\test
    
por 17.09.2018 / 17:49
1

Youssef Abidi deu-lhe uma resposta visando uma única unidade, mas parece que você está dizendo que o caminho da pasta para. \ compras, é desconhecido?

No entanto, a regra do fórum é que você deve fornecer o que você tentou e os erros que encontrou para mostrar a sua meta final, e não nos fazer adivinhar, e como a maioria diria 'faça o seu trabalho para você '. As pessoas aqui são muito úteis, mas, bem, você sabe.

Tudo isso dito, se minha suposição estiver correta. Essencialmente, faça um filtro para a pasta de compras em qualquer unidade do host e, em seguida, o arquivo PDF nessa pasta e faça o que você quiser.

É realmente apenas um comando de uma linha de pipeline - se o acima for uma suposição válida

(Get-PSDrive).Root -like '*:\' | 
% { (Get-ChildItem -Path ((Get-ChildItem -Path $_ -recurse -Filter Purchases -Directory -ErrorAction SilentlyContinue).FullName) -Filter '*.pdf' -Verbose).FullName }

# Results

C:\purchases\powershell-cheat-sheet.pdf
C:\purchases\PSPunctuationWallChart_1_0_4.pdf
D:\Temp\purchases\powershell-cheat-sheet.pdf
D:\Temp\purchases\PSPunctuationWallChart_1_0_4.pdf

Claro que você pode dividir essa frase em algo diferente.

    
por 18.09.2018 / 09:03
0

Concordo em fazer meu dever de casa é essencial para a comunidade. Eu descobri tanto com o gci quanto com o filtro, mas não consegui improvisar a parte do gci duplo entre aspas.

Faremos o meu melhor para a minha próxima pergunta para mostrar alguns esforços. Independentemente de ambas as suas respostas me ajudaram a resolver este problema.

Então, novamente, muito obrigado!

    
por 19.09.2018 / 21:39