根据列值将文件拆分为行

coo*_*490 3 linux grep sed awk text-processing

输入文件如下所示:

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
Run Code Online (Sandbox Code Playgroud)

实际文件太大无法处理,所以我想输出一个较小的文件,按特定范围内的染色体(第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
Run Code Online (Sandbox Code Playgroud)

我不想修改原始文件。

Rom*_*est 9

可能未排序的输入文件的解决方案:

sort -k1,1 -k2,2n file | awk '$1=="chr4" && $2>2 && $2<8'
Run Code Online (Sandbox Code Playgroud)

输出:

chr4    3    C    435
chr4    4    A    223
chr4    5    T    400
chr4    6    G    300
chr4    7    G    340
Run Code Online (Sandbox Code Playgroud)

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

awk '$1=="chr4" && $2>2 && $2<8' file
Run Code Online (Sandbox Code Playgroud)

  • OTOH,如果文件很大,最好对awk的输出而不是awk的输入进行排序。 (2认同)

Sco*_*ott 7

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

awk '$1=="chr4" && $2>=3 && $2<=7'
Run Code Online (Sandbox Code Playgroud)

您可能更喜欢将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' "$@"
Run Code Online (Sandbox Code Playgroud)

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

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

./myscript chr4 3 7   data
Run Code Online (Sandbox Code Playgroud)

或者

./myscript chr4 3 7 < data
Run Code Online (Sandbox Code Playgroud)

或者

(some_other_process) | ./myscript chr4 3 7
并且,无论如何,将输出重定向到带有>.