grep命令中“$ a $”的特殊含义

时间:2016-12-11 19:07:05

标签: regex bash shell grep

我正在尝试学习shell脚本,我正在尝试不同的东西。在我练习的过程中,我遇到了grep "$a$" file1并且无法理解输出。

我知道单引号采用字面含义的区别,双引号试图找到$a的特殊含义应该是变量$

我有file1内容

#!/bin/sh
a=1
b=1
echo $a
echo $b
for I in 1 2 3 4 5 6 7 8
do
    c=a
    b=$a
    b=$(($a+$c))
    echo $b
done

grep "$a$" file1为我提供了整个file1作为输出 grep '$a$' file1为我提供了应该给出的输出,就像以$a结尾的行一样。

请解释为何在使用grep "$a$"时将整个文件内容作为输出。

3 个答案:

答案 0 :(得分:1)

没有特别的意义。

我的代码中没有看到任何grep。我假设您正在从命令行进行grepping,并且变量a未定义。因此,grep "$a$"扩展为grep "$"$a扩展为空),grep $匹配每一行,因为$匹配行尾。

[update]'expand',我指的是shell变量扩展。由于$a位于双引号之间,因此shell将$a替换为变量a的值(未定义)。您的grep '$a$'会产生预期的结果,因为单引号之间的任何字符串始终不受shell的影响。试试echo "$a$" vs echo '$a$'

答案 1 :(得分:1)

以grep模式中的^$开头,分别代表开头和结尾。

grep "$a$" file1

$a进行扩展,因为它在双引号内。在您的情况下,$a应该是未定义的。因此"$a$"的结果是$,它匹配每一行的结尾,因此您将获得整个文件作为输出。要验证这一点,请将一些测试值分配给a,然后运行grep。

a="TestValue" # Before running grep
grep "$a$" file1

我打赌你什么也得不到输出。

现在,如果你想在双引号中加上文字“$”。然后你需要做

grep "\$a$" file1 # See the first $ is escaped

以上命令将为您提供以$a

结尾的所有行
echo $a
b=$a

现在如果你厌倦了逃避,你很可能会使用单引号,如下所示

grep '$a$' file1
# The first $ is literal $, and the last one symbolizes end of file.
# More over variable-expansion doesn't take place inside single quotes.

注意: a=1内的file1对grep结果没有影响,因为file1只是{{1}的输入}}

答案 2 :(得分:0)

"$a$"

字符串"$a$"扩展为$a shell变量的值,后跟文字$(为什么?见下文)。如果未设置$a变量,则其值将被解释为空字符串,并且展开的结果为"$"(仅限美元符号)。

为什么最后一个美元符号没有扩展?**

parameter expansion的基本形式是"${PARAMETER}"。如果PARAMETER不是具有多个数字(1011等)的位置参数,则不需要括号,如果PARAMETER后面没有$一个不被解释为其名称一部分的字符。由于a开始下一个参数扩展,命令替换或算术扩展,因此在我们的情况下,它不会被解释为$参数名称的一部分。

由于最后一个$没有任何内容,因此它不符合任何类型的扩展,并保持不变。

Grep如何解释模式

由于match-end-of-line operator$)匹配字符串末尾或字符串中换行符之前的空字符串,因此模式grep "$a$" file匹配任何行

因此,如果file为空,$a将匹配并打印'$a$'中的所有行。

grep '$a$' file

单引号保护字符串不受任何扩展(特殊字符的解释)。也就是说,字符串按原样传递给命令。

"$a"调用的情况下,模式匹配行末尾的$字符串 。以下描述了原因。

正如我们所知,最后$表示该行的结尾。其余的美元符号根据模式进行解释。它可以解释为文字美元符号或行尾。

在以下情况中,$表示行尾操作符。否则,$是普通的。

  • 如果foo$在模式中排在最后,如RE_CONTEXT_INDEP_ANCHORS
  • syntax'\(b$\)'已设置,位于括号表达式之外。
  • 它结束了一个开放组或交替运算符表达式,例如'\(b$\)\|a'$

由于

  • 我们模式中的第一个RE_SYNTAX_GREP显然不是最后一个,
  • 您使用的是基本$a$ syntax,即BRE,
  • 并且未使用开放组/替换,

$中的第一个美元符号普通

当第一个-E不是普通

例如,在扩展正则表达式的情况下,这不是普通的。也就是说,使用-Pegrep选项,或使用pgrepRE_CONTEXT_INDEP_ANCHORS命令(例如,设置$语法位)。< / p>

逃离美元符号

考虑转义美元符号,即使它在基本正则表达式中被解释为文字'\$a$'。它会养成一个好习惯。

要在单引号内转义美元符号,请使用反斜杠:"\\\$a\$"

在双引号内,反斜杠具有特殊含义,因此您需要转义反斜杠本身:pod install