我有一套.csv文件,我试图清理。每个都有这样的数据:
x0,"","",""
x1,123,456,789
x2,123,456,789
x3,123,456,789
-,"","",""
x4,123,456,789
[space],____,____,____
x5,123,456,789
x6,===,====,======
x7,---,--------=--,-------
我想删除所有不是xn,###,###,###的行,所以在这个例子中,它将是第1,5,7,9和10行。在cygwin命令中我按1键输入以下命令:
sed -i '/"",""/d' *.csv
sed -i '/___/d' *.csv
sed -i '/---/d' *.csv
sed -i '/===/d' *.csv
这些都有效。但是,当我尝试将它们一起放入perl脚本时(我的其余代码都在perl中,它们会失败:
system("sed -i '/"",""/d' *.csv");
system("sed -i '/___/d' *.csv");
system("sed -i '/---/d' *.csv");
system("sed -i '/===/d' *.csv");
我得到了结果:
找到运算符在test1.pl第1行,#34;&#34; sed -i&#39; /&#34;&#34;,&#34;&#34; < / p>
(在&#34之前缺少操作员;&#34;?)
找到运营商在test1.pl第1行,#34;&#34;&#34;&#34; / d&#39;附近的字符串*的.csv&#34;&#34;
(在&#34; / d&#39; * .csv&#34;?之前缺少操作员)
test1.pl第1行的语法错误,接近&#34;&#34; sed -i&#39; /&#34;&#34;,&#34;&#34;
我注意到除了第一个命令之外的所有工作 - sed中的""
有什么特别之处吗?任何帮助,将不胜感激!我们也欢迎更简单的解决方案!
答案 0 :(得分:2)
问题是sed
参数中的双引号结束了Perl字符串。你需要逃避它们
system("sed -i '/`"`",`"`"/d' *.csv");
或者您可以使用q(...)
。
system(q(sed -i '/"",""/d' *.csv));
顺便说一句,您可以向sed
提供多个命令,因此您不必多次运行它。
system(q(sed -i -e '/"",""/d' -e '/___/d' -e '/---/d' -e '/===/d' *.csv"));
或者您可以使用带有替换的正则表达式来同时匹配所有模式。
system(q(sed -i -e '/"",""\\|___\\|---/\\|===/d' *.csv"));
答案 1 :(得分:2)
如果你的脚本的其余部分是在Perl中,我强烈建议用本机实现替换你对sed的调用。
例如,您使用sed进行的替换可以替换为以下内容:
use strict;
use warnings;
for my $file (glob '*.csv') {
open my $in, '<', $file;
my @lines;
while (<$in>) {
next if /"",""/;
next if /___/;
next if /---/;
next if /===/;
push @lines, $_;
}
close $in;
# this will overwrite your files!
# change $file to something else to test
open my $out, '>', $file;
print $out $_ for @lines;
}
循环遍历以.csv
结尾的每个文件,读取每一行。它会跳过任何与其中一个模式匹配的行(如果需要,可以使用每个模式之间使用|
的单个正则表达式执行此操作,但我将其保留为与调用sed相同的行)。它将任何剩余的行推送到数组。然后它重新打开输入文件进行写入并打印数组。
当然,它在行数方面略长,但它可以节省您在Perl功能强大时必须使用system
来调用外部命令。这也意味着每个文件只打开一次,而不是像原始代码那样每次替换一次。
答案 2 :(得分:2)
使用转义字符\
使解释器理解sed命令中的(“,*,。)与Perl(”,* ,.)不相同,而应将它们视为字符串模式用于sed命令。
system("sed -i '/\"\",\"\"/d' \*\.csv");
system("sed -i '/___/d' \*\.csv");
system("sed -i '/---/d' \*\.csv");
system("sed -i '/===/d' \*\.csv");