我正在尝试提取一个字符串,该字符串位于一系列文本文件(字幕文件)中特定行中的第一个逗号和第二个逗号之间。文本文件的格式如下:
Subtitles01.txt
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour
Style: Default, Estrangelo Edessa, 57, &H00FFFFFF
Style: Title1, Arno Pro, 65, &H00606066Subtitles02.txt
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour
Style: OP Eng, Arno Pro, 45, &H00100F11
Style: ED Romaji, Nueva Std Cond, 46, &H00FFFFFFSubtitles03.txt
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour
Style: OP Eng, Estrangelo Edessa, 45, &H00100F11
Style: Default, Arno Pro, 45, &H00100F11
Style: ED Romaji, Nueva Std Cond, 46, &H00FFFFFF我想在这里实现的是提取每个以“样式:”开头的行的名称,然后以不重复的方式确定哪个字幕包含我想要的字体。因此,从本质上说,最终结果将输出到文本文件中,如下所示;
Subtitles01.txt: Estrangelo Edessa
Subtitles01.txt: Arno Pro
Subtitles02.txt: Arno Pro
Subtitles02.txt: Nueva Std Cond
Subtitles03.txt: Estrangelo Edessa
Subtitles03.txt: Arno Pro
Subtitles03.txt: Nueva Std Cond
Only Subtitles03.txt is needed.因为Subtitles03.txt包含Subtitles01.txt和Subtitles02.txt中的所有字体,所以只需要Subtitles03.txt。目标是使用最少数量的文件来查找所有文件中的唯一字体。我已经提出了以下批处理脚本,使用findstr提取以“Style”开头的行:但是我被困在了这个范围之外。
@echo off
findstr /B /C:"Style:" *.txt > results.txt
if %errorlevel%==0 (
echo Found! logged files into results.txt
) else (
echo No matches found
)任何帮助都将不胜感激。谢谢你们!
发布于 2012-07-09 23:46:24
我想,除了批处理之外,使用其他语言要容易得多,或者至少要使用非本地实用程序。但是这里是一个纯本地批处理解决方案。
我看不出FINDSTR正则表达式将如何帮助这个问题。它不能像许多其他非本地批处理regex实用程序一样提取匹配行的一部分。
您可以使用/F从每个文件中提取字体:
for /f "tokens=2 delims=," %%A in ('findstr /lb "Style:" file.txt') do echo font=%%A您可以使用环境变量生成唯一字体的列表。在变量名中使用字体名定义变量,所有变量都以font_为前缀。只能为给定的名称定义一个变量。分配的值并不重要。然后可以使用set font_列出所有唯一的字体名称。可以计算唯一名称的数量,也可以解析出实际的字体名称(删除font_前缀)。
棘手的部分是建立最小的文件集,以涵盖完整的一组独特的字体名称。我想有人能想出一个有效的解决方案。我刚刚使用了一种蛮力递归排列方法:我计算在每个排列中找到的唯一字体的数量,并将该数目与唯一字体的总数进行比较。我已经添加了一些快捷键,如果我已经找到了比当前集合更小的集合,就不会沿着特定的排列路径前进。
如果在递归中使用SETLOCAL,代码可能会更简单,但是批处理仅限于32级SETLOCAL。我想要一个可以支持超过32个文件的解决方案,尽管我有点担心这么多文件的性能。
编辑 -I修复了我的:permuteFiles例程中的一个错误,这个错误在我有超过3个文件时就出现了。
@echo off
setlocal enableDelayedExpansion
::Make sure there are no font_ variables defined
for /f "delims==" %%A in ('set font_ 2^>nul') do set "%%A="
::Read all the Subtitle files and
:: - create an "array" of file names
:: - create a file of font names for each input file
:: - create an "associative array" of unique font names
:: - List the available file/font pairs in the final results
:: - List the unique fonts in the final results
set fileCount=0
>results.txt (
echo Available fonts
echo ----------------------------
for %%F in (subtitles*.txt) do (
set /a totalFiles+=1
set "file_!totalFiles!=%%F"
3>"%%F.fonts" (
for /f "tokens=2 delims=," %%A in ('findstr /lb "Style:" "%%F"') do (
set "font_%%A=1"
>&3 echo %%A
echo %%F:%%A
)
)
)
echo(
echo Unique fonts
echo ----------------------------
for /f "delims==" %%A in ('set font_') do (
set "font=%%A"
echo !font:~5!
)
)
::Count the number of unique fonts
for /f %%N in ('set font_ ^| find /c /v ""') do set uniqueFonts=%%N
::Test all the permutations
set /a minFileCount=%totalFiles%+1
for /l %%N in (1 1 %totalFiles%) do (
call :permuteFiles %%N 0 ""
)
::List the required files in the final results
>>results.txt (
echo(
echo The following files contain the complete set of unique fonts:
echo -------------------------------------------------------------
for %%N in (%minFileList:~1,-1%) do echo !file_%%N!
)
type results.txt
::Cleanup
del subtitles*.txt.fonts
exit /b
:permuteFiles fileNumber fileCount fileList
if %1==%totalFiles% (
if %2 gtr 0 call :testPermutation %2 %3
set /a fileCount=%2+1
if !fileCount! lss !minFileCount! call :testPermutation !fileCount! "%~3,%1"
) else (
set /a nextFile=%1+1
if %2 gtr 0 call :permuteFiles !nextFile! %2 %3
set /a "nextFile=%1+1, fileCount=%2+1"
if !fileCount! lss !minFileCount! call :permuteFiles !nextFile! !fileCount! "%~3,%1"
)
exit /b
:testPermutation fileCount fileList
for /f "delims==" %%A in ('set font_ 2^>nul') do set "%%A="
for %%N in (%~2) do (
for /f "usebackq delims=" %%A in ("!file_%%N!.fonts") do set "font_%%A=1"
)
for /f %%N in ('set font_ ^| find /c /v ""') do if %%N==%uniqueFonts% (
set minFileList=%2
set minFileCount=%1
)
exit /b下面是使用示例输入的结果:
Available fonts
----------------------------
Subtitles01.txt: Estrangelo Edessa
Subtitles01.txt: Arno Pro
Subtitles02.txt: Arno Pro
Subtitles02.txt: Nueva Std Cond
subtitles03.txt: Estrangelo Edessa
subtitles03.txt: Arno Pro
subtitles03.txt: Nueva Std Cond
Unique fonts
----------------------------
Arno Pro
Estrangelo Edessa
Nueva Std Cond
The following files contain the complete set of unique fonts:
-------------------------------------------------------------
subtitles03.txt发布于 2012-07-09 07:40:02
编辑:使用这个:
^Style:\s*([^,]+)\s*,\s*([^,]+)\s*,\s*([^,]+)\s*,\s*(.+)\s*发布于 2012-07-09 08:33:26
我知道您显然是在一个默认情况下没有安装awk或Perl的平台上,但您可能仍然希望考虑安装其中一个工具,特别是在将来需要执行类似任务的情况下。
awk -F, '/^Style:/ { print FILENAME ":" $2 }' *.txt或者使用Perl:
perl -ne 'print "$ARGV:$1\n" if m/^Style: [^,]*,([^,]*)/' *.txt随后的优化(删除与其他匹配文件重叠的任何文件)在这两种语言中都不难做到。Perl可以更好地扩展到更大、更多样的任务,因此如果您不熟悉这两个任务,这将是我的第一条建议(代价是学习曲线更长、更颠簸,然后您也应该考虑Python )。
https://stackoverflow.com/questions/11390580
复制相似问题