使用 for 循环在多个文件上运行 zcat

ste*_*rt6 3 bash terminal filenames for-loop

我对终端/bash 很陌生,也许以前有人问过这个问题,但我找不到我要找的东西,也许是因为我不确定要搜索什么来回答我的问题。

我正在尝试格式化一些文件以进行遗传分析,虽然我可以为每个样本文件写出以下命令,但我知道有更好的方法:

zcat myfile.fastq.gz | awk 'NR % 8 == 5 || NR % 8 == 6 || NR % 8 == 7 || NR % 8 == 0 {print $0}' | gzip > myfile.2.fastq.gz
zcat myfile.fastq.gz | awk 'NR % 8 == 1 || NR % 8 == 2 || NR % 8 == 3 || NR % 8 == 4 {print $0}' | gzip > myfile.1.fastq.gz
Run Code Online (Sandbox Code Playgroud)

我有以下文件:

-bash-3.2$ ls
BB001.fastq BB013.fastq.gz  IN014.fastq.gz  RV006.fastq.gz  SL083.fastq.gz
BB001.fastq.gz  BB014.fastq.gz  INA01.fastq.gz  RV007.fastq.gz  SL192.fastq.gz
BB003.fastq.gz  BB015.fastq.gz  INA02.fastq.gz  RV008.fastq.gz  SL218.fastq.gz
BB004.fastq.gz  IN001.fastq.gz  INA03.fastq.gz  RV009.fastq.gz  SL276.fastq.gz
BB006.fastq.gz  IN002.fastq.gz  INA04.fastq.gz  RV010.fastq.gz  SL277.fastq.gz
BB008.fastq.gz  IN007.fastq.gz  INA05.fastq.gz  RV011.fastq.gz  SL326.fastq.gz
BB009.fastq.gz  IN010.fastq.gz  INA1M.fastq.gz  RV012.fastq.gz  SL392.fastq.gz
BB010.fastq.gz  IN011.fastq.gz  RV003.fastq.gz  SL075.fastq.gz  SL393.fastq.gz
BB011.fastq.gz  IN012.fastq.gz  RV004.fastq.gz  SL080.fastq.gz  SL395.fastq.gz
BB012.fastq.gz  IN013.fastq.gz  RV005.fastq.gz  SL081.fastq.gz
Run Code Online (Sandbox Code Playgroud)

我想将两个 zcat 函数应用于每个文件,从每个文件创建两个新文件,而无需将其写出 50 次。我在 R 中经常使用 for 循环,但不知道在 bash 中从哪里开始。我可以用文字说出我想要的东西,希望有人可以帮我编写代码!:

for FILENAME.fastq.gz in all files in cd

zcat FILENAME.fastq.gz | awk 'NR % 8 == 5 || NR % 8 == 6 || NR % 8 == 7 || NR % 8 == 0 {print $0}' | gzip > FILENAME.2.fastq.gz
zcat FILENAME.fastq.gz | awk 'NR % 8 == 1 || NR % 8 == 2 || NR % 8 == 3 || NR % 8 == 4 {print $0}' | gzip > FILENAME.1.fastq.gz
Run Code Online (Sandbox Code Playgroud)

非常感谢您的帮助!

*****编辑*****

我的符号有点不对,这是最后一个正确的 for 循环:

for fname in *.fastq.gz
do
    gzcat "$fname" | awk 'NR % 8 == 5 || NR % 8 == 6 || NR % 8 == 7 || NR % 8 == 0 {print $0}' | gzip >../../SeparateReads/"${fname%.fastq.gz}.2.fastq.gz"
    gzcat "$fname" | awk 'NR % 8 == 1 || NR % 8 == 2 || NR % 8 == 3 || NR % 8 == 4 {print $0}' | gzip >../../SeparateReads/"${fname%.fastq.gz}.1.fastq.gz"
done
Run Code Online (Sandbox Code Playgroud)

***** 后续问题 *****

当我运行以下命令时:

for fname in *.1.fastq.gz
do
cat ./CleanedSeparate/XhoI/"$fname" ./CleanedSeparate/MseI/"${fname%.1.fastq.gz}.2.fastq.gz" > ./FinalCleaned/"${fname%.1.fastq.gz}.fastq.gz"
done
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

cat: ./CleanedSeparate/XhoI/*.1.fastq.gz: No such file or directory
cat: ./CleanedSeparate/MseI/*.2.fastq.gz: No such file or directory
Run Code Online (Sandbox Code Playgroud)

显然我没有正确使用 * 。关于我哪里出错的任何提示?

Joh*_*024 5

for fname in *.fastq.gz
do
    zcat "$fname" | awk 'NR % 8 == 5 || NR % 8 == 6 || NR % 8 == 7 || NR % 8 == 0 {print $0}' | gzip >"${fname%.fastq.gz}.2.fastq.gz"
    zcat "$fname" | awk 'NR % 8 == 1 || NR % 8 == 2 || NR % 8 == 3 || NR % 8 == 4 {print $0}' | gzip >"${fname%.fastq.gz}.1.fastq.gz"
done
Run Code Online (Sandbox Code Playgroud)

关键点:

  • for fname in *.fastq.gz

    这会遍历当前目录中以.fastq.gz. 如果文件位于不同的目录中,则使用:

    for fname in /path/to/*.fastq.gz
    
    Run Code Online (Sandbox Code Playgroud)

    /path/to/获取这些文件的路径应该在哪里。

  • zcat "$fname"

    这部分很简单。它将文件名替换为zcat.

  • "${fname%.fastq.gz}.1.fastq.gz"

    这有点棘手。要获得所需的输出文件名,我们需要将 插入.1到原始文件名中。最简单的方法bash.fastq.gz从文件名中删除后缀,${fname%.fastq.gz}其中%is bash-speak 意思是从末尾删除后缀。然后,我们添加新的后缀.1.fastq.gz,我们就有了正确的文件名。

在不同的目录中创建新文件

根据后续问题,这不起作用:

for fname in *.1.fastq.gz
do
    cat ./CleanedSeparate/XhoI/"$fname" ./CleanedSeparate/MseI/"${fname%.1.fastq.gz}.2.fastq.gz" > ./FinalCleaned/"${fname%.1.fastq.gz}.fastq.gz"
done
Run Code Online (Sandbox Code Playgroud)

问题是,在for语句中,shell 正在*.1.fastq.gz当前目录中查找。但是,他们不在。他们在./CleanedSeparate/XhoI/. 相反,运行:

dir1=./CleanedSeparate/XhoI
for fname in "$dir1"/*.1.fastq.gz
do
    base=${fname#$dir1/}
    base=${base%.1.fastq.gz}
    echo "base=$base"
    cat "$fname" "./CleanedSeparate/MseI/${base}.2.fastq.gz" >"./FinalCleaned/${base}.fastq.gz"
done
Run Code Online (Sandbox Code Playgroud)

请注意,此处为for语句提供了可在其中查找文件的正确目录。