1

How do I replace regex with $var in this command?

echo "$many_lines" | sed -n '/regex/{g;1!p;};h'

$var could look like fs2@auto-17.

The sed command will output the line immediately before a regex, but not the line containing the regex.

If all this can be done easier with a Perl one-liner, then it is fine with me.

3
  • 1
    echo $many_lines won't work the way you expect unless you quote: echo "$many_lines" Commented Mar 26, 2013 at 15:26
  • 2
    Please improve your question by posting all relevant error messages exactly as they appear, and whatever input samples you're testing against. Also, please include a properly-formatted sample of your expected output so folks understand the results you're trying to achieve. Commented Mar 26, 2013 at 15:50
  • 1
    This can with all probability be done easier and better in perl. However, since you don't describe what you are trying to do, and I don't understand that sed code, I think you're out of luck. Commented Mar 26, 2013 at 16:19

5 Answers 5

1

It is not beautiful, but this gives me the previous line to $var which is want I wanted.

echo "$many_lines" | grep -B1 "$var" | grep -v "$var"
Sign up to request clarification or add additional context in comments.

Comments

1

In Perl regexes, you can interpolate variable contents into regexes like /$foo/. However, the contents will be interpreted as a pattern. If you want to match the literal content of $foo, you have to escape the metacharacters: $safe = quotemeta $foo; /$safe/. This can be shortended to /\Q$foo\E/, which is what you usually want. A trailing \E is optional.

I don't know if the sed regex engine has a similar feature.

A Perl one-liner: perl -ne'$var = "..."; print $p if /\Q$var/; $p=$_'

1 Comment

... and if the variable is an environment variable the way to access it is through the %ENV variable. $ENV{PATH}
0

Use double quotes instead of single quotes to allow variable expansion:

echo $many_lines | sed -n "/$var/"'{g;1!p;};h'

2 Comments

If I do that in the terminal and press arrow up, it is turned into "/$var/{g;1ps -p 1779;};h" and the error invalid command code f
Take care that $var does not contain any unescaped forward slashes.
0

Since you are looking for a line before the regex, with a single one liner it will not be that trivial and beautiful, but here is how I will do it (Using Perl only):

echo "$many_lines" | perl -nle 'print $. if /\Q$var/' | while read line_no; do     export line_no
    echo $many_lines | perl -nle 'print if $. - 1 == $ENV{line_no}'
done

or if you want to do in one line

echo "$many_lines" | perl -nle 'BEGIN {my $content = ""; } $content .= $_; END { while ($content =~ m#([^\n]+)\n[^\n]+\Q$var#gosm) { print $1 }}'

Or this one, should definitely match:

echo "$many_lines" | perl -nle 'BEGIN {my @contents; } push @contents, $_; if ($contents[-1] =~ m#\Q$var#o)') { print $contents[-2] if defined $contents[-2]; }

Comments

-1

Or you can use here-documents too, if you don't want to escape the double quotes!

In Perl it looks like this:

$heredoc = <<HEREDOC;
  here is your text and $var is your parameter
HEREDOC

Its important to end the heredoc with the same string you began, in my example its "HEREDOC" in a new line!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.