【问题标题】:Cmd copy files with filename length longer than 3 charactersCmd 复制文件名长度超过 3 个字符的文件
【发布时间】:2019-11-25 11:21:12
【问题描述】:

我想问你。如何,我可以复制文件名超过 3 个字符的所有文件。我需要批量写。我不知道,它是可制造的,但我在问。

【问题讨论】:

  • 您已将问题发布到一个站点,该站点可帮助您使用您提供的代码解决特定的可复制问题。看来你应该把它贴在别处,也许是Super User。请删除它,或发布您为执行任务而编写的代码并解释它如何无法按预期工作,谢谢。
  • 哪个代码?你读过我的问题吗?
  • 你看我的评论了吗?该站点旨在帮助您解决代码中的问题,如果没有代码,您的问题是关于一般编程的,因此在这里偏离主题。
  • 我需要一个大于 3 的所选目录。 :(
  • 什么是大于 3 的?您能否编辑您的问题并举例说明您想要做什么?

标签: batch-file cmd


【解决方案1】:

以下完整的 应复制当前目录中所有具有至少四个字符的基本名称的可访问文件,(忽略现有或其他扩展名)。这些文件将被复制到当前目录中名为copied 的目录中,(如果它不存在,则会创建它)

@Set "SPO=%__CD__:~2%"
@For /F "Tokens=1*Delims==" %%# In ('^""%__APPDIR__%wbem\WMIC.exe" DataFile Where "Drive='%__CD__:~,2%' And Path='%SPO:\=\\%' And FileName Like '____%%'" Get Name /Format:List 2^>NUL^"')Do @For /F Tokens^=* %%A In ("%%$")Do @"%__APPDIR__%xcopy.exe" "%%A" "%__CD__%copied\" /QHRKY>NUL 2>&1

【讨论】:

    【解决方案2】:

    试试这个:

    @echo off
    
    ::--------------------------------------
    set "source_folder=C:\source\"
    set "dest_folder=.\testfolder\"
    ::--------------------------------------
    
    setlocal enableDelayedExpansion
    
    for %%a in ("%source_folder%\*") do (
      set "filename=%%~nxa"
      rem if you don't want to count the extention too use  set "filename=%%~na"
      call ::strlen filename len
      if !len! GTR 3 (
        copy "%%~fa" "%dest_folder%" /y
      )
    )
    
    
    
    exit /b %errorlevel%
    
    :strlen  StrVar  [RtnVar]
      setlocal EnableDelayedExpansion
      set "s=#!%~1!"
      set "len=0"
      for %%N in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
        if "!s:~%%N,1!" neq "" (
          set /a "len+=%%N"
          set "s=!s:~%%N!"
        )
      )
      endlocal&if "%~2" neq "" (set %~2=%len%) else echo %len%
    exit /b
    

    您需要更改脚本开头的路径。

    【讨论】:

      【解决方案3】:

      文件名(不带扩展名)3 个或更多字符:

      for /f "delims=" %a in ('where /r . "???*.*"') do @echo %~nxa
      

      (命令行语法。要在批处理文件中使用,请使用%%a%%~nxa

      Where 使用通配符 ? 的不同定义(“正好一个字符”)。
      /r 开关定义递归搜索的起始文件夹(此处为当前工作文件夹 (.)。
      where /r 默认返回完整路径。

      【讨论】:

        【解决方案4】:

        这对我有用:

        在此命令中使用源文件/destiny 文件夹的目标路径替换:

        • cd /d "D:\FolderX\"
        • "%temp%\Target_DirX\"

        1) 通过 cd /d 转到文件所在的驱动器和文件夹

        2) 使用 1st 循环通过 dir cmd 列出文件,不包括目录 /a: -d

        3) 使用第二个 for 循环,计算文件名 d:\folder\ name_file_only .docx

        中的字符串

        4) 使用 if 检查文件名是否大于 3,如果为 true,则将文件复制到目标:


        @echo off && cd /d "D:\FolderX\"
        
        for /f tokens^=* %%i in ('dir /s /b /a:-d ".\*.*"')do for /f %%C in ('
        cmd /u/c set /p "'="%%~ni""^<nul^|find /v /c "^^"')do if %%~C gtr 3 (
        copy "%%~fi" "%temp%\Target_DirX\") else echo= %%~nxi less/equal 3^!!
        

        【讨论】:

          【解决方案5】:

          您可以测试名称中的第 4 个字符,如果有,则超过 3 个字符,如果没有,则为 3 个或更少。这个例子只是echos的结果,并没有实际复制它:

              @echo off
              setlocal enabledelayedexpansion
              for %%a in (*) do (
                 set "fname=%%~na"
                 if "!fname:~3,1!" == "" (
                   echo "%%~a" 3 or less chars
                 ) else (
                   echo "%%~a" more than 3 chars
               )
              )
          

          【讨论】:

            【解决方案6】:

            你可以几乎直接这样做,不需要for循环或其他复杂的方法,只需简单的文件globs。 **

            但是,因为? 等于“任何 0 或 1 个字符”,而不是大多数 Windows 命令的“任何一个字符”。因此,您可以轻松地直接选择最多 x 个字符的任何文件。

            如果您想复制然后删除任何事后时间不够长的文件,而无需任何循环或其他过程,则以下方法将起作用。

            在 CLI 上:

            COPY "C:\Source\folder\path\*.*" "C:\Dst\folder\path\"
            DEL /F /Q "C:\Dst\folder\path\???.*"
            

            在批处理文件中稍微有点毛茸茸,因为您可能想用它做更多事情:

            @(SETLOCAL
              ECHO OFF
              SET "_Src_Path=C:\Source\folder\path"
              SET "_Dst_Path="C:\Dst\folder\path"
              SET "_Src_FileGlob=*.*"
              SET "_Dst_FileGlob=???.*"
            )
            
            COPY "%_Src_Path%\%_Src_FileGlob%" "%_Dst_Path%\"
            DEL /F /Q "%_Dst_Path%\%_Dst_FileGlob%"
            

            您可以根据需要使用Robocopy/Move/Dir/Type/Find/FindStr/FOR loops/etc 和File glob

            File GlobsNOT regex,但仍然可以提供相当大的灵活性,让简单的命令能够完成您的请求等任务,而无需编写任何复杂的脚本。

            ** 在 Windows 上,您只能使用文件来表示 glob,并且只能使用静态字符,? 表示“任何零个或一个字符”(这实际上是 ? 的正则表达式)*对于“任意字符任意次数”

            要做到这一点,您就不会复制任何您不想要的文件,并且必须在之后删除它们(这肯定效率较低,尽管如上所述很容易实现,您可以在命令行:

            CLI 作为单行(易于向上箭头并再次运行:

            for /F "Tokens=*" %_ IN ('FOR %A IN (C:\Source\folder\path\???.*^) DO @ECHO.%A ^|FindStr /R /C:"^.*\\[^\\][^\\][^\\][^\\][^\\]*$"') DO ( COPY "%_" "C:\Dst\folder\path\" )
            

            CLI 为多行(更易于阅读,仍然可以粘贴):

            FOR /F "Tokens=*" %_ IN ('
              FOR %A IN (
                C:\Source\folder\path\???.*
              ^) DO @ECHO.%A ^|FindStr /R /C:"^.*\\[^\\][^\\][^\\][^\\][^\\]*$"
            ') DO ( COPY "%_" "C:\Dst\folder\path\" )
            

            在批处理文件中稍微有点毛茸茸,因为您可能想用它做更多事情:

            @(SETLOCAL
              ECHO OFF
              SET "_Src_Path=C:\Source\folder\path"
              SET "_Dst_Path="C:\Dst\folder\path"
              SET "_Src_FileGlob=???*.*"
              SET "_Dst_FileGlob=???.*"
            )
            
            FOR /F "Tokens=*" %%_ IN ('
              FOR %%A IN (
                C:\Source\folder\path\???.*
              ^) DO ECHO.%%A ^|FindStr /R /C:"^.*\\[^\\][^\\][^\\][^\\][^\\]*$"
            ') DO ( COPY "%%_" "C:\Dst\folder\path\" )
            

            另外,正如 Compo 所指出的,只有 Where 符合预期的行为:

            在 CLI 中:

            for /F "Tokens=*" %_ IN ('WHERE "C:\Source\folder\path:????.*"') DO ( COPY "%_" "C:\Dst\folder\path\" )
            

            在一个简单的脚本中:

            @(SETLOCAL
              ECHO OFF
              SET "_Src_Path=C:\Source\folder\path"
              SET "_Dst_Path="C:\Dst\folder\path"
              SET "_Src_FileGlob=????*.*"
            )
            
            for /F "Tokens=*" %_ IN ('
              WHERE "%_Src_Path%:%_Src_FileGlob%"
            ') DO ( COPY "%_" "%_Dst_Path%\" )
            

            【讨论】:

            • Ben,您的 copy 'Glob',将匹配名为 1.ca.h 且不符合条件的文件,即使包含扩展名!
            • 遗憾的是,通配符? 表示“零个或一个字符”(where 命令除外)
            • @Compo 和 @Stephan,很好,我在以前的用法中没有注意到它是 0 或 1 个字符,所以 ? = 实际正则表达式 ? 不是正则表达式 . 而 @ 987654352@ 仍为 .* 感谢您的说明,我已对其进行了修改。
            猜你喜欢
            • 1970-01-01
            • 2018-02-01
            • 2016-01-18
            • 1970-01-01
            • 2011-05-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多