循环,拆分包含'&'

时间:2014-05-14 20:20:08

标签: batch-file

我在另一个帖子中非常严重地提出这个问题,而且我得到的答案并没有奏效,因为我问得这么糟糕。这次我会尝试做对。

我想浏览目录中遇到某个掩码(* .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循环中完成所有操作,那也很好。

2 个答案:

答案 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--
)