标题: [文件操作] 【已解决】批处理以数字为分隔符 取左边文本构建文件夹,并移动文件。 [打印本页]
作者: zhengzhenhui 时间: 2024-7-21 03:23 标题: 【已解决】批处理以数字为分隔符 取左边文本构建文件夹,并移动文件。
比如 语文12-五年-六班-1208
语文23-五年-三班-1231
数学12-五年-三班-1231
只取数字最左侧的文字的内容 并新建文件夹移入
文件夹【语文】—— 语文12-五年-六班-1208
—— 语文23-五年-三班-1231
文件夹【数学】——数学12-五年-三班-1231
作者: czjt1234 时间: 2024-7-21 05:49
目测把
dir /b /a-d *[0-9]*
改成
dir /b /a-d *.*
作者: aloha20200628 时间: 2024-7-21 09:52
本帖最后由 aloha20200628 于 2024-7-21 14:19 编辑
回复 1# zhengzhenhui
第一段代码至少有如下错误》
一。使用延迟变量!var!须开启setlocal enabledelayedexpansion,仅setlocal不够
二。"[0-9]*" 是用于findstr的正则表达式,dir只能用其作为字面量
三。用 delims=0123456789 分割后提取的%%a%%b已经丢失了中间的数值字段
调整第一段代码如下...
- @echo off
- for /f "delims=" %%F in (
- ' dir /b/a-d^|findstr /rb "[^0-9\.]*[0-9]" ') do for /f "tokens=1* delims=0123456789" %%a in ("%%~nF") do (
- if not exist "【%%a】\" md "【%%a】\"
- move /y "%%F" "【%%a】\"
- )
- pause&exit/b
复制代码
作者: binghejin 时间: 2024-7-21 13:21
本帖最后由 binghejin 于 2024-7-21 13:23 编辑
如果确保每个文件的课程都是2个字,比如:语文、数学、美术等等的话,那么以下代码应该可行,代码中我并没有进行任何复制、移动、删除的操作,所以可以放心测试,一旦测试通过,那么稍作改动即可!- @echo off
- setlocal enabledelayedexpansion
- rem 下面一行修改你的文件后缀名
- set "hz=txt"
- cls
- for /f %%a in ('dir *.%hz% /b') do (
- set line=%%a
- for /f "tokens=1 delims=-" %%b in ("!line:~0,2!") do echo 完整文件名:!line!,准备新建的文件夹为:%%b
- )
- pause
复制代码
作者: zhengzhenhui 时间: 2024-7-21 16:21
回复 4# binghejin
字数不固定,但是规律都是文字和数字后缀
作者: zhengzhenhui 时间: 2024-7-21 16:24
这个是我目前解决办法,字符-为锚点取左边的文字,语文1 这样文件夹就会是语文
但是只能个位数。。。。主要是想以出现的第一个数字,取左侧文本作为文件夹并移入- @echo off
- cd /d "%~dp0"
-
- setlocal enabledelayedexpansion
-
- for /f "delims=" %%D in ('dir /ad /b /s') do (
- pushd "%%D"
- for /f "delims=" %%i in ('dir /b /a-d "*-*"') do (
- set "filename=%%i"
- set "folderName="
- for /f "tokens=1* delims=-" %%a in ("!filename!") do (
- set "folderName=%%a"
- set "folderName=!folderName:~0,-1!" // 新增这一行,去除数字部分
- if not exist "!folderName!" (
- md "!folderName!"
- )
- move "%%i" "!folderName!"
- )
- )
- popd
- )
-
- endlocal
- pause
复制代码
作者: 77七 时间: 2024-7-21 16:37
本帖最后由 77七 于 2024-7-21 16:47 编辑
ai写的有时候错的离谱,不要学习。可以稍加修改后使用。
- @echo off
- setlocal enabledelayedexpansion
-
- for /f "tokens=1* delims=0123456789" %%a in ('dir /b /a-d ^|find /v "%~nx0"') do (
- set "folderName=%%a"
- if not exist "!folderName!\" (
- md "!folderName!\"
- )
- move "%%a*%%b" "!folderName!\" 2>nul
- )
-
- echo Files have been moved to their respective folders.
- pause
- endlocal
复制代码
说明下,不要出现 北京、北京西,这样的文件名。
作者: zhengzhenhui 时间: 2024-7-21 17:03
本帖最后由 zhengzhenhui 于 2024-7-21 17:37 编辑
回复 7# 77七
你这个是当前目录的,应用于子目录里面的文件 刚刚试试了没改成功 能改一下不 【测试过了重叠字是没有移入文件夹】
【】
作者: aloha20200628 时间: 2024-7-21 17:22
回复 1# zhengzhenhui
还要处理子目录,可试试以下版本...
- @echo off
- for /f "delims=" %%F in (
- ' dir /b/s/a-d^|findstr /rb "[^0-9\.]*[0-9]" ') do for /f "tokens=1* delims=0123456789" %%a in ("%%~nF") do (
- if not exist "【%%a】\" md "【%%a】\"
- move /y "%%F" "【%%a】\"
- )
- pause&exit/b
复制代码
作者: 77七 时间: 2024-7-21 17:42
回复 8# zhengzhenhui
9楼与本楼所创建文件夹路径不同,楼主根据实际需要自行选用。- @echo off
- cd /d "%~dp0"
- for /f "delims=" %%i in ('dir /b /s /a-d ^|find /v "%~f0"') do (
- for /f "delims=0123456789" %%a in ("%%~ni") do (
- md "%%~dpi\%%a" 2>nul
- move "%%i" "%%~dpi\%%a\"
- )
- )
- pause
复制代码
作者: zhengzhenhui 时间: 2024-7-21 17:46
感谢77七提供的代码,已经解决- @echo off
- setlocal enabledelayedexpansion
-
- :: 定义一个变量来跟踪已经创建的文件夹
- set "createdFolders="
-
- :: 定义递归遍历子目录的函数
- call :processDirectory "%cd%"
- goto :eof
-
- :processDirectory
- pushd "%~1"
-
- :: 如果不是根目录,则遍历当前目录下的所有文件
- if not "%~1"=="%cd%" (
- for /f "tokens=1* delims=0123456789" %%a in ('dir /b /a-d ^| find /v "%~nx0"') do (
- set "folderName=%%a"
- set "folderPath=!folderName!\"
-
- :: 检查文件夹是否已经创建
- echo !createdFolders! | find /i "!folderName!" >nul
- if errorlevel 1 (
- :: 文件夹未创建,创建文件夹
- if not exist "!folderPath!" (
- md "!folderPath!"
- :: 将已创建的文件夹添加到跟踪变量中
- set "createdFolders=!createdFolders! !folderName!"
- )
- )
-
- :: 移动文件到文件夹
- move "%%a*%%b" "!folderPath!" 2>nul
- )
- )
-
- :: 遍历当前目录下的所有子目录,并递归调用自身
- for /d %%D in (*) do (
- call :processDirectory "%%D"
- )
-
- :: 返回到上一级目录
- popd
- goto :eof
-
- :eof
- echo Files have been moved to their respective folders in subdirectories.
- pause
- endlocal
复制代码
作者: aloha20200628 时间: 2024-7-21 21:19
本帖最后由 aloha20200628 于 2024-7-21 22:25 编辑
回复 1# zhengzhenhui
本帖的题型若是》
在当前目录包括其各子目录中匹配出全部文件名结构为 “非数值字段+数值字段+*.扩展名” (如 “语文12-五年-六班-1208.txt”)的目标文件
并将其转移至当前目录下每个对应的 “【非数值字段】” 子目录中
以下给出一个尽量简化的版本,代码存为 test.bat 在当前目录下运行
自动排除当前目录中的批处文件,自动排除 ‘只有非数值字段’ 或 ‘只有数值字段’ 的不合规文件名...
- @echo off
- for /f "delims=" %%F in ('dir /b/s/a-d') do if /i "%%~xF" neq ".bat" (
- for /f "tokens=1 delims=0123456789" %%a in ("%%~nF") do if /i "%%~nF" neq "%%a" (
- if not exist "【%%a】\" md "【%%a】\"
- move /y "%%F" "【%%a】\"
- )
- )
- pause&exit/b
复制代码
作者: zhengzhenhui 时间: 2024-7-22 00:20
回复 12# aloha20200628
简短且精悍
作者: qixiaobin0715 时间: 2024-7-22 09:22
本帖最后由 qixiaobin0715 于 2024-7-22 11:38 编辑
1.实际上cmd中的findstr命令字符搜索表达式,通常叫做一般表达式,与正统的Regular Expressions区别还是很大的。
2.正则表达式或者在这里的一般表达式,还是存在着许多坑等着我们去跳的,比如3楼代码中的表达式“findstr /rb "[^0-9\.]*[0-9]"”,我想是要表达字符串的开头不能是数字或.号,后面必须存在数字字符。实际上在方括号中的“.”是不需要转义的,当然转义也能得到正确的结果;*是数量词,表示前面的字符([^0-9\.])可以是0个或1个或多个,现在假设字符串是123a,上面的表达式也是可以匹配的,因为*号可以为0,“[^0-9\.]*”可以不匹配任何字符,字符串中的首个字符“1”就被表达式后面的部分“[0-9]”所匹配,所以字符串“123a”能够被上述表达式匹配。
3.要想正确匹配第2条所说的字符串,可以有多种方法,这样是其中一个方法:“findstr /b "[^0-9.].*[0-9]"”。
4.个人观点,可能存在错误的地方,欢迎批评指正。
以上几条只是就事论事,楼主处理的文件可能文件名很规范,不会遇到上面所说的那种情况,代码也可继续使用。
作者: aloha20200628 时间: 2024-7-22 18:22
3楼代码中的 findstr /rb "[^0-9\.]*[0-9]" 本意其实是为防止误配某些字段如 xxx.123 以及连带扩展名等...
但实测发现凡以数字开头的文件名均被此式误配,原因是findstr正则表达式中的量词不支持+,而*允许为零,故最终练了一把12楼代码...
作者: zhengzhenhui 时间: 2024-7-22 20:51
回复 15# aloha20200628
findstr命令可以这样用,真的是学到了
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |