1

我必须从每个子文件夹中读取文件名,找到我要查找的字符串,然后写入文本文件。每个子文件夹的文件名始终相同。

编辑:至于文件的数据结构......它是一个带有标签的 XML 文件。我只想在下面搜索这些标签,并将它们写入文本文件。

这是数据的片段(文件中有多个轨道标签:

             <track>
              <artists>
                <artist>
                    </read_only_info>
                    <primary>true</primary>
                    <language>en</language>
                    <artist_name>Kim Wilde</artist_name>
                    <roles>
                        <role>Primary</role>
                    </roles>
                </artist>
            </artists>
            <isrc>USMC18441630</isrc>
            </audio_file>
            <title>The Second Time</title>
            <locales/>
            <track_number>8</track_number>
         </track>

我使用“查找”来查找字符串。这就是我所拥有的...

@ECHO OFF


SET filename=metadata.txt

FOR /F %%D in ('dir /b /a:D') DO (

(find /i "<artist_name>" "%%D\%filename%")
(find /i "<title>" "%%D\%filename%")
(find /i "<track_number>" "%%D\%filename%")

)

如何为“artist_name”、“title”和“track_number”分配变量,然后将每个变量回显/打印到文件中,以便结果看起来像

艺术家姓名、标题、曲目编号(例如,逗号分隔)

提前致谢!

4

1 回答 1

0
@ECHO OFF
SETLOCAL
SET filename=metadata.xml

(
FOR /F %%D in ('dir /b /a:D') DO IF EXIST "%%D\%filename%" (
CALL :process "%%D\%filename%"
)
)>result.txt
GOTO :eof

:process
CALL :filter %1 art  artist_name
CALL :filter %1 titl title
CALL :filter %1 trak track_number
ECHO "%art%","%titl%","%trak%"
GOTO :eof

:filter
FOR /f "delims=" %%i IN ('type %1 ^|findstr /c:"<%3>"') DO (SET %2=%%i)
CALL SET "%2=%%%2:*%3=%%"
CALL SET "%2$=%%%2:*/%3=%%xx%3"
CALL SET "%2=%%%2:~1%%"
:lop
CALL SET "%2=%%%2:~0,-1%%"
CALL SET "%2$=%%%2$:~1%%"&IF DEFINED %2$ GOTO lop
GOTO :eof

完全替换代码 20130423-0805Z

陷入延迟扩张陷阱。

在我的测试系统中运行有 300 多个子目录。简化和转移并不完全奏效......

这次肯定...

确保文件存在于子目录中。

从文件中过滤掉到(art title trak)标签之间的内容(artist_name title track_number)显示结果

  • 结果被重定向到输出文件“result.txt”

该例程在..:FILTER中查找作为第三个参数(“tag”)提供的字符串,并将结果分配给第二个参数(“var”)给出的变量:FILTER<>:filter

  • 然后为 VAR 分配 %var:*tag=% ,它将所有内容从 VAR 中剥离到标签字符串的末尾
  • 接下来,为 VAR$ 分配 %var:*/tag%xxtag 这是 /tag 后面的所有内容(如果 /tag 后面有更多数据)+ 再次标记 + 2 个字符(xx=/ 和 <)
  • 然后从 VAR 中删除前导“>”
  • 然后从 VAR 和 VAR$ 的末尾删除一个字符(将被初始化为“anystraydataattheendoftheclosetagxxtag”),直到 VAR$ 为空,这将删除关闭标签和任何额外的数据。


啊-每个文件有多个轨道数据。

只需将>report.txt结果发送到文件而不是屏幕。完全可选

@ECHO OFF
SETLOCAL
SET filename=%1&IF NOT DEFINED filename ECHO syntax:%~n0 startingdirname&GOTO :EOF 
PUSHD "%~1"
SET filename=metadata.xml

(
FOR /F %%D in ('dir /b /a:D') DO IF EXIST "%%D\%filename%" (
SET skipto=1
CALL :process "%%D\%filename%"
)
)>report.txt
POPD
GOTO :eof

:process
FOR %%i IN (art titl trak) DO SET "%%i="
CALL :filter %1 art  artist_name
IF NOT DEFINED art GOTO :eof
CALL :filter %1 titl title
CALL :filter %1 trak track_number
ECHO "%art%","%titl%","%trak%"
GOTO process

:filter
FOR /f "skip=%skipto% delims=" %%i IN (
  'type %1^|FINDSTR /n "$"') DO if not defined %2 (
  ECHO "%%i"|findstr /c:"<%3>" >nul
  IF NOT ERRORLEVEL 1 (
   SET "%2=%%i"
   FOR /f "delims=:" %%L IN ("%%~i") DO SET skipto=%%L
   )
  )
)
IF NOT DEFINED %2 GOTO :EOF 
CALL SET "%2=%%%2:*%3=%%"
CALL SET "%2$=%%%2:*/%3=%%xx%3"
CALL SET "%2=%%%2:~1%%"
:lop
CALL SET "%2=%%%2:~0,-1%%"
CALL SET "%2$=%%%2$:~1%%"&IF DEFINED %2$ GOTO lop
GOTO :eof

经过修改的版本。

:process在设置为 1 后处理找到的每个文件skipto- 清除要使用的变量 - 尝试使用标签查找- 如果找到,使用andART重复,输出并重试。- 如果没有找到,退出并继续下一个文件。titltrak

现在的FILTER过程 - 查看源代码中的每一行,但linenumber:首先为每一行编号。第一%skipto%行被跳过。- 在跳过的行之后找到包含目标标记的第一行 - 将变量设置为整个编号行的内容,然后抓取编号行的部分,但不包括第一个冒号,并将其放入SKIPTO -其他匹配行被忽略,因为现在定义了变量。

如果在例程中没有设置变量,那么该skipto行之后就没有更多的数据项,否则当我们接下来查看文件时,我们知道我们已经处理到了该skipto行,所以下一个变量将被分配给下一个数据项,跳过所有以前找到的项。

(编辑 20130425-1640Z 添加PUSHD/POPD以更改目标相对根)

于 2013-04-18T19:36:36.653 回答