2

How can I remove the few lines from a multi-lined variable?

I'm getting this sort of stuff back from Expect and need to neaten it up a little bit

$var='

total 20
drwxr-xr-x 5 drew.jess users 4096 2013-01-22 15:51 bash
drwxr-xr-x 2 drew.jess users 4096 2011-11-11 10:37 diff
drwxr-xr-x 8 drew.jess users 4096 2012-02-14 09:09 expect
drwxr-xr-x 3 drew.jess users 4096 2011-10-06 11:05 perl 
drwxr-xr-x 3 drew.jess users 4096 2013-02-07 13:10 python
drew ~ $

';

Those blank lines are representative of what I have. Ideally, I want to make $var look like this:

$var='
total 20
drwxr-xr-x 5 drew.jess users 4096 2013-01-22 15:51 bash
drwxr-xr-x 2 drew.jess users 4096 2011-11-11 10:37 diff
drwxr-xr-x 8 drew.jess users 4096 2012-02-14 09:09 expect
drwxr-xr-x 3 drew.jess users 4096 2011-10-06 11:05 perl 
drwxr-xr-x 3 drew.jess users 4096 2013-02-07 13:10 python
';

I should clarify; the important part of this question to me is the removal of the following line:

drew ~ $

The whitespace, I think I can cope with.

Dharman
  • 30,962
  • 25
  • 85
  • 135
drew
  • 21
  • 1
  • 5

5 Answers5

2

You can always use a regex substitution:

$var =~ s/^\s*$//gm;

\s* will match newline, but also other whitespace which you probably do not want. ^ and $ and beginning and end of line anchors. The /m modifier allows the anchors to match inside the string, at start/end of lines (e.g. at newlines).

TLP
  • 66,756
  • 10
  • 92
  • 149
  • This won't delete the last blank line before a non-blank one, because `/$/m` matches only *before* a newline (or at the end of the string). – Borodin Feb 15 '13 at 12:41
  • @Borodin Huh, that's odd. I also discovered that `\z` and `\Z` do not work with the `/m` modifier. – TLP Feb 15 '13 at 12:51
  • I think it's a documentation bug. `$` matches *before* a terminating newline and at the end of the string. `$` with `/m` also matches before *any* newline. `\z` and `\Z` seem fine to me - `\Z` has the same behaviour as `$` behaviour without `/m`, i.e. the end of the string or before a newline at the end. `\z` just matches the end of the string. – Borodin Feb 15 '13 at 12:57
1

A regular expression like s/^[^\S\n]*\n//gm will remove all lines that contain only whitespace.

Update

If you want to do something more than just remove blank lines, then it is best to split the string into lines and remove the ones you don't want. This code uses grep to remove lines that are all-whitespace and then pop to remove the last one.

my @lines = grep /\S/, split /\n/, $var;
pop @lines;
$var = join '', map "$_\n", @lines;
print $var;

output

total 20
drwxr-xr-x 5 drew.jess users 4096 2013-01-22 15:51 bash
drwxr-xr-x 2 drew.jess users 4096 2011-11-11 10:37 diff
drwxr-xr-x 8 drew.jess users 4096 2012-02-14 09:09 expect
drwxr-xr-x 3 drew.jess users 4096 2011-10-06 11:05 perl 
drwxr-xr-x 3 drew.jess users 4096 2013-02-07 13:10 python
Borodin
  • 126,100
  • 9
  • 70
  • 144
  • Glad to help. The problem is that the data isn't organised as "lines" and "remove all the blank lines, plus the last non-blank one" isn't a trivial procedure! – Borodin Feb 15 '13 at 15:40
0

From this perlmonks answer

$var =~ s/(^|\n)[\n\s]*/$1/g;

Lots of ways to do this though. No problems just looping through and deleting blank lines in my opinion.

robert_b_clarke
  • 1,463
  • 10
  • 13
  • this was a particularly good solution for the whitespace, thank you! any ideas about the last line removal? :) – drew Feb 15 '13 at 12:20
  • If you just want to remove the final trailing newline you can call chomp on the entire variable e.g. chomp($var) – robert_b_clarke Feb 15 '13 at 12:29
  • how about the text on that last line too? effectively i want the line that looks like drew ~ $\n to be removed – drew Feb 15 '13 at 12:41
  • @drew: See the update to my answer to do more than just remove blank lines – Borodin Feb 15 '13 at 13:16
0

You can simply trim whitespace like you would do with a single-line string and add a terminating newline:

$var =~ s/^\s+//;  # Trim whitespace from beginning of string
$var =~ s/\s+$//;  # Trim whitespace from end of string
$var .= "\n";      # Add terminating newline
nwellnhof
  • 32,319
  • 7
  • 89
  • 113
-1

For the sake of a different solution that does not use regular expressions, you could use chomp in a loop:

for ( 1 .. 2 ) {
    1 while chomp $var;
    $var = reverse $var;
}
Alan Haggai Alavi
  • 72,802
  • 19
  • 102
  • 127
  • This will not effect the additional blank lines at the beginning of the string. – dgw Feb 15 '13 at 12:08