优化查找大压缩文件的脚本
Optimising my script which lookups into a big compressed file
我又来了!我想优化我的 bash 脚本以减少每个循环所花费的时间。
基本上它的作用是:
- 从 tsv 获取信息
- 使用该信息通过 awk 查找文件
- 打印行并导出
我的问题是:
1)文件是60GB的压缩文件:我需要一个软件来解压它(我现在正在尝试解压它,不确定我是否有足够的space)
2) 反正要研究很久
我的改进想法:
- 0) 如前所述,如果可能我会解压文件
使用 GNU 与 parallel -j 0
./extract_awk_reads_in_bam.sh ::: reads_id_and_pos.tsv
并行,但我不确定它是否按预期工作?我将每项研究的时间从 36 分钟减少到 16 分钟,所以只是 2.5 倍? (我有16核)
我在想(但它可能对 GNU 来说是多余的?)拆分
我的信息列表要查看几个文件以启动它们
并行
- 按读取名称对 bam 文件进行排序,并在完成后退出 awk
找到 2 个匹配项(不能超过 2 个)
这是我的 bash 脚本的其余部分,我非常愿意接受改进它的想法,但我不确定我是否是编程方面的超级明星,所以保持简单可能会有帮助? :)
我的 bash 脚本:
#/!bin/bash
while IFS=$'\t' read -r READ_ID_WH POS_HOTSPOT; do
echo "$(date -Iseconds) read id is : ${READ_ID_WH} with position ${POS_HOTSPOT}" >> /data/bismark2/reads_done_so_far.txt
echo "$(date -Iseconds) read id is : ${READ_ID_WH} with position ${POS_HOTSPOT}"
samtools view -@ 2 /data/bismark2/aligned_on_nDNA/bamfile.bam | awk -v read_id="$READ_ID_WH" -v pos_hotspot="$POS_HOTSPOT" '==read_id {printf [=10=] "\t%s\twh_genome",pos_hotspot}'| head -2 >> /data/bismark2/export_reads_mapped.tsv
done <""
我的 tsv 文件格式如下:
READ_ABCDEF\t1200
非常感谢++
TL;DR
您的新脚本将是:
#!/bin/bash
samtools view -@ 2 /data/bismark2/aligned_on_nDNA/bamfile.bam | awk -v st="" 'BEGIN {OFS="\t"; while (getline < st) {st_array[]=}} {if ( in st_array) {print [=10=], st_array[], "wh_genome"}}'
您正在读取每个输入的整个文件。最好同时寻找所有这些。首先提取有趣的读数,然后在此子集上应用第二个转换。
samtools view -@ 2 "$bam" | grep -f <(awk -F$'\t' '{print }' "") > "$sam"
在这里,您将使用 samtools
获取所有读数,并搜索出现在 grep
的 -f
参数中的所有术语。该参数是一个包含搜索输入文件第一列的文件。输出是一个 sam
文件,其中仅包含搜索输入文件中列出的读数。
awk -v st="" 'BEGIN {OFS="\t"; while (getline < st) {st_array[]=}} {print [=12=], st_array[], "wh_genome"}' "$sam"
最后,使用 awk 添加额外信息:
- 以awk开头打开搜索输入文件,将其内容读入数组(
st_array
)
- 将输出字段分隔符设置为制表符
- 遍历 sam 文件并添加来自预填充数组的额外信息。
我提出这个模式是因为我觉得 grep
在搜索方面比 awk
快,但单独使用 awk 可以获得相同的结果:
samtools view -@ 2 "$bam" | awk -v st="" 'BEGIN {OFS="\t"; while (getline < st) {st_array[]=}} {if ( in st_array) {print [=13=], st_array[], "wh_genome"}}'
在这种情况下,你只需要添加一个条件来识别有趣的阅读并摆脱grep
。
在任何情况下,您都需要多次重新读取文件或在使用它之前解压缩它。
我又来了!我想优化我的 bash 脚本以减少每个循环所花费的时间。 基本上它的作用是:
- 从 tsv 获取信息
- 使用该信息通过 awk 查找文件
- 打印行并导出
我的问题是: 1)文件是60GB的压缩文件:我需要一个软件来解压它(我现在正在尝试解压它,不确定我是否有足够的space) 2) 反正要研究很久
我的改进想法:
- 0) 如前所述,如果可能我会解压文件
使用 GNU 与
parallel -j 0 ./extract_awk_reads_in_bam.sh ::: reads_id_and_pos.tsv
并行,但我不确定它是否按预期工作?我将每项研究的时间从 36 分钟减少到 16 分钟,所以只是 2.5 倍? (我有16核)我在想(但它可能对 GNU 来说是多余的?)拆分 我的信息列表要查看几个文件以启动它们 并行
- 按读取名称对 bam 文件进行排序,并在完成后退出 awk 找到 2 个匹配项(不能超过 2 个)
这是我的 bash 脚本的其余部分,我非常愿意接受改进它的想法,但我不确定我是否是编程方面的超级明星,所以保持简单可能会有帮助? :)
我的 bash 脚本:
#/!bin/bash
while IFS=$'\t' read -r READ_ID_WH POS_HOTSPOT; do
echo "$(date -Iseconds) read id is : ${READ_ID_WH} with position ${POS_HOTSPOT}" >> /data/bismark2/reads_done_so_far.txt
echo "$(date -Iseconds) read id is : ${READ_ID_WH} with position ${POS_HOTSPOT}"
samtools view -@ 2 /data/bismark2/aligned_on_nDNA/bamfile.bam | awk -v read_id="$READ_ID_WH" -v pos_hotspot="$POS_HOTSPOT" '==read_id {printf [=10=] "\t%s\twh_genome",pos_hotspot}'| head -2 >> /data/bismark2/export_reads_mapped.tsv
done <""
我的 tsv 文件格式如下:
READ_ABCDEF\t1200
非常感谢++
TL;DR
您的新脚本将是:
#!/bin/bash
samtools view -@ 2 /data/bismark2/aligned_on_nDNA/bamfile.bam | awk -v st="" 'BEGIN {OFS="\t"; while (getline < st) {st_array[]=}} {if ( in st_array) {print [=10=], st_array[], "wh_genome"}}'
您正在读取每个输入的整个文件。最好同时寻找所有这些。首先提取有趣的读数,然后在此子集上应用第二个转换。
samtools view -@ 2 "$bam" | grep -f <(awk -F$'\t' '{print }' "") > "$sam"
在这里,您将使用 samtools
获取所有读数,并搜索出现在 grep
的 -f
参数中的所有术语。该参数是一个包含搜索输入文件第一列的文件。输出是一个 sam
文件,其中仅包含搜索输入文件中列出的读数。
awk -v st="" 'BEGIN {OFS="\t"; while (getline < st) {st_array[]=}} {print [=12=], st_array[], "wh_genome"}' "$sam"
最后,使用 awk 添加额外信息:
- 以awk开头打开搜索输入文件,将其内容读入数组(
st_array
) - 将输出字段分隔符设置为制表符
- 遍历 sam 文件并添加来自预填充数组的额外信息。
我提出这个模式是因为我觉得 grep
在搜索方面比 awk
快,但单独使用 awk 可以获得相同的结果:
samtools view -@ 2 "$bam" | awk -v st="" 'BEGIN {OFS="\t"; while (getline < st) {st_array[]=}} {if ( in st_array) {print [=13=], st_array[], "wh_genome"}}'
在这种情况下,你只需要添加一个条件来识别有趣的阅读并摆脱grep
。
在任何情况下,您都需要多次重新读取文件或在使用它之前解压缩它。