sed删除第1行并删除前导/尾随空格

时间:2013-09-18 18:55:26

标签: regex perl sed

我正在尝试删除第一行并使用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'命令”并且不打印任何内容。有人能告诉我哪里出错了吗

6 个答案:

答案 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