从任何非二进制文件中提取字符串,而不管其在文件中的位置

时间:2014-04-21 11:24:20

标签: batch-file

好的,这是一个问题,我没有成功地处理,编写批处理脚本。假设我有一个包含一些youtube地址的文件(例如带有youtube页面链接的html文件)。

文件内容可能如下所示:

Blaaaa blaa
blaa blaa blaa <a href=https://www.youtube.com/watch?v=9bZkp7q19f0>Gangnam1</a> blaaa blaa
<a href=https://www.youtube.com/watch?v=kYtGl1dX5qI&list=RD9bZkp7q19f0>Scream and shout</a> blaa blaa
blaaaaa <a href=https://www.youtube.com/watch?v=lWA2pjMjpBs&list=RD9bZkp7q19f0>Diamonds</a> blaa
blaa bla bla

将使用通配符字符掩码找到字符串,如下所示:

https://www.youtube.com/watch\?v=*> 

(或类似的东西)

另一个文件中保存的输出应如下所示:

https://www.youtube.com/watch?v=9bZkp7q19f0>
https://www.youtube.com/watch?v=kYtGl1dX5qI&list=RD9bZkp7q19f0>
https://www.youtube.com/watch?v=lWA2pjMjpBs&list=RD9bZkp7q19f0>

搜索当然也可以考虑其他字符串,而不仅仅是与YouTube相关的字符串。

不能使用像FIND或FINDSTR这样的简单命令,因为它们返回包含字符串的整行。类似地,带有令牌和分隔符的FOR似乎在这里没什么用处,因为要找到的字符串在整个文件中不规则地散布,有时在同一行中有几个。

我真的不知道如何解决这个问题。它可能看起来很简单,但我从来没有找到过可以提供类似输出的脚本或程序。也许甚至存在一个准备好的编译程序来完成它。我会非常感谢你的帮助。

2 个答案:

答案 0 :(得分:2)

我会使用另一种脚本语言作为蝙蝠来做到这一点。 在这里我在Autoit中做了一个小例子:

<强> StringBetween.au3

#include <String.au3>
Local $hOutFile=FileOpen("output.txt",2)
Local $hTexte=FileRead($CmdLine[1])
$AFind=_StringBetween($hTexte,$cmdline[2],$cmdline[3])
For $i= 0 To UBound($Afind)-1 step 1
   FileWrite($hOutFile,$AFind[$i]&@crlf)
Next
FileClose($hOutFile)

您可以自己编译或下载已在此编译的文件:

StringBetween.rar

用法:

[InPutFile] [StringRight] [StringLeft]

之间的字符串

输出:&#34; Output.txt&#34;

在你的情况下:

Stringbetween.exe "example.html" "<a href=" ">"

将使用以下内容创建文件"Output.txt"

https://www.youtube.com/watch?v=9bZkp7q19f0
https://www.youtube.com/watch?v=kYtGl1dX5qI&list=RD9bZkp7q19f0
https://www.youtube.com/watch?v=lWA2pjMjpBs&list=RD9bZkp7q19f0

答案 1 :(得分:0)

感谢您的快速回复。它真的帮了很多忙。我印象非常深刻。

我从未使用过AutoIt,现在我发现它确实是一个有用的实用程序!我已经下载了该程序并尝试了它很有趣。我喜欢庞大的函数库(尽管它们分散在各种脚本中,使得它们看起来有点混乱和不直观),尤其是将脚本代码编译成可执行文件的能力。我也一定会在将来使用它。

我稍微修改了您的脚本,以便能够一次处理一个目录中的多个文件。这就是它现在的样子:

#include <String.au3>
#include <File.au3>
#include <Array.au3>
#include <MsgBoxConstants.au3>
#include <WinAPIFiles.au3>

;Parameters:
Local $Ldelimiter, $Rdelimiter, $Filter, $Outputfilename

;Prompt for parameters if not stated in command line:
If $CmdLine[0] < 1 Then
$Ldelimiter=InputBox("","Enter the left delimiter :","") 
Else
   $Ldelimiter=$CmdLine[1]
   EndIf
If $CmdLine[0] < 2 Then
$Rdelimiter=InputBox("","Enter the right delimiter :","") 
Else
   $Rdelimiter=$CmdLine[2]
EndIf
If $CmdLine[0] < 3 Then
$Filter=InputBox("","Enter the filter mask :","*.*") 
Else
   $Filter=$CmdLine[3]
EndIf
If $CmdLine[0] < 4 Then
$Outputfilename=InputBox("","Enter the name of output file :","output.txt") 
Else
   $Outputfilename=$CmdLine[4]
EndIf

Local $hOutFile=FileOpen($Outputfilename,2) ;Open output file
Local $curpath=_WinAPI_GetCurrentDirectory()    ;Get current directory

Local $FileList=_FileListToArray($curpath,$Filter,1)    ;Make an array with the list of files to process

For $k= 1 To UBound($FileList)-1 step 1 ;Process a file from the list
    Local $hTexte=FileRead($FileList[$k])   ;Read file content
    $AFind=_StringBetween($hTexte,$Ldelimiter,$Rdelimiter)  ;Make an array with the list of strings to be found
    For $i= 0 To UBound($Afind)-1 step 1    ;Get a string from the list
        FileWrite($hOutFile,$Ldelimiter&$AFind[$i]&$Rdelimiter&@crlf)   ;Write the string to output file
    Next
Next
FileClose($hOutFile)

exit

<强>用法:

String [StringLeft] [StringRight] [FileMask] [OutputFile]

之间的字符串

如果您未能在命令行中提供参数,程序将提示它们。 FileMask默认为*。*(目录中的所有文件都将被处理)。我还在输出中添加了左右分隔符。

此致

PS:我仍然想知道是否可以用简单的BAT做同样的事情。