windows - Kopier filnavne fra en mappe til en anden, mens du beholder de oprindelige udvidelser

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har brug for hjælp til at kopiere filen navne (ikke filerne selv) fra C-drev til D-drev. Jeg kunne finde følgende powershell kode online:


$names = @()
$getPath = "C:MyFiles"
$setPath = "D:MyFiles"
Get-ChildItem $getPath |
    Foreach-object{
    $names += $\_
}
$i = 0
Get-ChildItem $setPath |
Foreach-object{
    Rename-Item -Path $\_.FullName -NewName $names[$i]
    $i++
}


Denne kode omdøber/kopierer alle filnavne fra C:MyFiles til D:MyFiles, strengt ved tilsvarende stillinger (indekser i opgørelsen).


Det opdaterer dog også udvidelser , for eksempel:


C:MyFilesmyfile.txt omdanner D:MyFiles hisfile.docx til D:MyFilesmyfile.txt


Er der en måde at redigere Powershell-koden på, så den kun omdøber base for filnavnet (f.eks. myFile), mens målfilerne ' extensions .docx)?


Så at C:MyFilesmyfile.txt omdanner D:MyFiles hisfile.docx til D:MyFilesmyfile.docx ved hjælp af

Bedste reference


Det lyder som om du vil omdøbe filer i en målkatalog positionelt , baseret på tilsvarende filer i en kildekatalog - samtidig med at du behåller målkatalogfilerne 'udvidelser:


$getPath = "C:MyFiles"
$setPath = "D:MyFiles"
$sourceFiles = Get-ChildItem -File $getPath

$iRef = [ref] 0
Get-ChildItem -File $setPath | 
  Rename-Item -NewName { $sourceFiles[$iRef.Value++].BaseName + $\_.Extension }



  • Til forhåndsvisning de resulterende filnavne, tilføj -WhatIf til til Rename-Item opkaldet.

  • Ejendommen .BaseName af [System.IO.FileInfo] objekter udgivet af Get-ChildItem returnerer filnavnet-porten uden udvidelsen.

  • $\_.Extension ekstrakter inputfilen s (dvs. målfilen) s eksisterende udvidelse, herunder den førende .

  • Bemærk, at scriptblokken ({ ... }), der sendes til Rename-Item opretter et barn variabelt omfang, så du ikke kan øge en variabel i opkalderens anvendelsesområde direkte (det ville skabe en ny kopi af en sådan variabel med den oprindelige værdi hver gang); derfor oprettes en [ref] instans til indirekte holde nummeret, som Barnets omfang kan derefter ændres via egenskaben .Value.






Her er et komplet eksempel :


Bemærk: Mens dette eksempel bruger lignende filnavne og ensartede udvidelser, fungerer koden generisk med nogen navne og udvidelser.


# Determine the temporary paths.
$getPath = Join-Path ([System.IO.Path]::GetTempPath()) ('Get' + $PID)
$setPath = Join-Path ([System.IO.Path]::GetTempPath())  ('Set' + $PID)

# Create the temp. directories.
$null = New-Item -ItemType Directory -Force $getPath, $setPath

# Fill the directories with files.

# Source files: "s-file{n}.source-ext"
"--- Source files:"
1..3 | \% { New-Item -ItemType File (Join-Path $getPath ('s-file{0}.source-ext' -f $\_)) } | 
  Select -Expand Name

# Target files: "t-file{n}.target-ext"
"
---- Target files:"
1..3 | \% { New-Item -ItemType File (Join-Path $setPath ('t-file{0}.target-ext' -f $\_)) } | 
  Select -Expand Name

# Get all source names.
$sourceFiles = Get-ChildItem -File $getPath

# Perform the renaming, using the source file names, but keeping the
# target files' extensions.
$i = 0; $iVar = Get-Variable -Name i
Get-ChildItem -File $setPath | 
  Rename-Item -NewName { $sourceFiles[$iVar.Value++].BaseName + $\_.Extension }

"
---- Target files AFTER RENAMING:"

Get-ChildItem -Name $setPath

# Clean up.
Remove-Item -Recurse $getPath, $setPath


Ovennævnte udbytter:


--- Source files:
s-file1.source-ext
s-file2.source-ext
s-file3.source-ext

---- Target files:
t-file1.target-ext
t-file2.target-ext
t-file3.target-ext

---- Target files AFTER RENAMING:
s-file1.target-ext
s-file2.target-ext
s-file3.target-ext


Bemærk, hvordan målfilerne nu har kildefilerne 'base filnavne' (s-file*), men målfilerne 'originale udvidelser' .target-ext).