Bash 如何在模式前插入字符串或换行符;使用SED";(不替换模式)在MAC OS中
我有一个包含以下内容的文件:Bash 如何在模式前插入字符串或换行符;使用SED";(不替换模式)在MAC OS中,bash,macos,shell,sed,Bash,Macos,Shell,Sed,我有一个包含以下内容的文件: aaaabbaaabbaa 我需要这样的输出: aaaa bbaaa bbaa 我需要在第一次出现'b'之前添加新行。我只需要SED命令就可以在bash中使用 sed -i.bak -e 's/bb/qbb/g' input.txt sed -i.bak -e 's/qbb/\'$'\nbb/g' input.txt 我正在使用以下命令。我知道它现在是最完美的 有谁能告诉我比这更好的命令吗。 Pl注意,我只需要在bash中使用SED命令 sed -i.
aaaabbaaabbaa
我需要这样的输出:
aaaa
bbaaa
bbaa
我需要在第一次出现'b'
之前添加新行。我只需要SED命令就可以在bash中使用
sed -i.bak -e 's/bb/qbb/g' input.txt
sed -i.bak -e 's/qbb/\'$'\nbb/g' input.txt
我正在使用以下命令。我知道它现在是最完美的
有谁能告诉我比这更好的命令吗。
Pl注意,我只需要在bash中使用SED命令
sed -i.bak -e 's/bb/qbb/g' input.txt
sed -i.bak -e 's/qbb/\'$'\nbb/g' input.txt
grep-oP
使用lookahead regex将更容易:
echo 'aaaabbaaabbaa' | grep -oP '.+?[^b](?=(b|$))'
aaaa
bbaaa
bbaa
使用sed
:
$ echo "aaaabbaaabbaa" | sed -r 's/([b]+)/\n\1/g'
aaaa
bbaaa
bbaa
sed-r
允许使用()
捕捉块,并使用\1
将它们打印回来。它捕捉到它的块[b]+
,意思是“一个或多个b”
,并以新行开头将其打印回来
我看到您正在使用sed-I
,这样做也很好:
sed -i.bak -r 's/([b]+)/\n\1/g' input.txt
还有,更简单(!)
它替换了所有的“b”序列,并用一个换行符替换,该换行符后跟相同的“b”序列(
&
表示在s//
左侧匹配的内容)。丑陋的awk
版本:)
另一个
awk
。将任何b
或b
组替换为换行符及其本身&
echo "aaaabbaaabbaa" | awk 'gsub(/b+/,"\n&")'
aaaa
bbaaa
bbaa
posix兼容,如果线路以b开头,则不会生成新线。这可能适用于您:
sed -e :a -e '/ab\(.*\)\(.\)$/!b' -e G -e 's//a\2b\1/' -e ta file
这将循环通过当前行,将任何ab
组合替换为a\nb
。它使用了保留空间的副作用,即在创建sed的新实例时,换行符始终存在
当然:
sed 's/bb*/\n&/g' file
或:
更简单,但可能取决于GNU版本的sed或bash。sed-e的/bb/\
nn/g'input.txt
我让它工作。这与您最初的尝试非常相似。我使用的是iMac,所以我很确定这同样适用于您。当您需要时,请避免在行首出现新的行
b
,并且所有这些都符合POSIX标准
$ echo -e "aaaabbaaabbaa\nbbaaaabbaaabbaa" | sed -e 's/\([^b]\)b/\1\nb/g'
aaaa
bbaaa
bbaa
bbaaaa
bbaaa
bbaa
如果您的输入字符串确实只包含
a
和b
字符,那么我认为问题将退化为用ab
替换ab
的所有实例。如果是这种情况,则您可以完全省略sed
,并使用:
在终点站:
$ str="aaaabbaaabbaa"
$ echo "${str//ab/a
> b}"
aaaa
bbaaa
bbaa
$
或者在shell脚本中:
$ cat ab.sh
#!/bin/bash
echo "${1//ab/a
b}"
$ ./ab.sh "aaaabbaaabbaa"
aaaa
bbaaa
bbaa
$
这在OSX 10.8.5上适用于我
此信息也可在由apple.com托管的网站上获得。在该页面上搜索“参数/模式”。您可以说:
$ echo aaaabbaaabbaa | sed 's/b\{1,\}/\'$'\n&/g'
aaaa
bbaaa
bbaa
或
为了使
sed
将正则表达式解释为扩展正则表达式,可以使用-E
选项:
$ echo aaaabbaaabbaa | sed -E 's/b+/\'$'\n&/g'
aaaa
bbaaa
bbaa
不需要严格地使用
-r
:sed's/b\+/\n&/g'Uhms,所以这是个好消息:当只捕获一个块时,我们可以使用&
,不需要\1
。我喜欢,谢谢!也更新了。由于&1
,在输出中的bb
之后出现了额外的1
。哎呀,我在做一些测试,但忘了删除它:)谢谢@anubhava@sam因为你在Mac OS上,我没有它要测试,你最好检查其他答案。跳过q
中间层,只使用's/b/\'$'\n'bb/g
。最短:11个字符:s/b+/\n和/g
+r
开关:sed-re's/b+/\n和/g'
就可以了。对于grep
s和-P
,但是OSX在10.8中删除了它。所以你的grepv不支持grep-P?我明白了。但是如果安装了awk
(它是正常安装的)并且做得更好,您可能会有更好的工具。我不希望用户为我安装awk。。这就是为什么没有awk加入另一个awk
版本。您使用的哪个系统没有awk?它在终端中工作正常。。。但是当我把它插入我的bash脚本时,它就不起作用了…@sam:听起来很奇怪。您的终端正在运行shell。在终端中键入的内容(应该)与shell脚本中的行完全相同。如果没有,就真的坏了。
$ str="aaaabbaaabbaa"
$ echo "${str//ab/a
> b}"
aaaa
bbaaa
bbaa
$
$ cat ab.sh
#!/bin/bash
echo "${1//ab/a
b}"
$ ./ab.sh "aaaabbaaabbaa"
aaaa
bbaaa
bbaa
$
$ echo aaaabbaaabbaa | sed 's/b\{1,\}/\'$'\n&/g'
aaaa
bbaaa
bbaa
$ echo aaaabbaaabbaa | sed $'s/b\{1,\}/\\\n&/g'
aaaa
bbaaa
bbaa
$ echo aaaabbaaabbaa | sed -E 's/b+/\'$'\n&/g'
aaaa
bbaaa
bbaa