我在另一个帖子中非常严重地提出这个问题,而且我得到的答案并没有奏效,因为我问得这么糟糕。这次我会尝试做对。
我想浏览目录中遇到某个掩码(* .txt)的所有文件,并且对于每个文件,将名称拆分为两个字符串。
每个文件名的格式为:
string1 by string2.txt
他们实际上是文档,文件名是文档标题和作者。
string1和string2都可以包含空格;字符串1和字符串2都可以包含&符号('&')。
到目前为止我得到的是:
@echo off
echo.
setlocal EnableDelayedExpansion
for %%f in (*.mobi) do (
call:split "%%f"
)
goto :EOF
:split
set "filename=%~1"
set "author=%filename:* by =%"
set "title=!filename: by %author%=!"
set "author=%author:.txt=%"
echo Filename: -%filename%-
echo Title: -%title%-
echo Author: -%author%-
echo.
除非在任何一个字符串中都有&符号,否则效果很好。然后一切都变成了梨形。
如果我可以摆脱子程序并在for循环中完成所有操作,那也很好。
答案 0 :(得分:2)
您可以使用延迟展开!var!
代替%var%
,并且会保留所有内容,甚至是&
等有毒字符。这也可以让你摆脱子程序。但是有一种更简单的方法。
使用~n
修饰符只获取没有扩展名的基本名称。
将" by "
替换为":"
,这是一个无法出现在文件名中的字符。然后,您可以使用FOR / F循环轻松解析标题和作者。无需为Title和Author分配变量 - 只需直接使用FOR变量即可。与延迟扩展一样,FOR变量也可以保护毒性。
@echo off
setlocal enableDelayedExpansion
for %%F in (*.mobi) do (
set "file=%%~nF"
for /f "tokens=1,2 delims=:" %%A in ("!file: by =:!") do (
echo Filename: -%%F-
echo Title: -%%A-
echo Author: -%%B-
echo(
)
)
或者应该是
for %%F in (*.txt) do ...
如果标题可能包含!
字符,那么在展开%%A
时它会被损坏,因为已启用延迟展开。解决方案是在循环内打开和关闭延迟扩展。
@echo off
setlocal disableDelayedExpansion
for %%F in (*.mobi) do (
set "file=%%~nF"
setlocal enableDelayedExpansion
for /f "tokens=1,2 delims=:" %%A in ("!file: by =:!") do (
endlocal
echo Filename: -%%F-
echo Title: -%%A-
echo Author: -%%B-
echo(
)
)
你还有一个我担心难以克服的潜在问题 - 如果标题中包含“by”这个词怎么办?在我的脑海中,我可以想到一个电影名称,“North by Northwest”。但我不得不相信还有书名。如果有一位作者使用带有“by”字样的假名,我不会感到震惊。
以下修改将正确处理标题中出现“by”的情况。它可以扩展为在标题内支持两个,三个等。通过递归,它可以支持N次出现。但如果“by”出现在作者身上,那么我现在不知道如何解决它。
@echo off
setlocal disableDelayedExpansion
for %%F in (*.mobi) do (
set "file=%%~nF"
setlocal enableDelayedExpansion
for /f "tokens=1,2* delims=:" %%A in ("!file: by =:!") do (
endlocal
echo Filename: -%%F-
if "%%C" equ "" (
echo Title: -%%A-
echo Author: -%%B-
) else (
echo Title: -%%A by %%B-
echo Author: -%%C-
)
echo(
)
)
答案 1 :(得分:0)
你不能回复&
而不用双引号。如果您可以使用"Asimov & Heinlein"
而不是Asimov & Heinlein
的输出:
@echo off
setlocal enabledelayedexpansion
for %%i in (*.mobi) do (call :doit "%%i")
exit /b
:doit
set string=%1
set string=%string:&=§%
set string=%string: by =.%
for /F "tokens=1,2 delims=." %%a in ("%string%") do (
set str1=%%a
set str2=%%b
set str1="!str1:§=&!"
set str2="!str2:§=&!"
echo( --!str1!--!str2!--
)
goto :eof
如果可以选择将其替换为+
:
@echo off
set string=
for %%i in (*.mobi) do ( call :doit "%%i" )
exit /b
:doit
set string=%1
set string=%string:&=+%
set string=%string: by =.%
for /F "tokens=1,2 delims=." %%a in (%string%) do (
echo --%%a--%%b--
)