我有一段编辑提示表的代码,如果找到了,我不知道如何反转两个连续的行:
/^TITLE.*?"$/
/^PERFORMER.*?"$/反转到
/^PERFORMER.*?"$/
/^TITLE.*?"$/ 在我的情况下,解决方案是什么?
use strict;
use warnings;
use File::Find;
use Tie::File;
my $dir_target = 'test';
find(\&c, $dir_target);
sub c {
/\.cue$/ or return;
my $fn = $File::Find::name;
tie my @lines, 'Tie::File', $fn or die "could not tie file: $!";
for (my $i = 0; $i < @lines; $i++) {
if ($lines[$i] =~ /^REM (DATE|GENRE|REPLAYGAIN).*?$/) {
splice(@lines, $i, 3);
}
if ($lines[$i] =~ /^\s+REPLAYGAIN.*?$/) {
splice(@lines, $i, 1);
}
}
untie @lines;
}发布于 2010-05-21 12:05:50
好的,因为您绑定到一个数组中,所以我只检查$lines[$i]和$lines[$i+1] (只要+1地址存在),如果前者与标题匹配,而后者与表演者匹配,则交换它们。除非您可能需要转置这些,即使它们不是连续的??
如果你知道它们是连续的,这里有一个选项(这段代码将放在你的for循环中,也许在REM检查行的上面):
if ($i < $#lines and $lines[$i] =~ /^TITLE.*?"$/
and $lines[$i+1] =~ /^PERFORMER.*?$/) {
my $tmp = $lines[$i];
$lines[$i] = $lines[$i+1];
$lines[$i+1] = $tmp;
}另一种选择(无论是否连续都可以工作,而且可以说更优雅)将是
use List::MoreUtils qw(first_index);(在顶部,使用其他use语句),然后执行(在&c内,但在for循环之外):
my $title_idx = first_index { /^TITLE.*?"$/ } @lines;
my $performer_idx = first_index { /^PERFORMER.*?"$/ } @lines;
if($title_idx >= 0 and $performer_idx >= 0 and $title_idx < $performer_idx)
{
# swap these lines:
($lines[$title_idx],$lines[$performer_idx]) =
($lines[$performer_idx],$lines[$title_idx]);
}这就是你要找的吗?
发布于 2010-05-21 12:01:28
这可能看起来有点夸张,但是看到您的文件不是很大,我很想利用以下一行代码(从命令行或通过system调用)。
一行程序的工作原理是一次遍历所有行,然后将其余的工作留给一个正则表达式替换,该替换颠倒了行的顺序。
如果你使用*nix:
perl -0777 -i -ne 's/(TITLE.*?")\n(PERFORMER.*?")/$2\n$1/g' file1 file2 ..如果您使用的是Windows,则需要创建现有文件的备份:
perl -0777 -i.bak -ne "s/(TITLE.*?\")\n(PERFORMER.*?\")/$2\n$1/g" file1 file2 ..解释
命令开关(有关详细信息,请参阅perlrun )
骰子(一个八进制数)强制执行文件窃取,behavior
-i启用就地编辑(不需要splice-‘n’- -0777!)。Windows系统要求您提供一个备份扩展名,因此会在文件中的所有行上执行额外的.bak-n循环(尽管由于您是在窃听它们,所以Perl将每个文件的内容视为一个line)-e,从而允许Perl识别command-line中的代码
正则表达式
TITLE行,即连续的PERFORMER行,并将其分别存储在变量$1和$2中。然后,替换正则表达式颠倒两个变量的顺序,用换行符分隔。文件名参数
在你尝试这些一行程序之前,我会为你的文件创建一个备份。
https://stackoverflow.com/questions/2879274
复制相似问题