为什么sed没有将 t识别为标签?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为什么sed没有将 t识别为标签?相关的知识,希望对你有一定的参考价值。
sed "s/\(.*\)/\t\1/" $filename > $sedTmpFile && mv $sedTmpFile $filename
我期待这个sed脚本在$filename
的每一行的字体中插入一个标签,但事实并非如此。由于某种原因,它插入一个t代替..奇怪..
并非所有版本的sed
都了解\t
。只需插入一个文字标签(按Ctrl-V然后按Tab键)。
我认为其他人已经充分澄清了其他方法(sed
,AWK
等)。但是,我的bash
特定答案(在macOS High Sierra和CentOS 6/7上测试)如下。
1)如果OP想要使用类似于他们最初提出的搜索和替换方法,那么我建议使用perl
,如下所示。注意:正则表达式的正则表达式之前的反斜杠不应该是必需的,并且此代码行反映了$1
如何比使用\1
替换运算符的perl
更好(例如,每个Perl 5 documentation)。
perl -pe 's/(.*)/\t$1/' $filename > $sedTmpFile && mv $sedTmpFile $filename
2)但是,正如ghostdog74所指出的那样,因为在将tmp文件更改为输入/目标文件($filename
)之前,所需的操作实际上只是在每行的开头添加一个制表符,我会再次推荐perl
但是以下修改:
perl -pe 's/^/\t/' $filename > $sedTmpFile && mv $sedTmpFile $filename
## OR
perl -pe $'s/^/\t/' $filename > $sedTmpFile && mv $sedTmpFile $filename
3)当然,tmp文件是多余的,所以最好只做“就地”(添加-i
标志)并将事情简化为更优雅的单行程序
perl -i -pe $'s/^/\t/' $filename
使用Bash,您可以编程方式插入TAB字符,如下所示:
TAB=$'\t'
echo 'line' | sed "s/.*/$TAB&/g"
echo 'line' | sed 's/.*/'"$TAB"'&/g' # use of Bash string concatenation
@sedit是在正确的道路上,但定义一个变量有点尴尬。
Solution (bash specific)
在bash中执行此操作的方法是在单引号字符串前放置一个美元符号。
$ 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
如果您的字符串需要包含变量扩展,您可以将引用的字符串放在一起,如下所示:
$ timestamp=$(date +%s)
$ echo -e '1\n2\n3' | sed "s/.*/$timestamp"$'\t&/g'
1491237958 1
1491237958 2
1491237958 3
Explanation
在bash中$'string'
导致“ANSI-C扩展”。这就是我们大多数人在使用\t
,\r
,\n
等等时所期望的。来自:https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html#ANSI_002dC-Quoting
$'string'形式的单词是专门处理的。单词扩展为字符串,替换为ANSI C标准指定的反斜杠转义字符。反斜杠转义序列(如果存在)将被解码...
扩展结果是单引号,好像美元符号不存在一样。
Solution (if you must avoid bash)
我个人认为大多数避免使用bash的努力都是愚蠢的,因为避免使用bashisms并不能使你的代码可移植。 (如果你把它放到bash -eu
,你的代码会比你试图避免使用sh
[除非你是一个绝对的POSIX忍者]而不那么脆弱。)但是我不会就此做出宗教争论,我会给你最好的答案。
$ echo -e '1\n2\n3' | sed "s/.*/$(printf '\t')&/g"
1
2
3
* 最佳答案?是的,因为大多数反bash shell脚本编写者在他们的代码中会出错的一个例子是在echo '\t'
中使用@robrecord's answer。这适用于GNU echo,但不适用于BSD echo。这是由http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37_16的开放组解释的。这是为什么试图避免基本原则通常失败的一个例子。
我在Ubuntu 12.04(LTS)上使用了类似的东西和Bash shell:
要添加带选项卡的新行,请在第一个匹配时添加第二行:
sed -i '/first/a \\t second' filename
首先用tab替换,第二个:
sed -i 's/first/\\t second/g' filename
实际上,您不需要使用sed
进行替换,您只需要在该行前面插入一个选项卡。与仅打印出来相比,此案例的替换是一项昂贵的操作,尤其是在处理大文件时。它更容易阅读,因为它不是正则表达式。
例如使用awk
awk 'print "\t"$0' $filename > temp && mv temp $filename
使用$(echo '\t')
。你需要围绕模式引用。
例如。要删除标签:
sed "s/$(echo '\t')//"
我在Mac上用过这个: -
sed -i '' $'$i\\\n\\\thello\n' filename
sed
不支持\t
,也不支持像\n
这样的其他逃脱序列。我发现这样做的唯一方法是使用sed
在脚本中插入制表符。
也就是说,您可能需要考虑使用Perl或Python。这是我写的一个简短的Python脚本,我用于所有流正则表达式:
#!/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:])
而不是BSD sed,我使用perl:
ct@MBA45:~$ python -c "print('\t\t\thi')" |perl -0777pe "s/\t/ /g"
hi
以上是关于为什么sed没有将 t识别为标签?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 Qt::mightBeRichText() 不能将 HTML 表格标签识别为富文本?
我可以在 vue js 中创建一个带有循环的组件吗?有没有办法让它被识别为html标签?