【问题标题】:Using escape characters in shell在 shell 中使用转义字符
【发布时间】:2015-01-14 18:25:46
【问题描述】:

在 shell 中阅读 Escape characters 时,我尝试了一个示例 -

echo "用户 $USER 的余额为:\$5:00"

它给出了输出

用户 me 的余额为:$5.00

但是当我尝试将转义字符 \ 与制表符 \t 或换行符 \n 一起使用时,它似乎不起作用。我尝试在双引号中使用它(转义字符在双引号中保留其含义)但它仍然不起作用。

echo "用户 $USER 的余额为:\t\$5:00"

不给出输出

用户 me 的余额为:$5:00

相反,输出是 -

用户vyadav的余额为:\t$5:00

【问题讨论】:

  • “为什么它不起作用?” -- 因为 shell 从来没有也从来没有将"\t" 扩展成双引号内的制表符。 Bash 将在 $'\t' 样式引号内执行此操作,但它们是不同的。 echo "\t" 适用于具有符合 XSI 的 echo 命令的系统,因为 echo 命令——而不是 shell 解析/预处理——扩展了序列;对于具有 GNU 扩展的系统上的 echo -e "\t" 也是如此。
  • 我不明白,Shell 扩展了什么以及命令echo 是什么? ~Shell 扩展,对吗? * 等通配符也是如此。
  • 是的,波浪号扩展和全局扩展都是由 shell 完成的。 echo 支持的唯一扩展是反斜杠转义序列,即使这样也只有一些版本的 echo(这就是为什么最好使用 printf,因为它的行为在版本之间是一致的)。请参阅 pubs.opengroup.org/onlinepubs/009604599/utilities/echo.htmlOPERANDS 部分以获取符合 XSI 的 echo 将展开的反斜杠转义序列列表。

标签: regex shell


【解决方案1】:

echo 命令不会在没有-e 选项的情况下展开反斜杠转义

您可以使用echo -e(请注意,这是一个gnu 扩展,不是很便携):

echo -e "The balance for user $USER is:\t\$5:00"
The balance for user anubhava is:   $5:00

根据help echo

-e  enable interpretation of the following backslash escapes

或者更好用printf:

printf "The balance for user %s is:\t\$%s\n" "$USER" "5:00"

或者

printf 'The balance for user %s is:\t$%s\n' "$USER" "5:00"

The balance for user anubhava is:   $5:00

【讨论】:

  • @yadav_vi:您在我的回答中哪里看到了扩展的 grep?
  • printf 的情况下,在格式字符串内扩展$USER 是不好的做法;格式字符串应始终使用单引号:printf 'The balance for user %s is:\t$%s\n' "$USER" "5:00";这样可以避免格式字符串攻击(当然,在 printf 的 bash 实现中不存在这种攻击)。
  • 值得一提的是,-e 是一个 GNU 扩展——与 XSI 或非 XSI 版本的 POSIX 标准化 echo 完全不兼容(前者将处理反斜杠转义没有它并在其输出中打印-e(如果给定,后者根本不支持它们)。
  • @CharlesDuffy:谢谢我添加了关于它的评论。 printf 这里肯定更好。
【解决方案2】:

\$ 所做的事情与 \t 所做的事情之间存在差异。

当 shell 看到 $ 时,它会扩展双引号字符串中的变量,因此您需要从 shell 中“转义”$(这就是 \$ 正在做的事情)。您也可以使用不扩展变量的单引号。

另一方面,\t 是“反斜杠转义”(使用echo 手册页使用的术语)。 \t(在双引号字符串中)对 shell 没有什么特别之处,所以它不会碰到它。而且,默认情况下, echo 不处理“反斜杠转义”。你需要 -e 标志来开启它。

许多人认为带有参数的echo 是可憎的,不应该存在,并且使用-e 标志很容易避免使用printf 代替(它确实处理了一些“反斜杠转义”的格式字符串)。

所以printf 版本将是(请注意,由于单引号,格式字符串中缺少\$)。

printf 'The balance for user %s is:\t$5:00' "$USER"

【讨论】:

  • 这是一些关于 GNU echo 支持公然不兼容 POSIX(不仅是非标准化的,而且在兼容时不可能支持)-e 论点的抱怨的部分。 :)
猜你喜欢
  • 2019-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-02
  • 2021-10-25
相关资源
最近更新 更多