使用sed或VIM将空格替换为新行

4
我有以下数据。
1455931_at Chrna3 1420468_at Asb17 1445520_at −−− 1436717_x_at Hbb−y 1431788_at Fabp12 1458975_at −−−

使用sed或VIM编辑器,我该如何将其更改为

1455931_at Chrna3 
1420468_at Asb17 
1445520_at −−− 
1436717_x_at Hbb−y 
1431788_at Fabp12 
1458975_at −−−

所有包含_at的单词都将成为每行的第一个单词。每行由成对的 _at 和 gene 术语组成。

7个回答

10
在Vim中,我会这样做:
:%s/ /^M/g
:g/_at/j

在输入^M时,需要按下Control-V(Windows上为Control-Q),然后再按Enter/Return键。

这假定词元之间只有单个空格; 如@Floris所建议的,您可以使用s/ \+/^M/g将多个连续空格转换为单个换行符。或者,您可以使用s/\v\s+/^M/g来处理包括制表符和字面空格字符在内的任何连续空格。


2
只要有一个空格,这个命令就可以工作。也许第一个命令应该改成 %s/ \+/^M/g?它可以处理额外的空白字符。 - Floris

2

惊人但真实:

sed 's/\([^ ]*\) \(.[^ ]* \)/\1 \2\
> /g' <<<"1455931_at Chrna3 1420468_at Asb17 1445520_at −−− 1436717_x_at Hbb−y 1431788_at Fabp12 1458975_at −−−"
1455931_at Chrna3 
1420468_at Asb17 
1445520_at −−− 
1436717_x_at Hbb−y 
1431788_at Fabp12 
1458975_at −−−

换句话说,我使用的 sed 字符串中有一个物理回车符(>是由控制台添加的):
sed 's/\([^ ]*\) \(.[^ ]* \)/\1 \2\
> /g'

您可以尝试一下其他表达方式(目前我假设是平衡的对,但如果您特别想匹配第一个字符串末尾的at,则可以这样做)。


可以在VIM里面使用吗? 我尝试在VIM的可视模式下运行了这段代码,但是失败了: :'<,'>!sed sed 's/\([^ ]*\) \(.[^ ]* \)/\1 \2\ ENTER 但添加 /g' 前失败了。 - pdubois
在Bash或其他POSIX shell中,您还可以利用POSIX字符串,并将其类型化为$'...\\\n/g' - Mark Reed
@MarkReed - 三个反斜杠表示换行?你能解释一下吗?谢谢。 - Floris
@Floris - $'\\\n' 在 shell 中被转换成与您的答案相同的序列:反斜杠后跟一个换行符;sed 无法区分。在 POSIX 字符串 $'...' 中,\\ 变成了一个字面上的反斜杠,\n 变成了一个换行符,因此将它们放在一起,您就会得到 \\\n 表示反斜杠 + 换行符。 - Mark Reed

1
对于你的例子,
sed -e 's/\(_at [0-9a-zA-Z−]*\) /\1\n/g'

1
sed 's/\(_at[[:blank:]]\{1,\}[^[:blank:]\{1,\}\)\([[:blank:]]\)/\1\
\2/g' YourFile

这允许任何“空格”作为分隔符,并且可以出现一次或多次,最后一行没有\n。在字符串的任何部分以_at结尾后,取1个“单词”,不是单词的交替(我的解释)。这不能避免在两个单独的行上写入2个“_at”(如果有一个缺少/空白的单词的情况)。

1
这是一个与编程有关的HTML代码,展示了一个awk的解决方案。
awk '{for (i=1;i<=NF;i+=2) print $i,$(i+1)}' file
1455931_at Chrna3
1420468_at Asb17
1445520_at ...
1436717_x_at Hbb.y
1431788_at Fabp12
1458975_at ...

这将打印两个字段。

另一个版本:

awk '{printf $0 FS;getline;print}' RS=" " file

1
你可以使用这个工具来查找所有以“_at”结尾的第一个单词和第二个单词组成的两个单词对。
grep -oP '\S+_at\s+\S+' file

或者,将每两个单词之间换行:

tr -s '[:blank:]' '\n' < file | paste -d " " - -

1
使用sed命令:s/ /\n/g; s/_at\n/_at /g。也许有更优雅的解决方案,但这个方案已经可以胜任了。

1
看起来很优雅,但在我的 sed 版本(Mac OS)中,\n 无法识别。 - Floris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接