Script para varrer vários diretórios, procurar por um arquivo e copiá-lo para um novo nome

1

Espero que alguém possa me ajudar aqui. Eu preciso limpar alguns dados em um intervalo regular, mas curto de fazê-lo manualmente eu não encontrei uma boa solução.

Aqui está o fluxo que eu passo manualmente.

Eu tenho uma pasta de nível superior chamada "Data", sob ela tenho várias pastas, cerca de 100 que vêm e vão. Sob cada um desses, existe um arquivo chamado folder.jpg. Há também subpastas nesse diretório, mas preciso parar no nível raiz.

O ideal seria procurar em cada pasta e verificar se há um arquivo chamado show.jpg, se ignorar a pasta e seguir em frente. Se não, procure na mesma pasta por um arquivo chamado folder.jpg e copie-o para um novo arquivo chamado show.jpg.

Parece fácil em minha mente.

    
por JoshFink 08.10.2014 / 20:44

1 resposta

2

Aqui está um script que deve funcionar no PowerShell, mas ainda não testei. Isso pressupõe que sua pasta Data esteja na raiz de C:.

Get-ChildItem C:\Data\*\* | Where-Object {$_.Name -eq 'folder.jpg'} | ForEach-Object {
    $CurrentFolder = $_.Directory
    if ((Test-Path "$CurrentFolder\show.jpg") -eq $false)
    {Copy-Item $_ "$CurrentFolder\show.jpg"}
    Remove-Variable CurrentFolder
}

Divisão:

O parâmetro dado a Get-ChildItem diz para retornar todos os objetos que estão separados de C: \ Data por um nível de pasta abaixo.

Where-Object é usado para filtrar esses resultados para apenas arquivos nomeados folder.jpg.

ForEach-Object é usado para percorrer os resultados restantes.

Para processar cada pasta.jpg, primeiro definimos uma variável ( $CurrentFolder ) para conter o valor do caminho da pasta.

Em seguida, usamos Test-Path para ver se show.jpg está faltando na mesma pasta.

Se show.jpg não for encontrado, Copy-Item copiará folder.jpg para show.jpg.

Limpar a variável $CurrentFolder com Remove-Variable é estritamente opcional, mas é uma boa prática.

O script provavelmente também pode ser reduzido para isso, se você estiver procurando por um "one-liner":

ls C:\Data\*\*|?{$_.Name -eq 'folder.jpg'}|%{$c=$_.Directory;if(!(Test-Path "$c\show.jpg")){cp $_ "$c\show.jpg"}}

ls é um alias interno para Get-ChildItem

? é um alias interno para Where-Object

% é um alias interno para ForEach-Object

$CurrentFolder foi reduzido para $c

O resultado de Test-Path "$c\show.jpg" foi negado (ou seja, TRUE será FALSE e vice-versa) encapsulando em !() . Se uma expressão for avaliada diretamente para um booleano e você quiser que um bloco de código seja executado em TRUE, não será necessário incluir -eq $true na instrução if .

cp é um alias interno para Copy-Item

Remove-Variable foi omitido. (Embora você possa usar o alias interno rv , se quiser.)

    
por 08.10.2014 / 21:29