Shell脚本:如何将文件分割成多个列?

3

我有一个看起来像这样的文件:

t1   ATGCGTCCGTAGCAG
t2   ATGCCTAGCTAGGCT

即一个名称后跟着一个(DNA)序列。我想要将这个序列分割。例如,上述序列的长度为15,我想将其分割成长度为5的3个部分。我希望有三个新文件,使得:

file1

t1   ATGCG
t2   ATGCC

文件2

t1   TCCGT
t2   TAGCT

文件3

t1   AGCAG
t2   AGGCT

我正在尝试编写一个shell脚本来完成这个任务。一种方法是使用sed '$Nq;d'命令编写for循环以获取文件的第N行,然后通过cut -c命令对其进行切割并保存到一个变量中。然后,使用cut, head和tail命令和一个额外的变量来实现它。但是,我想知道是否有更好的方法(更整洁和更快)来完成这个任务。
注:实际文件将包含1-10千行,每个序列的长度为10-50k长度,我将把序列分成长度为1-2k的序列。
3个回答

2
以下使用子字符串表示法(即字符串:起始位置:长度)来提取所需的输出:
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
    echo ${line:0:10} >> file1
    echo ${line:0:5}  ${line:10:5} >> file2
    echo ${line:0:5}  ${line:15:5} >> file3
done < "$1"

将其保存至myscript.sh文件中,并使用以下命令运行:./myscript.sh <input-file>


1
在读取后对 $line 进行二次测试以防止文件末尾没有 newline(非 POSIX 行结尾)的情况,这是一个很好的发现。 - David C. Rankin

1

一行代码解决方案,使用单个循环:

for i in $(seq 3); do cut -c1-5,$((i * 5 + 1))-$(((i + 1) * 5)) < source.txt > file$i.txt ; done

根据自己的宽度调整计算。你真的不需要逐行进行,这会非常慢。


1

awk可以帮助

awk '{for(i=1;i<=3;i++)print $1" "substr($2,5*(i-1)+1,5) >> "file"i".txt"}' inputfilename

扩展 awk
awk '{
        for(i=1;i<=3;i++)
          print $1" "substr($2,5*(i-1)+1,5) >> "file"i".txt"
     }' inputfilename

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