0

我很少使用 UNIX,所以如果这似乎是一个简单的问题,我深表歉意。我正在尝试遍历子目录和文件,然后从循环抓取的特定文件生成输出,然后将输出通过管道传输到另一个目录中的文件,该目录的名称可以从输入文件中识别出来。到目前为止,我有:

 for file in /home/sub_directory1/samples/SSTC*/ 
      do
           samtools depth -r chr9:218026635-21994999 < $file > /home/sub_directory_2/level_2/${file}_out
      done

我希望从 sub_directory1/samples/SSTC*/ 中的 file_1_novoalign.bam 生成输出,并将该输出作为名为 file_1_novoalign_out.bam 的输出文件发送到 /home/sub_directory_2/level_2/ 但是它不起作用 - 它说' bash:/home/sub_directory_2/level_2/file_1_novoalign.bam.out:没有这样的文件或目录。

理想情况下,我希望能够剥离 outfile 的“_novoalign.bam”部分并替换为“_out.txt”。我相信这对于普通的 unix 用户来说会很容易,但我已经搜索过,但找不到快速答案,也没有时间花很长时间搜索。提前感谢任何基于我到目前为止的代码的建议,或者欢迎任何替代建议。

ps 我无权将文件写入包含输入文件夹的目录

4

1 回答 1

1

在没有空格的文件名的解释下,保持简单。当你想要文件而不是目录时,你应该用and not
结束你的 for 循环。当你只想处理以 结尾的文件时,你应该告诉 unix。最简单的方法是使用 sed 将字符串的一部分替换为 sed。美元符号用于字符串的结尾。总脚本将是**/_novoalign.bam

OUTDIR=/home/sub_directory_2/level_2
for file in /home/sub_directory1/samples/SSTC/*_novoalign.bam; do
   echo Debug: Inputfile including path: ${file}
   OUTPUTFILE=$(basename $file | sed -e 's/_novoalign.bam$/_out.txt/')
   echo Debug: Outputfile without path: ${OUTPUTFILE}
   samtools depth -r chr9:218026635-21994999 < ${file} > ${OUTDIR}/${OUTPUTFILE}
done

注 1:您可以使用 file=${fullfile##*/} 之类的参数扩展来获取不带路径的文件名,但您会在一小时内忘记语法。更容易记住的是 basename 和 dirname,但您仍然需要进行一些处理。

注意 2:当您的脚本首次将目录更改为 /home/sub_directory_2/level_2 时,您可以跳过 basename 调用。
当要处理目录中的所有文件时,可以使用星号。
当所有文件最多有一个下划线时,可以使用 cut。您可能想要添加一些错误处理。当您想要输出文件中来自 samtools 的 STDERR 时,添加2>&1.
这些会将您的脚本变成

   OUTDIR=/home/sub_directory_2/level_2
   cd /home/sub_directory1/samples/SSTC
   for file in *; do
       echo Debug: Inputfile: ${file}
       OUTPUTFILE="$(basename $file | cut -d_ -f1)_out.txt"
       echo Debug: Outputfile: ${OUTPUTFILE}
       samtools depth -r chr9:218026635-21994999 < ${file} > ${OUTDIR}/${OUTPUTFILE} 2>&1
    done
于 2015-02-10T16:55:07.450 回答