bash脚本中的回显制表符


313

如何使用bash脚本回显一个或多个制表符?当我运行这段代码

res='       'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]

我明白了

res=[ x] # that is [<space>x]

Answers:


529
echo -e ' \t '

将回显“空格制表符空间换行符”(-e表示“启用反斜杠转义符的解释”):

$ echo -e ' \t ' | hexdump -C
00000000  20 09 20 0a                                       | . .|

谢谢约翰尼斯。您帮助我找到了这个解决方案:res ='\ t \ t'x; echo -e'['$ res']'
kalyanji

2
您是否知道,为什么echo -e不能在Makefiles中使用?
dma_k 2010年

23
那是因为echo -e不是POSIX,通常不是程序使用的make调用/bin/sh是交互使用的,并且通常没有-e实现。为了便于携带,请printf '\t'改用。
乔苏(So So)

在Darwin(macOS)中,命令man页面echo未提及option -e。但是,此选项被接受。
ePi272314

75

使用printf,而不是echo

echo命令有多个不同版本。有/bin/echo(可能是GNU Coreutils版本,也可能不是GNU Coreutils版本,具体取决于系统),并且该echo命令内置在大多数Shell中。不同的版本有不同的方法(或没有方法)来指定或禁用控制字符的转义符。

printf另一方面,变化较小。它通常可以作为命令存在/bin/printf,并且已内置在某些shell中(bash和zsh拥有,tcsh和ksh却没有),但是各种版本之间的相似之处要远得多echo。而且您不必记住命令行选项(有一些例外情况; GNU Coreutils printf接受--version--help,内置bash printf接受-v var将输出存储在变量中)。

例如:

res='           'x # res = "\t\tx"
printf '%s\n' "[$res]"

现在是时候让我承认,echo对于您正在询问的示例,该方法同样适用。您只需要在参数周围加上双引号即可:

echo "[$res]"

正如kmkaplan所写(两年半前,我才注意到!)。您原始命令的问题:

res='           'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]

不与echo; 这是因为外壳在echo看到它之前用空格替换了标签。

echo对于简单的输出(例如)来说是很好的选择echo hello world,但printf只要您想做更复杂的事情就应该使用。您可以开始echo工作,但是当您使用不同的echo实现或外壳程序运行它时,生成的代码可能会失败。


1
我喜欢这一点,它使我可以使用printf和所有格式说明符的知识。
阿伦(Arun)2013年

@JezenThomas:它没有更多的争议,因为它以不同于请求的方式回答了问题。这个问题专门提到回声,回声不是动词,而是命令。
Paulo Neves'5

@PauloNeves:我会说它在以下问题中用作动词:“如何使用bash脚本回显一个或多个制表符?”
基思·汤普森

34

将您的字符串放在引号之间:

echo "[$res]"

1
同样在这里-这是我首先尝试的。-e效果不错
froderik

2
在zsh中@kmkaplan对我的作品-在bash失败对我来说
卡尔

34

您也可以尝试:

echo Hello$'\t'world.

4
+1获取更通用的解决方案。我已经使用bash多年了,现在我才知道这一点!
Aryeh Leib Taurog 2012年

这比公认的答案要笼统得多,因为它可以不带回声地使用。
jwan

22

您需要使用-e标志进行回显,然后就可以

echo -e "\t\t x"

16

从bash手册页:

$'string'形式的单词经过特殊处理。该单词扩展为字符串,并按ANSI C标准的规定替换反斜杠转义字符。

因此,您可以执行以下操作:

echo $'hello\tworld'

为什么这在cli上起作用,但在bash脚本中却不起作用?
Freek

13

使用逐字按键,^VCTRL+VC-v不管)。

当您输入^V终端(或在大多数Unix编辑器中)时,以下字符逐字显示。您可以使用它在要回显的字符串内键入文字制表符。

类似于以下作品:

echo "^V<tab>"     # CTRL+V, TAB

Bash文档qv,“ quoted-insert”)

quoted-insert(Cq,Cv)将您键入的下一个字符逐字添加到行中。例如,这就是如何插入诸如Cq的键序列。

旁注:据此, ALT+TAB 应该做同样的事情,但是我们都将该序列绑定到了窗口切换上,所以我们不能使用它

制表符(M-TAB)插入制表符。

-

注意:您可以对各种异常字符使用此策略。就像回车一样:

echo "^V^M"        # CTRL+V, CTRL+M

这是因为回车符是ASCII 13,而M是字母的第13个字母,因此,键入时^M,您将获得第13个ASCII字符。您可以使用ls^M,在一个空的提示下看到它的运行情况,该提示将插入一个回车符,从而使提示的行为就像您按回车一样。正常解释这些字符后,逐字即可获取文字字符。


1
希望我能为您提供更多的支持。在这种情况下,我不想在参数中使用-e,并且效果很好。谢谢!
亚伦·

“ ...大多数Unix编辑器”?试图同时使用vi和emacs来输入它,但是在任何一个中都没有得到期望的结果。
GreenMatt

太酷了!并试图grep捕捉包含tab字符的行时节省了我的时间。
乔尔


2

如果要echo "a\tb"在脚本中使用,请按以下方式运行脚本:

# sh -e myscript.sh

或者,您可以授予myscript.sh执行权限,然后运行脚本。

# chmod +x myscript.sh
# ./myscript.sh

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.