我需要在我正在为一个小项目工作的.bat
文件中处理两件事。首先,我必须知道在同一个文件夹中包含的任何文件名(递归)我启动.bat
in是否超过100个字符。如果是这样,我需要将其设置为92个字符并保留扩展名。
例如,我有这个文件名:
IncrediblyLongFileNameIAmSorryForThisItLooksLikeSomeDamnSpamJesusIAintEvenCloseTo100yetalmostwaitforitYEAH.omg
以上文件名为110个字符。我需要保留扩展名,因此程序应该将文件重命名为:
IncrediblyLongFileNameIAmSorryForThisItLooksLikeSomeDamnSpamJesusIAintEvenCloseTo100yetalmos.omg
到目前为止,我的主要问题是我不知道如何批量处理文件名字符串。我用了这段代码:
@echo off & setlocal enableextensions
FOR /R %%i IN (*.*) DO (
ECHO %%~nxi
FOR /f "delims=:" %%a in ('
^(echo."%%~nxi"^& echo.^)^|findstr /o .'
) DO set lenght=%%a-5
echo The length of "%%~nxi" is %lenght%
)
endlocal & goto :EOF
但我不能在SET
内FOR
,也无法进行基本数学运算(即无法执行-5
操作)。
第二件事,我相信一旦完成第一件事就应该更容易,只是比较文件夹中的所有文件名(递归,再次),并确保没有相同的文件名。如果程序找到任何相同的文件名,则应重命名第二个匹配项以在末尾添加l1l
之类的内容。 (我不能在这里使用括号,因此我使用两个l
来代替数字。)你唯一需要注意的是文件扩展名,因为我不能在文件之后添加任何内容扩展,以免它们变得无法使用。
有人能解释如何实现这一目标吗?我真的希望能够自己解决这个问题,但我缺乏批处理编程方面的经验。
答案 0 :(得分:1)
@ECHO OFF
SETLOCAL
SET "sourcedir=c:\sourcedir"
SET "tempfile=%temp%\##fn##.92"
ECHO ::>"%tempfile%"
FOR /f "delims=" %%a IN (
'dir /s /b /a-d "%sourcedir%\*" '
) DO (
SET "fullname=%%a"
SET "name=%%~na"
SET "ext=%%~xa"
CALL :chgname
)
del "%tempfile%"
GOTO :EOF
:chgname
:: Proposed new name part - first 92 characters of existing name
:: also prepare for adding modifier
SET "newname=%name:~0,92%"
SET /a modifier=0
:modl
:: See whether this name has already been found
ECHO %newname%%ext%|FINDSTR /b /e /i /g:"%tempfile%" >NUL
IF ERRORLEVEL 1 GOTO makechange
:: existing name - modify it
SET "newname=%name:~0,92%@%modifier%@"
SET /a modifier+=1
GOTO modl
:makechange
IF "%name%" NEQ "%newname%" ECHO REN "%fullname%" "%newname%%ext%"
>>"%tempfile%" ECHO %newname%%ext%
GOTO :eof
合理简单的问题。
以基本形式获取目录列表(仅限完整文件名),并将完整文件名,名称部分和扩展部分应用于适当命名的变量。
将文件名操作为由原始名称部分的前92个字符组成的新名称。预计需要通过建立一个可选的应用修饰符来修改这个新名称。
查看建议的新名称是否已存在于已处理的新名称的临时文件中。如果在该文件中找不到,则可以安全地重命名(如果需要)并记录使用的名称。
如果文件名已被使用,请将其修改为原始的第一个92 +“@
anumber @
”,在预期中增加修饰符,然后重试。
仅需要进一步评论 - 首先,我使用@
而不是!
,因为!
具有批处理的特殊含义。其次,将::
写入临时文件(临时文件的名称无关紧要 - 我选择了一个不太可能存在的...)意味着findstr
不会抱怨,因为该文件为空,但是{ {1}}不可能是真正的文件名。
::
的{{1}}选项意味着/b /e /i
的名称必须与一行完全匹配(与findstr
匹配 - 开始和echo
- 结束但/b
- 案件无关紧要。