【问题标题】:Why does my Perl one-liner containing an escaped $ not work inside Bash backticks?为什么我的 Perl 单行包含转义的 $ 在 Bash 反引号中不起作用?
【发布时间】:2016-10-11 17:34:33
【问题描述】:

我正在尝试在 Bash 脚本中使用 Perl 单行符在文本文档中搜索 $。我怀疑它会将$ 视为变量。

这是我的代码:

ITEMVALUE=`perl -ne 'print /\$.*/g' file.txt`

文本看起来像这样:

a bunch of random text
$80
a bunch of random text

我只想提取$80。为什么这不起作用,我如何检索所需的文本?

【问题讨论】:

  • 检查this的答案,也许有帮助。
  • 用两个反斜杠替换反斜杠。
  • Perl 看起来不错——请让我们看看您的整个 Bash 脚本?

标签: regex bash perl


【解决方案1】:

来自Bash manual

命令替换

命令替换允许命令的输出替换命令名称。有两种形式:

$(command)

`command` 

...

当使用旧式反引号形式的替换时,反斜杠保留其字面含义除非后面跟着 $`\ ... 当使用 @ 987654329@形式,括号之间的所有字符组成命令;没有人受到特殊对待。

(强调)

Bash 将\$ 中的\ 视为转义序列,所以

ITEMVALUE=`perl -ne 'print /\$.*/g' file.txt`

实际运行

perl -ne 'print /$.*/g' file.txt

$. 是一个 Perl 内置变量,表示当前行号,因此第一行的正则表达式变为 /1*/,第二行为 /2*/,依此类推。您将获得包含其自己的行号的任何行的输出。

您可以使用 Perl 的 re pragma 看到这一点:

$ ITEMVALUE=`perl -Mre=debug -ne 'print /\$.*/g' file.txt`
Compiling REx "1*"
...
Compiling REx "2*"
...

要修复,请使用$(command) 形式的命令替换,无论如何这通常是首选:

ITEMVALUE=$(perl -ne 'print /\$.*/g' file.txt)

【讨论】:

  • 旁注:使用/g 很奇怪,因为\$.* 每行只能匹配一次,所以我更喜欢print $1 if /(\$.*)/
【解决方案2】:

它比这更简单——它不会像你想象的那样做。

你可能想要:

perl -ne 'print $1 if m/(\$\d+)/'

匹配正则表达式,捕获值并打印值。 (注意 - 可能会匹配多次)。

【讨论】:

  • 如果它存在的话,也许它也能捕捉到美分的价值?
  • 另外,这会引发警告:Possible unintended interpolation of $\ in regex at -e line 1.
  • echo -e 'foo\n$80\nbar' | perl -ne 'print /\$.*/g'(OP 的版本)打印 $80,和你的一样。你为什么说“那不符合你的想法”?
  • 您的选择有效,我找到了替代解决方案的方法。使用 ITEMVALUE=$(command) 设置变量。
  • 这个解决方案有一个反引号和一个正引号?
猜你喜欢
  • 1970-01-01
  • 2021-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-23
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
相关资源
最近更新 更多