根据列值将文件拆分为行

根据列值将文件拆分为行

输入文件看起来像这样:

chr1    1    G    300
chr1    2    A    500
chr1    3    C    200
chr4    1    T    35
chr4    2    G    400
chr4    3    C    435
chr4    4    A    223
chr4    5    T    400
chr4    6    G    300
chr4    7    G    340
chr4    8    C    400

实际文件太大而无法处理,因此我想输出一个较小的文件,按特定范围内的染色体(第1列)和位置(第2列)过滤。

例如,我正在寻找一个 Linux 命令(sed、awk、grep 等),该命令将从chr4位置 3 到 7 进行过滤。所需的最终输出是:

chr4    3    C    435
chr4    4    A    223
chr4    5    T    400
chr4    6    G    300
chr4    7    G    340

我不想修改原始文件。

答案1

潜在未排序输入文件的解决方案:

sort -k1,1 -k2,2n file | awk '$1=="chr4" && $2>2 && $2<8'

输出:

chr4    3    C    435
chr4    4    A    223
chr4    5    T    400
chr4    6    G    300
chr4    7    G    340

如果输入文件已排序,则足以使用:

awk '$1=="chr4" && $2>2 && $2<8' file

答案2

awk可能是完成这项工作的最佳工具。一种简单的解决方案与已经给出的解决方案类似,但实际上使用您指定的参数:

awk '$1=="chr4" && $2>=3 && $2<=7'

您可能更喜欢更通用的解决方案,其中涉及将awk命令放入 shell 脚本中,如下:

#!/bin/sh
if [ "$#" -lt 3 ]
then
        echo "Usage:    $0 chromosome low_position high_position"
        exit 1
fi
chr="$1"
lo="$2"
hi="$3"
shift 3
awk -vchromo="$chr" -vpos1="$lo" -v pos2="$hi" '$1==chromo && $2>=pos1 && $2<=pos2' "$@"

如果运行的参数少于三个,它会提醒您参数应该是什么,然后退出。否则,它将前三个参数保存到 shell 变量中,然后将它们移出参数列表。然后它调用awk,将 shell 变量值作为awk变量传递。

您可以通过以下任一方式调用它:

./myscript chr4 3 7   data

或者

./myscript chr4 3 7 < data

或者

(一些其他进程)| ./myscript chr4 3 7
并且,无论如何,将输出重定向到带有>.

答案3

您可以使用 grep 完成此操作:

grep -e '^chr4\s\+[3-7]' input

其中表达式为:以 chr4(一个或多个空格字符)^chr4开头的行,匹配 3 到 7 范围内的一位数字。\s\+[3-7]

也许更有用的是使用headtail给你尽可能多的行,而不是匹配它们grep(仅使用 grep 来匹配第一列)。

grep -e '^chr4\s\+' input| tail -n +3| head -n 5

grep匹配以 开头的行chr4tail给出从第 3 行开始的行,并使用head限制输出到前 5 行(第 3 行到第 7 行)。

答案4

您可以使用该split实用程序。

split -p 'chr4    (3|8)' -a 1 my_file output
  • split将一个文件分成多个部分(基本上是 的逆cat
  • p根据扩展正则表达式 'chr4 (3|8)' 进行拆分
  • -a 1使用单个字符为创建的文件添加后缀
  • output是每个创建的文件的前缀名称

现在该文件outputb将包含您所需的输出。您还可以修改它以将每个色酮放入其自己的文件中。

相关内容