Copy file names from one folder to another while keeping the original extensions

橙三吉。 提交于 2019-12-07 03:29:30

It sounds like you want to rename files in a target directory positionally, based on corresponding files in a source directory - while retaining the target directory files' extensions:

$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 }
  • To preview the resulting filenames, append -WhatIf to to the Rename-Item call.

  • The .BaseName property of the [System.IO.FileInfo] objects output by Get-ChildItem returns the file-name portion without the extension.

  • $_.Extension extracts the input file's (i.e., the target file's) existing extension, including the leading .

  • Note that the script block ({ ... }) passed to Rename-Item creates a child variable scope, so you cannot increment a variable in the caller's scope directly (it would create a new copy of such a variable with the original value every time); therefore, a [ref] instance is created to indirectly hold the number, which the child scope can then modify via the .Value property.


Here's a complete example:

Note: While this example uses similar file names and uniform extensions, the code works generically, with any names and extensions.

# 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

The above yields:

--- 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

Note how the target files now have the source files' base file names (s-file*), but the target files' original extensions (.target-ext).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!