Sed不承认\ t反而把它当作't'为什么呢?

sed "s/\(.*\)/\t\1/" $filename > $sedTmpFile && mv $sedTmpFile $filename 

我期待这个sed脚本在$filename的每一行字体中插入一个标签,但事实并非如此。 由于某种原因,它插入在..而奇怪..

并非所有sed版本都能理解\t 。 只需插入一个文字标签(按CtrlV然后选项卡 )。

使用Bash,你可以像这样以编程方式插入一个TAB字符:

 TAB=$'\t' echo 'line' | sed "s/.*/${TAB}&/g" echo 'line' | sed 's/.*/'"${TAB}"'&/g' # use of Bash string concatenation 

我在Ubuntu 12.04(LTS)上使用了一个类似于Bash shell的东西:

第一个匹配的时候再添加一个带有制表符的新行:

 sed -i '/first/a \\t second' filename 

第一个replace为tab,第二个

 sed -i 's/first/\\t second/g' filename 

使用$(echo '\t') 。 你需要引用模式。

例如。 要删除标签:

 sed "s/$(echo '\t')//" 

@sedit是在正确的道路上,但定义一个variables有点尴尬。

解决scheme(特定于bash)

在bash中这样做的方法是在您的单引号string前放置一个美元符号。

 $ echo -e '1\n2\n3' 1 2 3 $ echo -e '1\n2\n3' | sed 's/.*/\t&/g' t1 t2 t3 $ echo -e '1\n2\n3' | sed $'s/.*/\t&/g' 1 2 3 

如果你的string需要包含variables扩展,你可以像这样引用string:

 $ timestamp=$(date +%s) $ echo -e '1\n2\n3' | sed "s/.*/$timestamp"$'\t&/g' 1491237958 1 1491237958 2 1491237958 3 

说明

在bash中$'string'导致“ANSI-C扩展”。 这就是我们大多数人所期望的,当我们使用像\t\r\n等等的东西。来自: https : //www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html# ANSI_002dC-报价

$'string'forms的单词被特殊处理。 字扩展为string ,反斜杠转义字符被ANSI C标准指定。 反斜杠转义序列(如果存在)被解码…

扩大的结果是单引号的,好像美元符号不存在。

解决scheme(如果你必须避免bash)

我个人认为,避免bash的大部分努力是愚蠢的,因为避免bashisms不会使你的代码变得轻松。 (如果你把代码bash -eu了,那么你的代码就不那么脆弱了,比起你试图避免bash和使用sh (除非你是一个绝对的POSIX忍者)。但是我不会对此有宗教争论,给你最好的答案。

 $ echo -e '1\n2\n3' | sed "s/.*/$(printf '\t')&/g" 1 2 3 

* 最佳答案? 是的,因为大多数反bash shell脚本会在代码中做错的一个例子是在@ robrecord的回答中使用echo '\t' 。 这将适用于GNU回声,但不是BSD回声。 The Open Group在http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37_16中解释了这一点;

实际上,您不需要使用sed进行replace,只需要在行前插入一个选项卡即可。 与仅打印出来相比,这种情况下的replace是一个昂贵的操作,特别是在处理大文件时。 它更容易阅读,因为它不是正则expression式。

例如使用awk

 awk '{print "\t"$0}' $filename > temp && mv temp $filename 

sed不支持\t ,也不支持\n这样的其他转义序列。 我发现这样做的唯一方法是实际上使用sed在脚本中插入制表符。

也就是说,你可能要考虑使用Perl或Python。 下面是我写的一个简短的Python脚本,用于所有stream正则expression式:

 #!/usr/bin/env python import sys import re def main(args): if len(args) < 2: print >> sys.stderr, 'Usage: <search-pattern> <replace-expr>' raise SystemExit p = re.compile(args[0], re.MULTILINE | re.DOTALL) s = sys.stdin.read() print p.sub(args[1], s), if __name__ == '__main__': main(sys.argv[1:]) 

我在Mac上使用这个: –

 sed -i '' $'$i\\\n\\\thello\n' filename 

使用这个链接作为参考

而不是BSD sed,我使用Perl:

 ct@MBA45:~$ python -c "print('\t\t\thi')" |perl -0777pe "s/\t/ /g" hi