Reputation: 309
I am trying to delete the 1st line and removing leading and trailing white spaces in the subsequent lines using sed
If I have something like
line1 line2 line3
It should print
line2 line3
So I tried this command on unix shell:
sed '1d;s/^ [ \t]*//;s/[ \t]*$//' file.txt
and it works as expected.
When I try the same in my perl script:
my @templates = `sed '1d;s/^ [ \t]*//;s/[ \t]*$//' $MY_FILE`;
It gives me this message "sed: -e expression #1, char 10: unterminated `s' command" and doesn't print anything. Can someone tell me where I am going wrong
Upvotes: 1
Views: 757
Reputation: 41460
This can also be down with awk
awk 'NR>1 {$1=$1;print}' file
line2
line3
Upvotes: 0
Reputation: 189936
Why would you invoke Sed from Perl anyway? Replacing the sed with the equivalent Perl code is just a few well-planned keystrokes.
my @templates;
if (open (M, '<', $MY_FILE)) {
@templates = map { s/(?:^\s*|\s*$)//g; $_ } <M>;
shift @templates;
close M;
} else { # die horribly? }
Upvotes: 2
Reputation: 870
As others have mentioned, I would recommend you do this only in Perl, or only in Sed, because there's really no reason to use both for this task. Using Sed in Perl will mean you have to worry about escaping, quoting and capturing the output (unless reading from a pipe) somehow. Obviously, all that complicates things and it also makes the code very ugly.
Here is a Perl one-liner that will handle your reformatting:
perl -le 'my $line = <>; while (<>) { chomp; s/^\s*|\s*$//; print $_; }' file.txt
Basically, you just take the first line and store in a variable that won't be used, then process the rest of the lines. Below is a small script version that you can add to your existing script.
#!/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;
Upvotes: 1
Reputation: 805
You have a typo in your expression. You need a semicolon between the 2 substitution statements. You should use the following instead:
my @templates = `sed '1d;s/^ [ \\t]*//;s/[ \\t]*\$//' $MY_FILE`;
escaping $
and \
as suggested in the other answer. I should note that it also worked for me without escaping \
as it was replaced by a literal tab.
Upvotes: 1
Reputation: 4581
Consider to use safe pipe open instead of backticks, to avoid problems with escaping. For example:
my @templates = do {
open my $fh, "|-", 'sed', '1d;s/^ [ \t]*//;s/[ \t]*$//', $MY_FILE
or die $!;
local $/;
<$fh>;
};
Upvotes: 1
Reputation:
The backticks work like double-quotes. Perl interpolates variables inside them, as you already know due to your use of $MY_FILE
. What you may not know is that $/
is actually a variable, the input record separator (by default a newline character). The same is true for the backslashes before the tab character. Here Perl will interpret \t
for you and replace it with the tab character. You'll need a second backslash so that sed sees \t
instead of an actual tab character. The latter might work as well, though.
Upvotes: 1