将不同目录中的类似名称的文件转换为同名的单个文件

将不同目录中的类似名称的文件转换为同名的单个文件

谁能帮我解决以下问题?我有大约 40 个不同物种的目录,每个目录都有 100 个包含直系同源序列的序列文件。每个物种目录的序列文件都以类似的方式命名。我想将 40 个物种目录的同名文件连接成一个名称相似的序列文件。

例如,我有以下 3 个目录:“Species1”、“Species2”、“Species3”。这些目录中包含类似命名的文件:“SequenceA.fasta”、“SequenceB.fasta”、“SequenceC.fasta”。我需要将不同 SequenceA.fasta 文件的所有内容连接到另一个目录中名为“SequenceA.fasta”的新文件中。我该怎么做呢?

我用下面的循环尝试了它,但失败了。文件已创建但为空:

ls . | while read FILE; do cat ./*/"$FILE" >> ./final/"$FILE"; done

感谢您的任何建议或帮助!

(对于任何潜在的交叉发布,我很抱歉,我之前不小心在错误的论坛上发布了这个问题)

答案1

这个答案中有几件事需要注意。

  1. ls如果您可以使用 shellglob模式来执行您想要的操作,则解析输出通常是一个坏主意- 请参阅 [http://mywiki.wooledge.org/ParsingLs]。为了可移植性,我没有使用 nullglob shell 选项,但这会使脚本稍微短一些。

  2. 您希望确保您的全局模式不太宽泛,因此您告诉cat输入和输出使用相同的文件名,如果这样做,当您尝试创建无限大小的文件时,您可能会很快填满硬盘驱动器。

  3. 如果您给出类似的模式*.fasta,但它不匹配任何文件,则*.fasta使用文字字符串。

  4. 如果您有一个名为的文件*.fasta,那么区分该文件与模式之间的区别的一种方法是查看它是否可读。

  5. --如果可能存在恶意文件名,那么结束参数解析是个好主意。

首先是一个简单的脚本。

# Simple script, assumes that "Species1" has all the needed "SequenceX.fasta" files
# Start in the directory containing "Species1", "Species2" etc.
# create output directory
mkdir "final"
# Go into the first directory
cd "Species1"
# Loop over all the files
for i in *".fasta"
do
    # join all the like named files in the sibling directories to the output
    # use a pattern which doesn't match ../final/$i to get list of files to join.
    cat "../Species"*"/$i" > "../final/$i"
done

这假设“Species1”具有所有“SequenceX.fasta”文件。如果不是这种情况,那么您可能需要一个双循环。这更稳健,但更长且更慢。

# Start in the top level and loop over the directories
for dir in */
do
    # don't do anything inn the output directory
    [ "$dir" = "final" ] && continue
    # cd into directory, protecting against rogue directory names
    cd "./$dir" || { echo "cd to $dir failed" >&2 ; exit 1 ; }
    # loop over the files 
    for file in *"fasta"
    do
         # check the file exists, if there are no files matching the pattern
         # then the shell will pass the pattern through to the loop
         if [ -r "$file" ] ; then
             cat -- "$file" >> "../final/$file"
         fi
    done
    cd ".." || { echo "failed to return from $dir" ; exit 1 ; }
done

相关内容