Bash:尝试在函数的输出中追加变量名

时间:2014-05-30 11:27:46

标签: bash bioinformatics

这是我在Stackoverflow上的第一篇文章,我应该指出,我对很多编程都非常陌生。我目前是一名研究生,从事各种程序的大量编码项目,从LaTeX到bash,MATLAB等等。

如果您可以明确地解释您的答案,我会非常感激,因为我正在努力学习。我很抱歉,如果有其他答案可以做我想做的事情,但我现在花了几天时间看。

所以我要解决的问题是:我目前正在使用一系列生物信息学工具来分析一系列基因组,而我正试图在某种程度上自动化这一过程。

我有一些名称看起来像这样的序列(所有序列都包含在当前作为配对文件的文件夹中):

SOL2511_S5_L001_R1_001.fastq
SOL2511_S5_L001_R2_001.fastq
SOL2510_S4_L001_R1_001.fastq
SOL2510_S4_L001_R2_001.fastq

......等等......

我基本上希望通过将这些变量转换为变量并将这些变量传递给我依次使用的每个程序来自动化该过程。因此,例如我的想法是将它们分配为通配符,使用R1和R2(它出现在所有文件名中,因为它们代表每条DNA链),如下所示:

#!/bin/bash

seq1=*R1_001*
seq2=*R2_001*

在一个基本的层面上,这是有效的,因为它返回正确的文件,所以现在我将这些变量传递给我的第一个函数,它将DNA序列减少指定量,如下所示:

# seqtk is the program suite, trimfq is a function within it, 
# and the options -b -e specify how many bases to trim from the beginning and end of     
# the DNA sequence respectively. 

seqtk trimfq -b 10 -e 20 $seq1 > 
seqtk trimfq -b 10 -e 20 $seq2 > 

所以现在我的问题是我希望能够在&gt;之后出现的输出文件中添加类似“_trim”的内容,但我找不到任何看似可以在线工作的内容。< /强>

或者,我一直在寻找一个脚本,它将获取文件所在文件夹的名称,并为文件夹名称创建一个变量,然后我可以将其提供给相关函数,以便所有输出文件名称正确,以便稍后使用。

非常感谢您提供任何帮助,我很抱歉这不是一个真正的最低限度的工作示例,因为我只是开始讨论所有这些事情!

修改

所以我修改了@ghoti的for循环(我可以添加奇妙的工作,为你代表:D)现在我追加trim_,就像之前的循环一样,给我一个.fastq.trim以后会导致错误。

有什么方法可以将_trim附加到文件名的末尾,但是在扩展名之前?

2 个答案:

答案 0 :(得分:2)

匹配文件名时,显式通常比默示更好。您的通配符可能比预期的更多,特别是如果您的文件版本附加了“_trim”!

我会更加精确地使用通配符,并使用for循环来处理文件,而不是依靠seqtk来处理多个文件。这样,您就可以对文件名进行自己的处理。

以下是一个例子:

#!/bin/bash

# Define an array of sequences
sequences=(R1_001 R2_001)

# Step through the array...
for seq in ${sequences[@]}; do

  # Step through the files in this sequence...
  for file in SOL*_${seq}.fastq; do
    seqtk trimfq -b 10 -e 20 "$file" > "${file}.trim"
  done

done

我不知道你的文件夹是如何设置的,所以我没有在这个脚本中解决这个问题。但基本思想是,如果你希望脚本能够操作单个文件名,你需要类似for循环的东西来处理每个文件名的操作。

这有帮助吗?

<强>更新

要将_trim放在扩展名之前,请将seqtk行替换为以下内容:

    seqtk trimfq -b 10 -e 20 "$file" > "${file%.fastq}_trim.fastq"

如果您想阅读它,请使用Parameter Expansion下的Bash手册页中记录的内容。基本上,${file%.fastq}采用$file变量并删除后缀。然后我们添加您的额外文本以及后缀。

您也可以使用basename(1)删除扩展程序,但是当您可以使用内置于shell中的内容时,无需调用外部扩展程序。

答案 1 :(得分:0)

您可以使用这些文件名将ls的输出传输到要运行的命令,而不是使用文件名设置变量,如下所示:

ls *R{1,2}_001* | xargs -I@ sh -c 'seqtk trimfq -b 10 -e 20 "$1" > "${1}_trim"' -- @

xargs -I@将获取上一个命令的输出并将其存储在@中以供seqtk

使用