如何在序列标题之后和实际序列之前添加断行?

如何在序列标题之后和实际序列之前添加断行?

我有一个包含多个序列的文件,问题是 id 后面有一个空格,然后是实际序列,我想在 id 和实际序列之间添加一个换行符。

这就是我所拥有的:

UniRef90_Q8YC41 Putative binding protein BMEII0691 MNRFIAFFRSVFLIGLVATAFGRACA

我想要的效果如下:

UniRef90_Q8YC41 Putative binding protein BMEII0691
MNRFIAFFRSVFLIGLVATAFGRACA

如果可能的话我宁愿它看起来像这样

UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

答案1

  • 使用awk,以 作为分隔符打印第一个和最后一个字段\n

    awk '{printf "%s\n%s\n", $1, $NF}' file.txt
    
  • 使用sed,在匹配时捕获第一个和最后一个字段并在替换中使用:

    sed -E 's/([^[:blank:]]+).*[[:blank:]]([^[:blank:]]+)$/\1\n\2/' file.txt
    
  • perl的逻辑类似sed

    perl -pe 's/^([^\s]+).*\s([^\s]+)/$1\n$2/' file.txt
    
  • 使用bash较慢的方法,从每一行创建一个数组并打印数组中的第一个和最后一个元素,并用以下方式分隔它们\n

    while read -ra line; do printf '%s\n%s\n' "${line[0]}" \
           "${line[$((${#line[@]]}-1))]}"; done <file.txt
    
  • 使用python,创建一个包含每行用空格分隔的元素的列表,然后打印列表中的第一个和最后一个元素,并用 分隔\n

    #!/usr/bin/env python3
    with open("file.txt") as f:
        for line in f:
            line = line.split()
            print(line[0]+'\n'+line[-1])
    

例子:

$ cat file.txt                               
UniRef90_Q8YC41 Putative binding protein BMEII0691 MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41 Putative binding protein BMEII0691 MNRFIAFFRSVFLIGLVATAFGRACA

$ awk '{printf "%s\n%s\n", $1, $NF}' file.txt                             
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

$ sed -E 's/([^[:blank:]]+).*[[:blank:]]([^[:blank:]]+)$/\1\n\2/' file.txt
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

$ perl -pe 's/^([^\s]+).*\s([^\s]+)/$1\n$2/' file.txt
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA


$ while read -ra line; do printf '%s\n%s\n' "${line[0]}" "${line[$((${#line[@]]}-1))]}"; done <file.txt
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

>>> with open("file.txt") as f:
...     for line in f:
...         line = line.split()
...         print(line[0]+'\n'+line[-1])
... 
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

答案2

Ruby 版本

File.open(ARGV[0]) do |f|
  f.each do |line|
    puts "#{line.partition(' ')[0] + "\n" + line.rpartition(' ')[-1]}"
  end
end

将其保存为任意名称并运行line_breaker.rbruby line_breaker.rb file.txt文件.txt是存储序列的文件。

答案3

在这个答案中:

  1. bash+xargs单行
  2. python单行
  3. Ruby单行

1. bash+xargs版本。

$> cat input_file.txt  | xargs -L 1 bash -c 'for i; do : ; done ; echo $1;echo $i' bash 

这实际上是将每一行作为命令行参数传递给 bash,循环直到我们得到最后一行,然后将它们回显出来。

演示:

$> cat input_file.txt                                                                     
UniRef90_Q8YC41 Putative binding protein BMEII0691 MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41 Putative binding protein BMEII0691 MNRFIAFFRSVFLIGLVATAFGRACA
$> cat input_file.txt  | xargs -L 1 bash -c 'for i; do : ; done ; echo $1;echo $i' bash   
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

更短的版本:

$> cat input_file.txt  | xargs -L 1 bash -c 'echo $1;echo ${@: -1}' bash                  
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

2.python单行

这行代码组装了一个字符串列表,该列表基本上由第一个单词 + 换行符 + 最后一个单词组成。最后,它将所有列表项打印为一个以换行符连接的字符串。

python -c 'import sys ; print "\n".join([ l.split()[0] + "\n" + l.split()[-1]  for l in sys.stdin ])' < input_file.txt

使用演示:

$ python -c 'import sys ; print "\n".join([ l.split()[0] + "\n" + l.split()[-1]  for l in sys.stdin ])' < input_file.txt
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

3. Ruby 单行代码

在此行中,-n标志用作while gets . . . end循环。$_保存读取的每一行的值,因此对于每一行,我们将其分成一个单词数组,然后打印第一个和最后一个单词。

$ ruby -ne 'words=$_.split(); puts words[0],words[-1]' < input_file.txt                   
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA
UniRef90_Q8YC41
MNRFIAFFRSVFLIGLVATAFGRACA

相关内容