2011-09-19 64 views
2

基本上,我试图做的是从一组下载的YouTube视频中提取音频,其名称在文件中(部分)被识别(mus.txt )用手柄TXTFILELIST打开。 TXTFILELIST包含每行上视频的11个字符的标识符(例如“dQw4w9WgXcQ”),下载的文件的格式为[title] - [ID] .mp4(在前面的示例中为“Rick Astley - Never Gonna给你起来 - dQw4w9WgXcQ.mp4“)。从Perl中的某些文件中提取音频

#snip... 
if ($opt_extract_audio) { 
    open(TXTFILELIST, "<", "mus.txt") or die $!; 
    my @all_dir_files = `dir /b`; 
    my $file_to_convert; 
    foreach $file_to_convert (<TXTFILELIST>) { 
    my @files = grep("/${file_to_convert}\.mp4$/", @all_dir_files); #the problem line! 
    print "files: @files\n"; 
    foreach $file (@files) { 
     system("ffmpeg.exe -i ${file} -vn -y -acodec pcm_s16le -ac 2 ${file}.wav"); 
    } 
    } 
#snip... 

的剪断代码的其余部分工作(我有几个视频检查的话,更换瓦尔,评论等),是合法的(我用的strictwarnings编译指示),我相信,是无关紧要的,因为它与定义此片段中使用的任何变量(除$opt_extract_audio之外)无关。但是,这是代码给我带来麻烦的一点,我似乎无法从@all_dir_files中提取TXTFILELIST中标识的文件。我从其他堆栈溢出回答者那里获得了“问题行”的代码,但由于某种原因它无法正常工作。

TL; DR我想要做的是:列出当前目录中的所有文件(比如说目录中包含mus.txt,“里克阿斯特利 - 永远不会给你 - dQw4w9WgXcQ.mp4”)和blah.mp4 ),使用TXTFILELIST(dQw4w9WgXcQ)中的11-char ID选择仅识别的文件(Rick Astley视频)并从中提取音频。是的,我在Windows上运行这个脚本,所以我不能使用像ackfind这样的nix实用程序。

+1

ack带有Perl,我在我的win32盒子上运行它。我也运行了许多已经为win32编译的Unix工具,包括find。 –

回答

2

卸下线

my @all_dir_files = `dir /b`; 

,并使用此循环代替:

for my $file (<*${file_to_convert}.mp4>) { 
    say $file; 
    system(...); 
} 

上述<...>是水珠,也可写成glob "${file_to_convert}.mp4"。我认为使用perl函数几乎总是更好,而不是依赖系统调用。

正如已经指出的那样,"/${file...$/"不是一个正则表达式,而是一个字符串。既然你可以在grep中使用表达式,并且非空字符串总是为真,那么你的grep本质上什么都不做,并且将所有的值传递给你的数组。

+0

我不确定这是否会起作用,$ file_to_convert变量是错误名称,它只是文件名称的一部分,后缀,但它不是模式。 OP执行尾部锚定匹配的这个后缀加上.mp4来获取组中的所有文件。我想,你的glob需要在前面有一个“* - ”。 –

+0

@Bill啊是的..谢谢指出。 – TLP

3

摆脱grep函数中正则表达式的双引号。