如何在此命令中替换regex
为?$var
echo "$many_lines" | sed -n '/regex/{g;1!p;};h'
$var
可能看起来像fs2@auto-17
。
该sed
命令将输出正则表达式之前的行,但不输出包含正则表达式的行。
如果使用 Perl 单线可以更轻松地完成所有这些工作,那么对我来说没问题。
它并不漂亮,但这给了我$var
想要的前一行。
echo "$many_lines" | grep -B1 "$var" | grep -v "$var"
在 Perl 正则表达式中,您可以将变量内容插入到正则表达式中,例如/$foo/
. 但是,内容将被解释为模式。如果要匹配 的文字内容$foo
,则必须转义元字符:$safe = quotemeta $foo; /$safe/
。这可以缩写为/\Q$foo\E/
,这是您通常想要的。尾随\E
是可选的。
我不知道 sed 正则表达式引擎是否有类似的功能。
Perl 单行:perl -ne'$var = "..."; print $p if /\Q$var/; $p=$_'
使用双引号而不是单引号来允许变量扩展:
echo $many_lines | sed -n "/$var/"'{g;1!p;};h'
由于您正在寻找正则表达式之前的一行,因此使用一个单行将不会那么琐碎和美观,但我将这样做(仅使用 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]; }
或者,如果您不想转义双引号,也可以使用 here-documents!
在 Perl 中它看起来像这样:
$heredoc = <<HEREDOC;
here is your text and $var is your parameter
HEREDOC
用您开始的相同字符串结束heredoc很重要,在我的示例中,它的“HEREDOC”在一个新行中!