DOS读取,解析,然后写入文件

时间:2013-04-18 18:21:43

标签: batch-file dos

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

编辑:至于文件的数据结构......它是一个包含TAGS的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>

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

@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”分配变量,然后将每个变量回显/打印到文件中,以便结果看起来像

artist_name,title,track_number(例如逗号分隔)

提前致谢!

1 个答案:

答案 0 :(得分: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 titl trak)标签之间的内容(artist_name title track_number) 显示结果

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

:FILTER例程在:FILTER ... <内查找作为第>条提供的字符串,并将结果分配给由第二个:filter参数(“var”)

给出的变量
  • 然后为VAR指定%var:* tag =%,它将所有内容都删除 来自VAR
  • 的标签字符串的结尾
  • 接下来,VAR $被指定为%var:* / tag%xxtag,这是以下所有内容 / tag(如果更多数据跟随/ tag)+标签再次+ 2 字符(xx = /和&lt;)
  • 领先的“&gt;”然后从VAR
  • 中删除
  • 然后将一个字符从VAR和VAR $的末尾删除(将初始化为“anystraydataattheendoftheclosetagxxtag”),直到VAR $为空,这将删除close-tag和任何额外数据。

<小时/> 啊 - 每个文件的多个曲目数据。

>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中找到的每个文件   - 清除要使用的变量   - 尝试使用标记找到ART   - 如果找到,请重复titltrak,输出并重试。   - 如果没有找到,请退出并转到下一个文件。

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

如果未在例程中设置变量,则skipto行之后没有其他数据项,否则当我们下次查看文件时,我们知道我们已经处理了{{{ 1}}行,所以下一个变量将被分配给下一个数据项,跳过所有以前找到的项目。

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