我从一个文件中创建各种文本文件,像这样:
Chrom_x,Pos,Ref,Alt,RawScore,PHRED,ID,Chrom_y
10,113934,A,C,0.18943,5.682,rs10904494,10
10,126070,C,T,0.030435000000000007,3.102,rs11591988,10
10,135656,T,G,0.128584,4.732,rs10904561,10
10,135853,A,G,0.264891,6.755,rs7906287,10
10,148325,A,G,0.175257,5.4670000000000005,rs9419557,10
10,151997,T,C,-0.21169,0.664,rs9286070,10
10,158202,C,T,-0.30357,0.35700000000000004,rs9419478,10
10,158946,C,T,2.03221,19.99,rs11253562,10
10,159076,G,A,1.403107,15.73,rs4881551,10
我想做的是提取,在bash中,两个值之间的所有值:
gawk '$6>=0 && $NF<=5 {print $0}' file.csv > 0_5.txt
创建文件从6到10,从11到15…从95到100。我想用
之类的东西创建一个循环#!/usr/bin/env bash
n=( 0,5,6,10...)
if i in n:
gawk '$6>=n && $NF<=n+1 {print $0}' file.csv > n_n+1.txt
等等
我如何将此转换为循环并创建具有此特定值的文件。
虽然可以使用shell循环向awk脚本提供输入,但也可以直接使用awk将值本地拆分为存储桶,并将行写入这些"存储桶";文件本身:
awk -F, ' NR > 1 {
i=int((($6 - 1) / 5))
fname=(i*5) "_" (i+1)*5 ".txt"
print $0 > fname
}' < input
代码跳过标题行(NR > 1
),然后计算一个"桶索引";用第六列的值除以五。然后通过将该索引(及其增量)乘以5来构造文件名。然后将整行打印到该文件名。
for((i=0; i <= 19; i++))
do
floor=$((i * 5))
ceiling=$(( (i+1) * 5))
awk -F, -v floor="$floor" -v ceiling="$ceiling"
'NR > 1 && $6 >= floor && $6 < ceiling { print }' < input
> "${floor}_${ceiling}.txt"
done
基本思想是一样的;这里,我们使用外部循环创建桶索引,然后将范围作为floor和ceiling变量传递给awk。我们只要求awk打印匹配的行;shell将awk的输出作为重定向到适当文件的方式捕获。