我有一个5000行的文本文件。每一行对应一个唯一的FILE
,所有标记为gwas*
:
CHR BP FILE
chr1 12345678 gwas1
chr2 87654321 gwas2
...
我有5000个gwas*
文件,它们都有唯一的文件名(如上面的第4列-FILE
),例如,gwas1
看起来像这样:
CHR BP
chr1 12345678
chr1 12345679
chr1 12356777
...
我想从每个gwas*
文件中提取所有行,其中BP
值在文本文件中的BP
值的500,000(上下)内。CHR
的值也必须匹配。例如:
gwas1
文本文件中CHR
的值为chr1
,BP
的值为12,345,678
。- 我想从
gwas1
中提取所有行,这些行在CHR
列中具有chr1
值,并且在11,845,678
(此值从文本文件中的BP
值下降50万)和12,845,678
(此值从文本文件中的BP
值下降50万)之间具有BP
值。
我可以使用以下代码对单个gwas文件手动执行此操作(但不使用5000行文本文件):
export CHR="chr11"
export BP=107459522
export WINDOW=500000
awk -v CHR=$CHR -v BP_pos=$(($BP + $WINDOW)) -v BP_neg=$(($BP - $WINDOW)) 'BEGIN{FS=OFS="t"}FNR==1 || ($1 == CHR && $2 < BP_pos && $2 > BP_neg )' gwas1 > gwas1_extract
我希望能够为我的文本文件中列出的所有5,000 gwas文件做到这一点。每个gwas文件的输出应该只包括以下行:(i)列CHR
包含该文件的值(例如,对于gwas1
,这是chr1
),BP
列包含的值在BP
列文本文件中给定的值的500,000范围内(对于gwas1
,这是12,345,678
两侧的500,000)。输出文件如下所示:
CHR BP
chr1 12345678
chr1 12345679
chr1 12356777
awk --version
= GNU Awk 4.0.2
任何帮助将是伟大的!
示例输入:
$ cat file.txt
CHR BP FILE
chr1 12345678 gwas1
chr2 87654321 gwas2
chr4 99999999 gwas4 # file gwas4 does not exist
$ cat gwas1
CHR BP
chr1 12345678 # match
chr1 12345679 # match
chr1 12356777 # match
chr1 99999999
$ cat gwas2
CHR BP
chr1 12345678
chr2 87650000 # match
$ cat gwas3 # no matches since gwas3 not in file.txt
CHR BP
chr3 2134234
注意:实际文件中不存在注释
单个GNU awk
脚本处理所有gwas*
文件:
awk -v diff=500000 '
function abs(x) { return (x < 0.0) ? -x : x }
BEGIN { FS=OFS="t" }
FNR==NR { if (FNR>1) # 1st file; skip header and ...
bp_list[$3][$1]=$2 # save contents in our bp_list[FILE][CHR] array
next
}
FNR==1 { close(outfile) # close previous output file
fn=FILENAME
outfile=fn "_extract"
if (fn in bp_list) # if fn in 1st file then ...
print > outfile # print header else ...
else # skip to next input file; also addresses gwas* matching on gwas*_extract files, ie, these will be skipped, too
nextfile
next
}
fn in bp_list { if ($1 in bp_list[fn] && abs(bp_list[fn][$1] - $2) <= diff)
print > outfile
}
' file.txt gwas*
注意:要求GNU awk
用于多维数组
由此产生:
$ head gwas*extract
==> gwas1_extract <==
CHR BP
chr1 12345678
chr1 12345679
chr1 12356777
==> gwas2_extract <==
CHR BP
chr2 87650000
任何帮助都很棒!
你可能会发现GNUAWK
的ARGC和ARGV在你的情况下是有用的
程序可以修改ARGC和ARGV中的元素。每次醒来到达输入文件的末尾时,它使用ARGV的下一个元素作为下一个输入文件的名称。通过存储一个不同的字符串,程序可以更改要读取的文件。使用"产生绯闻;代表标准输入。存储额外的元素并增加ARGC导致读取其他文件。
从而允许您根据文件的内容选择要处理的文件。