不同命令中反斜杠的用法

不同命令中反斜杠的用法

我一直在尝试更好地理解某些命令中如何使用反斜杠。我理解它用于转义特殊字符(例如echo 'that'\''s no moon' )的用法,但其他命令的输出有点令人困惑。例如:

rpm-qa rpmname\*

grep '\s/tmp' /etc/fstab

有人可以帮我分解这些吗?也对您可能知道的任何其他用法感到好奇。谢谢你!

答案1

反斜杠通常用来表示“让下一个字符代表自己,而不是赋予它特殊的含义”。我们说反斜杠引号下一个字符。这种含义存在于许多编程语言中,包括 shell 语法。例如,在 中rpm-qa rpmname\*,反斜杠导致*字符在参数中传递给rpm-qa命令。相反,rpm-qa rpmname*将替换rpmname*为当前目录中以rpmname. (如果没有匹配的文件,则 bash 不会出现rpmname*;默认情况下,zsh 会抱怨没有匹配项。)

shell 提供了另一种按字面解释字符的方式,即使其代表自身而不是以某种特殊方式解释。这就是引用,它取消了整个字符序列的特殊含义。有两种引号:单引号'使每个字符代表自己,直到下一个单引号,而双引号则为"少数字符( 、 和 )保留"特殊$含义。在 中,该命令接收一个参数,该参数是(用文字字符串编写的,而不是在该特定情况下有任何具有特殊含义的字符)的串联,(反斜杠单引号取消了该单引号的特殊含义,因此这会扩展为一个单引号字符),并且(空格失去了其特殊含义,因为它们位于引号内:它们不是分隔参数,而是参数的一部分)。\`echo 'that'\''s no moon'echothat's no moon

在 shell 中,当反斜杠具有特殊含义时,通常是引用下一个字符。但:

  • 在单引号内,反斜杠没有特殊含义。
  • 在双引号内,反斜杠仅引用下一个字符(如果它是 之一)"$\`。否则,反斜杠和后面的字符都按字面解释,例如"\a"是两个字符的字符串\a
  • 在美元单引号文字中,反斜杠具有不同的含义,类似于C。反斜杠后跟八进制数字或某些字母提供了输入字符的替代方法,这对于不可打印的字符很有用。例如,\n是小写的N,"\n"是反斜杠+n,但是$'\n'是换行符。

在 中grep '\s/tmp' /etc/fstab,单引号导致grep接收参数\s/tmp。这个论点是一个正则表达式。正则表达式有许多语法变体,但大多数基于以下两个标准之一:POSIX 基本正则表达式 (BRE) 和扩展正则表达式 (ERE)。 ERE 遵循广泛的惯例,即反斜杠后跟除字母或数字之外的任何内容来引用以下字符。但由于历史原因,在 BRE 中,反斜杠有时会使下一个字符变得特殊,否则它不会如此。在本例中,\s是基本正则表达式语法的 GNU grep 扩展,可用于 BRE 和 ERE,表示一个空白字符。因此列出了前面包含空格或制表符的grep '\s/tmp' /etc/fstab行。/etc/fstab/tmp

答案2

我假设您正在使用 bash 或类似的东西。

首先,您必须了解 bash 如何评估您的输入。您可以在 bash 中使用许多特殊字符。例如,其中一些是* ; ~ $

当您输入内容时,bash 将尝试替换所有应该替换的字符。例如以$符号开头的变量。将*替换为您当前所在目录中存在的每个文件/目录(用 确定pwd)。

如果替换步骤完成,bash 将最终执行(带有fork())您指定的程序。

告诉\bash 忽略给定的特殊字符:\*

答案3

你是对的,有一个常见的约定,即反斜杠用于转义字符,或者所述字符具有特殊含义并且您希望它是字面意思:

# echo 'It\'s a string!'

在上面的示例中,撇号用于分隔文字字符串,但由于字符串中需要撇号,因此必须对其进行转义。

另一种情况则相反,当您需要一个“正常”字符具有某种特殊含义时:

# grep '\s/tmp' /etc/fstab

在上面的例子中,反斜杠是告诉 grep 具有s特殊含义并且不是文字s(是正则表达式空格:空格、制表符、换行符、回车符、垂直制表符)

换句话说,当一个字符有两种可能的含义时,您将其转义,使其成为次要含义。

编辑:

对于你的第一个例子:

rpm-qa rpmname\*

这里*有一个特殊的含义(以“rpmname”开头的任何内容),但为了避免 shell 尝试扩展它,您需要转义它,以便命令rpm获取文字*并可以相应地处理它。

这会导致字符串被解释多次,并且当字符串由多个命令传递时,这可能是一场真正的斗争。

答案4

用于\转义特殊字符和触发正则表达式。

您的rpm命令是 escaping *,在这种情况下,其功能与不转义它相同。 RPM 知道这*是一个无效的包字符,因此即使您转义它它也会解释它。转义特殊字符更常用于处理非字母数字文件名等情况。

假设有两个文件,一个名为“foo-biz-bar”,另一个名为“foo*bar”,我们只想看到“foo*bar”。出现下面的第一个结果是因为未转义的*是 blob 通配符。

$ ls foo*bar
foo*bar foo-biz-bar
$ ls foo\*bar
foo*baz

\s示例中的是grep一个正则表达式,表示“任何空白”,即制表符和空格。

进一步阅读

很难在线获得详尽的正则表达式列表,但您可以开始这里

对我帮助很大的一本书是《Unix Shells by Examples》。广泛的sedgrep、 和awk用法也都涵盖了。

相关内容