将命令循环到子目录中不同数量的文件

将命令循环到子目录中不同数量的文件

我正在尝试找到一种方法来编写一个脚本,该脚本对子目录中不同数量的文件执行命令。我有 72 个子目录,每个子目录都有不同数量的示例文件(fastq.gz 文件),其中最多的子目录有 20 个示例文件。我使用了以下命令,但当子目录中的文件数量少于 20 个时,它会给出大量空文件夹和文件。

#!/bin/sh
TOPHAT_BINARY=/home/alex/tools/tophat-2.1.0.Linux_x86_64/tophat2
GENE_REFERENCE=/home/alex/toxo/ref/genes/ToxoDB-27_TgondiiME49.gff
BOWTIE_INDEX=/home/alex/toxo/ref/bwt/ToxoDB-27_TgondiiME49_Genome
P=10 #use 10 threads
for FILE_ID in {001..072}
do
 for SAMPLE_ID in {001..020}
 do
 $TOPHAT_BINARY -G $GENE_REFERENCE -p $P -o /home/alex/toxo/alignments/Nishi_${FILE_ID}/sample_${SAMPLE_ID} $BOWTIE_INDEX /home/junya/bioinfo/NGS/original/Nishikawa.cell/rename_and_link/Nishi_${FILE_ID}/*_${SAMPLE_ID}.fastq.gz &
 mv /home/alex/toxo/alignments/Nishi_${FILE_ID}/sample_${SAMPLE_ID}/accepted_hits.bam /home/alex/toxo/alignments/Nishi_${FILE_ID}/sample_${SAMPLE_ID}.bam
 done
done

我如何编辑脚本

for SAMPLE_ID in {001..020}

以便该命令仅适用于特定子目录中的特定数量的文件而不输出空文件?

有些子目录包含 2、3、10、16 等数量的文件,所以我只做了 20 个,所以如果子目录有 2 个示例文件,那么输出将包含 18 个空文件....我添加了一个命令来删除所有空文件最后它起作用了,但是有没有其他方法可以仅指定多个子目录中包含的文件?

## secure and fast version ###
find /home/alex/toxo/alignments/Nishi_${FILE_ID} -type f -empty -print0 | xargs -0 -I {} /bin/rm "{}"

答案1

看起来梅尔的回答已经解决了你的问题;这是另一种变体。我没有循环遍历大范围的 SAMPLE_ID(如果最终得到的数量超过了预期的 20 个怎么办?),我更改了循环,以便它使用 bash 的文件名扩展来循环遍历所有且仅实际存在的 sample_* 文件在 /home/alex/toxo/alignments/Nishi_${FILE_ID} 中。为了取回 SAMPLE_ID 的原始值,我使用参数扩展从 SAMPLE_ID 文件名中检索最后三个字符。请注意,如果您最终有超过 999 个 Sample_* 文件,则会中断!

我还更改了您的 she-bang 标题行以显式调用 bash(通过 env),因为如果调用为 /bin/sh,bash 将尝试模拟 Bourne shell,并失去 Bourne Again SHell 的功能(例如花哨的参数扩展!)。

作为一个额外的好处,以这种方式使用 SAMPLE_FILE 可以使命令变得更短并且更容易阅读!

#!/usr/bin/env bash
TOPHAT_BINARY=/home/alex/tools/tophat-2.1.0.Linux_x86_64/tophat2
GENE_REFERENCE=/home/alex/toxo/ref/genes/ToxoDB-27_TgondiiME49.gff
BOWTIE_INDEX=/home/alex/toxo/ref/bwt/ToxoDB-27_TgondiiME49_Genome
P=10 #use 10 threads
for FILE_ID in {001..003}
do
  for SAMPLE_FILE in /home/alex/toxo/alignments/Nishi_${FILE_ID}/sample_*
  do
    SAMPLE_ID=${SAMPLE_FILE: -3}
    $TOPHAT_BINARY -G $GENE_REFERENCE -p $P -o $SAMPLE_FILE $BOWTIE_INDEX /home/junya/bioinfo/NGS/original/Nishikawa.cell/rename_and_link/Nishi_${FILE_ID}/*_${SAMPLE_ID}.fastq.gz
    mv ${SAMPLE_FILE}/accepted_hits.bam ${SAMPLE_FILE}/sample_${SAMPLE_ID}.bam
    echo
  done
done

答案2

在第二do行之后,插入新行并输入

if [ -a /home/alex/toxo/alignments/Nishi_${FILE_ID}/sample_${SAMPLE_ID} ] ; then

并在第一done行之前再次插入新行并键入

fi

这将在尝试处理文件之前检查文件是否存在。如果它不存在,它将跳过该 SAMPLE_ID 值。

相关内容