7

我有一个包含以下内容的文件:

aaaabbaaabbaa

我需要一个像这样的输出:

aaaa
bbaaa
bbaa

我需要在第一次出现之前添加一个新行'b'。我只需要在 bash 中使用 SED 命令

我正在使用以下命令。我知道它现在是完美的..

谁能告诉我比这更好的命令。请注意我只需要在 bash 中使用的 SED 命令

sed -i.bak  -e 's/bb/qbb/g' input.txt  
sed -i.bak  -e 's/qbb/\'$'\nbb/g' input.txt
4

9 回答 9

10

sed

$ echo "aaaabbaaabbaa" | sed -r 's/([b]+)/\n\1/g'
aaaa
bbaaa
bbaa

sed -r允许使用 捕获块()并使用\1. 它捕获它的块[b]+,意思是"one or more b's",并在新行之前将其打印回来。

正如我看到您正在使用sed -i的那样,这样做也很好:

sed -i.bak -r 's/([b]+)/\n\1/g' input.txt

此外,更容易(感谢格伦杰克曼!)

$ echo "aaaabbaaabbaa" | sed 's/b\+/\n&/g'
aaaa
bbaaa
bbaa

它替换“b”的所有序列并用换行符替换它,后跟相同的“b”序列(&表示在左侧匹配的任何内容s///)。

于 2013-10-25T12:35:45.630 回答
3

grep -oP使用前瞻正则表达式会更容易:

echo 'aaaabbaaabbaa' | grep -oP '.+?[^b](?=(b|$))'

aaaa
bbaaa
bbaa
于 2013-10-25T12:35:09.600 回答
2

如果您的输入字符串确实只包含aandb字符,那么我认为问题会退化为简单替换abwith的所有实例a<newline>b。如果是这种情况,那么您可以sed完全省略并在 bash 中使用Shell Parameter Expansion 功能

在终端:

$ 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 托管的bash 手册页上找到。在该页面上搜索“参数/模式”。

于 2013-12-12T05:27:28.490 回答
1

这可能对您有用:

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

或者:

sed 's/bb*/'"\n"'&/g' file

容易得多,但可能取决于 sed 或 bash 的 GNU 版本。

于 2013-12-06T13:33:51.487 回答
1

你可以说:

$ echo aaaabbaaabbaa | sed 's/b\{1,\}/\'$'\n&/g'
aaaa
bbaaa
bbaa

或者

$ echo aaaabbaaabbaa | sed $'s/b\{1,\}/\\\n&/g'
aaaa
bbaaa
bbaa

为了将sed正则表达式解释为扩展正则表达式,您可以使用以下-E选项:

$ echo aaaabbaaabbaa | sed -E 's/b+/\'$'\n&/g'
aaaa
bbaaa
bbaa
于 2013-12-12T10:12:35.717 回答
1

当您想避免在行首b出现新行并且所有这些都符合 POSIX 标准时。

$ echo -e "aaaabbaaabbaa\nbbaaaabbaaabbaa" | sed -e 's/\([^b]\)b/\1\nb/g'
aaaa
bbaaa
bbaa
bbaaaa
bbaaa
bbaa
于 2013-12-10T19:03:48.953 回答
1
echo "aaaabbaaabbaa\nbbaabba" | sed 's/\([^b]\)b/\1\
b/g'

aaaa
bbaaa
bbaa
bbaa
bba

posix 兼容,如果行以 ab 开头,则不创建新行

于 2013-12-06T10:45:31.090 回答
1

一个丑陋的awk版本:)

echo "aaaabbaaabbaa" | awk '{for (i=1;i<=NF;i++) {printf ($i=="b" && f!="b" ?"\n":"")"%s",$i; f=$i}} END {print ""}' FS=
aaaa
bbaaa
bbaa

一个gnu awk版本

echo "aaaabbaaabbaa" | awk '{$1=$1} NR>1 {$0=RS $0;} 1' RS="bb"
aaaa
bbaaa
bbaa

另一个awk. 用换行符和本身替换任何b或组b&

echo "aaaabbaaabbaa" | awk 'gsub(/b+/,"\n&")'
aaaa
bbaaa
bbaa
于 2013-10-25T12:55:30.690 回答
1

sed -e 's/bb/\nn/g' input.txt

我得到了这个工作。这与您最初的尝试非常相似。我在 iMac 上,所以我很确定这同样适用于你。

于 2013-12-10T01:37:47.907 回答