我正在尝试删除第一行并使用sed删除后续行中的前导和尾随空格
如果我有类似
的话line1 line2 line3
应打印
line2 line3
所以我在unix shell上尝试了这个命令:
sed '1d;s/^ [ \t]*//;s/[ \t]*$//' file.txt
它按预期工作。
当我在perl脚本中尝试相同时:
my @templates = `sed '1d;s/^ [ \t]*//;s/[ \t]*$//' $MY_FILE`;
它给了我这条消息“sed:-e expression#1,char 10:unterminated`s'命令”并且不打印任何内容。有人能告诉我哪里出错了吗
答案 0 :(得分:2)
为什么你要从Perl调用Sed呢?用等效的Perl代码替换sed只是一些精心设计的按键。
my @templates;
if (open (M, '<', $MY_FILE)) {
@templates = map { s/(?:^\s*|\s*$)//g; $_ } <M>;
shift @templates;
close M;
} else { # die horribly? }
答案 1 :(得分:1)
反引号就像双引号一样。由于您使用了$MY_FILE
,Perl会在其中插入变量。您可能不知道的是$/
实际上是variable,输入记录分隔符(默认情况下是换行符)。制表符前面的反斜杠也是如此。 Perl将为您解释\t
并将其替换为制表符。您需要第二个反斜杠,以便sed看到\t
而不是实际的制表符。不过,后者可能会起作用。
答案 2 :(得分:1)
你的表情中有一个拼写错误。您需要在2个替换语句之间使用分号。您应该使用以下代码:
my @templates = `sed '1d;s/^ [ \\t]*//;s/[ \\t]*\$//' $MY_FILE`;
按照其他答案中的建议转义$
和\
。我应该注意到它在没有转义\
的情况下对我有用,因为它被文字标签取代。
答案 3 :(得分:1)
考虑使用安全管打开而不是反引号,以避免转义问题。例如:
my @templates = do {
open my $fh, "|-", 'sed', '1d;s/^ [ \t]*//;s/[ \t]*$//', $MY_FILE
or die $!;
local $/;
<$fh>;
};
答案 4 :(得分:1)
正如其他人所提到的,我建议你只在Perl中执行此操作,或仅在Sed中执行此操作,因为实际上没有理由同时使用它们。在Perl中使用Sed意味着你必须担心转义,引用和捕获输出(除非从管道中读取)。显然,所有这些都使事情复杂化,这也使得代码非常难看。
这是一个可以处理重新格式化的Perl单行程序:
perl -le 'my $line = <>; while (<>) { chomp; s/^\s*|\s*$//; print $_; }' file.txt
基本上,你只需要取第一行并存储一个不会被使用的变量,然后处理其余的行。下面是一个小脚本版本,您可以将其添加到现有脚本中。
#!/usr/bin/env perl
use strict;
use warnings;
my $usage = "$0 infile";
my $infile = shift or die $usage;
open my $in, '<', $infile or die "Could not open file: $infile";
my $first = <$in>;
while (<$in>) {
chomp;
s/^\s*|\s*$//;
# process your data here, or just print...
print $_, "\n";
}
close $in;
答案 5 :(得分:0)
这也可以使用awk
awk 'NR>1 {$1=$1;print}' file
line2
line3