【问题标题】:Batch rename files in subfolders to parent folder name将子文件夹中的文件批量重命名为父文件夹名称
【发布时间】:2020-08-11 09:09:41
【问题描述】:

所以我正在编写一个批处理脚本来将子文件夹中的 CSV 文件重命名为与其父文件夹相同的名称。例如,文件R:\Royal Mail\Results\202008101416151232.rm\results.csv 将变为R:\Royal Mail\Results\202008101416151232.rm\202008101416151232.rm.csv。每个文件夹中只有一个 CSV。

完成后,文件将向上移动一个目录,以便另一个软件可以处理它。我已经完成了这项工作,但问题是它当前重命名了主文件夹和子目录中的文件。例如,它会将R:\Royal Mail\Results\202008101416151232.rm.csv 重命名为R:\Royal Mail\Results\Results.csv

这是我目前的代码:

@echo off

set folder="\\rackstation\Couriers\Royal Mail\Results"

rem Rename CSV files to parent folder name
for /r %folder% %%D in (.) do (
  for /f "delims=" %%F in ('dir /b /A:-D "%%D"') do ren "%%D\%%F" "%%~nxD%%~xF"
  echo %%D
)

rem Move CSV files to previous folder
FOR /R %folder% %%i IN (*.csv) DO MOVE "%%i" %folder%

rem Deletes empty folders
for /f "delims=" %%i in ('dir %folder% /s /b /ad ^| sort /r') do rd "%%i"

我已经尝试了几件事,但没有设法添加一个 if 条件来说明如果 %%D = "\\rackstation\Couriers\Royal Mail\Results" 则不要重命名文件。

任何人都可以修改这个脚本来做到这一点吗?

【问题讨论】:

    标签: batch-file cmd


    【解决方案1】:

    如果一个目录中有多个 .csv 文件,此 PowerShell 脚本将完成此操作并显示警告。如果您对文件将被正确移动和重命名感到满意,请从 Move-Item 命令中删除 -WhatIf

    Get-ChildItem -Directory -Path 'C:\src\t\Royal Mail\Results' |
        ForEach-Object {
            $FileToMove = Get-ChildItem -File -Path $_.FullName -Filter '*.csv'
            if ($FileToMove.Count -eq 1) {
                $NewBaseName = Split-Path -Path $_.FullName -Leaf
                Move-Item -Path $FileToMove.FullName `
                    -Destination (Join-Path -Path $_.Parent -ChildPath "$NewBaseName.csv") -WhatIf
            } else {
                Write-Warning "Directory $($_.FullName) contins multiple .csv files."
            }
        }
    

    如果您无法使用 PowerShell 控制台,请将上述脚本保存在文件 Move-RoyalMailFiles.ps1 中,然后在 cmd.exe 或 .bat 文件脚本中运行:

    powershell -NoLogo -NoProfile -File 'Move-RoyalMailFiles.ps1"
    

    【讨论】:

      【解决方案2】:

      以下方法应该只对仅包含一个 CSV 文件的任何子目录执行该任务,因此如果出于某种原因您有一个包含其中两个文件的子目录,则无需担心。它使用Dir 处理目录名称,以便在处理文件之前完成目录解析。这可确保重命名和移动的文件不会被回收回循环中。如果只有一个 CSV 文件,则无需知道其名称,只需使用 glob *.csv 进行移动和重命名操作,如果该操作成功,请尝试删除目录 (只有现在为空才会成功).

      @Echo Off
      SetLocal EnableExtensions DisableDelayedExpansion
      
      Set "folder=\\rackstation\Couriers\Royal Mail\Results"
      
      For /F Delims^=? %%D In (
          'Dir /B/S/A:D-S-L "%folder%"'
      )Do (
          Set "_="
          For /F "Skip=6Tokens=3" %%C In (
              '""%__AppDir__%Robocopy.exe" "%%D" Null "*.csv" /L /NFL /NDL /NJH"'
          )Do If "%%C"=="1" If Not Defined _ (
              Set "_=T"
              Move /Y "%%D\*.csv" "%%D\..\%%~nxD.csv"&&RD "%%D" 2>NUL
          )
      )
      Pause
      
      GoTo :EOF
      

      您也可以使用PushD 来确保您从一开始就位于源文件夹中,只有在您完成后才返回。

      @Echo Off
      SetLocal EnableExtensions DisableDelayedExpansion
      
      Set "folder=\\rackstation\Couriers\Royal Mail\Results"
      
      PushD "%folder%" 2>NUL||GoTo :EOF
      For /F Delims^=? %%D In (
          'Dir /B/S/A:D-S-L'
      )Do (
          Set "_="
          For /F "Skip=6Tokens=3" %%C In (
              '""%__AppDir__%Robocopy.exe" "%%D" Null "*.csv" /L /NFL /NDL /NJH"'
          )Do If "%%C"=="1" If Not Defined _ (
              Set "_=T"
              Move /Y "%%D\*.csv" "%%D\..\%%~nxD.csv"&&RD "%%D" 2>NUL
          )
      )
      PopD
      Pause
      
      GoTo :EOF
      

      请注意,我没有考虑到脚本的任何后续运行都可能将同一文件移动和重命名到另一个级别。为了处理这些事情,我需要了解更多关于您的特定树结构和命名模式的信息,然后再考虑哪个可能是最好的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-21
        • 2016-09-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-04
        相关资源
        最近更新 更多