GNU parallel和awk之间的冲突(拆分列并筛选某些行)
我正在处理许多大型gz文件,如下面的示例(这里只显示前5行) 下面是我想要的输出 在这里,我将第二列拆分为“z”,并根据第二列和第三列(拆分后)选择行($2==1,$3>20000)。我将其保存为txt。下面的命令工作正常GNU parallel和awk之间的冲突(拆分列并筛选某些行),awk,gnu-parallel,Awk,Gnu Parallel,我正在处理许多大型gz文件,如下面的示例(这里只显示前5行) 下面是我想要的输出 在这里,我将第二列拆分为“z”,并根据第二列和第三列(拆分后)选择行($2==1,$3>20000)。我将其保存为txt。下面的命令工作正常 zcat InputData.txt.gz | awk -F "_" '$1=$1' | awk '{if ($2==1 && $3>20000) {print}}' > OutputData.txt ENSG00000223972.4
zcat InputData.txt.gz | awk -F "_" '$1=$1' | awk '{if ($2==1 && $3>20000) {print}}' > OutputData.txt
ENSG00000223972.4 1 54421 A G b37 42552 28 28 0.039548 0.680357 0.0741142 0.179725
ENSG00000223972.4 1 54490 G A b37 42621 112 120 0.176471 0.00824733 0.247533 0.093081
但是我想使用GNU并行来加速这个过程,因为我有很多大的gz文件要处理。然而,GNU parallel和awk之间似乎存在一些冲突,可能是在报价方面
我尝试按如下所示单独定义awk选项,但它在输出文件中没有给出任何信息
在下面的命令中,我只在一个输入文件上运行并行程序。但是我想在多个输入文件上运行,并保存多个输出文件,每个输出文件对应一个输入文件
比如说,
InputData_1.txt.gz到OutputData_1.txt
InputData_2.txt.gz到OutputData_2.txt
awk1='{ -F "_" "$1=$1" }'
awk2='{if ($2==1 && $3>20000) {print}}'
parallel "zcat {} | awk '$awk1' |awk '$awk2' > OutputData.txt" ::: InputData.txt.gz
有人对这项任务有什么建议吗?
多谢各位
根据@karakfa的建议,这是一个解决方案
chr=1
RegionStart=10000
RegionEnd=50000
zcat InputData.txt.gz | awk -v chr=$chr -v start=$RegionStart -v end=$RegionEnd '{split($2,NewDF,"_")} NewDF[1]==chr && NewDF[2]>start && NewDF[2]<end {gsub("_"," ",$2) ; print > ("OutputData.txt")}'
#This also works using parallel
awkbody='{split($2,NewDF,"_")} NewDF[1]==chr && NewDF[2]>start && NewDF[2]<end {gsub("_"," ",$2) ; print > ("{}_OutputData.txt")}'
parallel "zcat {} | awk -v chr=$chr -v start=$RegionStart -v end=$RegionEnd '$awkbody' " ::: InputData_*.txt.gz
chr=1
RegionStart=10000
区域编号=50000
zcat InputData.txt.gz | awk-v chr=$chr-v start=$RegionStart-v end=$RegionEnd'{split($2,NewDF,“”)}NewDF[1]==chr&&NewDF[2]>start&&NewDF[2](“OutputData.txt”)}
#这也适用于使用并行
awkbody='{split($2,NewDF,“{”)}NewDF[1]==chr&&NewDF[2]>start&&NewDF[2](“{}\u OutputData.txt”)}'
并行“zcat{}awk-v chr=$chr-v start=$RegionStart-v end=$RegionEnd'$awkbody':::InputData_*.txt.gz
输入文件
InputData\u 1.txt.gz
的输出文件名将是InputData\u 1.txt.gz\u OutputData.txt
一种方法是使用split
$ awk '{split($2,f2,"_")}
f2[1]==1 && f2[2]>20000 {gsub("_"," ",$2); print > (FILENAME".output")}' file
但是,如果您通过stdin提供数据,
awk
将不会捕获要写入的文件名。您需要将其作为变量传递给脚本……一种方法是使用split
$ awk '{split($2,f2,"_")}
f2[1]==1 && f2[2]>20000 {gsub("_"," ",$2); print > (FILENAME".output")}' file
但是,如果您通过stdin提供数据,
awk
将不会捕获要写入的文件名。您需要将其作为一个变量传递给脚本,也许…简单的解决方案是将过滤器组合成单个awk
脚本,而不是且只有并行才能工作
下面是一个示例解决方案,它只扫描整个input.txt
一次(性能的两倍):
说明:
BEGIN{FS=“[]*[\u]?”}
将字段分隔符设置为多个“或””\
$2==1&&$7>20000{print}
仅打印第二个字段==1和7nt字段>2000的行
调试脚本示例:
BEGIN{FS="[ ]*[_]?"}
{
for(i = 1; i <= NF; i++) printf("$%d=%s%s",i, $i, OFS);
print "";
}
$2==1 && $7 > 20000 {print}
简单的解决方案是将过滤器组合到单个
awk
脚本中,然后并且只有并行才能工作
下面是一个示例解决方案,它只扫描整个input.txt
一次(性能的两倍):
说明:
BEGIN{FS=“[]*[\u]?”}
将字段分隔符设置为多个“或””\
$2==1&&$7>20000{print}
仅打印第二个字段==1和7nt字段>2000的行
调试脚本示例:
BEGIN{FS="[ ]*[_]?"}
{
for(i = 1; i <= NF; i++) printf("$%d=%s%s",i, $i, OFS);
print "";
}
$2==1 && $7 > 20000 {print}
得出结论:
结论:为了避免处理引用问题,只需编写一个小脚本或函数(记住导出函数-f)并让GNU并行调用它,可能会更容易
因此:
得出结论:
结论:为了避免处理引用问题,只需编写一个小脚本或函数(记住导出函数-f)并让GNU并行调用它,可能会更容易
因此:
不考虑并行,但你不必使用两个awk,你可以让
或空白
作为awk的FS。我尝试了这个awk-F“”$1=$1'{if($2==1&$3>20000){print}}
,但是这两个awk都不起作用,因为与parallel和awk之间的一些交互相比,使用存储在变量中的awk脚本更有可能成为问题。您是否尝试过不并行地执行zcat{}|awk'$awk1'| awk'$awk2'
?怎么样?一旦你将变量周围的引号改为双引号而不是单引号,让它们展开,那么它是如何进行的呢?一旦你迭代地修复了这些问题,然后试着用parallel运行它。同意上面的评论,但是你评论说我尝试了这个awk-F““'$1=$1”。。你的意思是像你上面的代码那样,$2==1
?祝你好运。@EdMorton,你说得对。没有并行的awk'$awk1'也不起作用。关于并行,但你不必使用两个awk,你可以让
或whitespaces
作为awk的FS。我尝试了这个awk-F“'$1=$1'{if($2==1&$3>20000){print}},但是这两个awk都不起作用,因为与parallel和awk之间的一些交互相比,使用存储在变量中的awk脚本更有可能成为问题。您是否尝试过不并行地执行zcat{}|awk'$awk1'| awk'$awk2'
?怎么样?一旦你将变量周围的引号改为双引号而不是单引号,让它们展开,那么它是如何进行的呢?一旦你迭代地修复了这些问题,然后试着用parallel运行它。同意上面的评论,但是你评论说我尝试了这个awk-F““'$1=$1”。。你的意思是像你上面的代码那样,$2==1
?祝你好运。@EdMorton,你说得对。没有平行线的awk“$awk1”也不起作用。
$1=gene $2=id $3=variant $4=id $5=tss $6=distance $7=ma $8=samples $9=ma $10=count $11=maf $12=pval $13=nominal $14=slope $15=slope $16=se
$1=ENSG00000223972.4 $2=1 $3=13417 $4=C $5=CGAGA $6=b37 $7=1548 $8=50 $9=50 $10=0.0766871 $11=0.735446 $12=-0.0468165 $13=0.138428
$1=ENSG00000223972.4 $2=1 $3=17559 $4=G $5=C $6=b37 $7=5690 $8=7 $9=7 $10=0.00964187 $11=0.39765 $12=-0.287573 $13=0.339508
$1=ENSG00000223972.4 $2=1 $3=54421 $4=A $5=G $6=b37 $7=42552 $8=28 $9=28 $10=0.039548 $11=0.680357 $12=0.0741142 $13=0.179725
ENSG00000223972.4 1_54421_A_G_b37 42552 28 28 0.039548 0.680357 0.0741142 0.179725
$1=ENSG00000223972.4 $2=1 $3=54490 $4=G $5=A $6=b37 $7=42621 $8=112 $9=120 $10=0.176471 $11=0.00824733 $12=0.247533 $13=0.093081
ENSG00000223972.4 1_54490_G_A_b37 42621 112 120 0.176471 0.00824733 0.247533 0.093081
doit() {
zcat "$1" |
awk -F "_" '$1=$1' |
awk '{if ($2==1 && $3>20000) {print}}'
}
export -f doit
parallel 'doit {} > {=s/In/Out/; s/.gz//=}' ::: InputData*.txt.gz