1

如何在此命令中替换regex为?$var

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

$var可能看起来像fs2@auto-17

sed命令将输出正则表达式之前的行,但不输出包含正则表达式的行。

如果使用 Perl 单线可以更轻松地完成所有这些工作,那么对我来说没问题。

4

5 回答 5

1

它并不漂亮,但这给了我$var想要的前一行。

echo "$many_lines" | grep -B1 "$var" | grep -v "$var"
于 2013-03-26T16:28:38.860 回答
1

在 Perl 正则表达式中,您可以将变量内容插入到正则表达式中,例如/$foo/. 但是,内容将被解释为模式。如果要匹配 的文字内容$foo,则必须转义元字符:$safe = quotemeta $foo; /$safe/。这可以缩写为/\Q$foo\E/,这是您通常想要的。尾随\E是可选的。

我不知道 sed 正则表达式引擎是否有类似的功能。

Perl 单行:perl -ne'$var = "..."; print $p if /\Q$var/; $p=$_'

于 2013-03-26T18:54:55.097 回答
0

使用双引号而不是单引号来允许变量扩展:

echo $many_lines | sed -n "/$var/"'{g;1!p;};h'
于 2013-03-26T15:25:52.060 回答
0

由于您正在寻找正则表达式之前的一行,因此使用一个单行将不会那么琐碎和美观,但我将这样做(仅使用 Perl):

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

或者如果你想在一行中做

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

或者这个,绝对应该匹配:

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

于 2013-04-05T03:38:13.613 回答
-1

或者,如果您不想转义双引号,也可以使用 here-documents!

在 Perl 中它看起来像这样:

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

用您开始的相同字符串结束heredoc很重要,在我的示例中,它的“HEREDOC”在一个新行中!

于 2013-03-26T15:45:09.467 回答