Cat arquivos com nomes semelhantes de diretórios diferentes em um único arquivo com o mesmo nome

Cat arquivos com nomes semelhantes de diretórios diferentes em um único arquivo com o mesmo nome

Alguém pode me ajudar com o seguinte problema? Tenho cerca de 40 diretórios de espécies diferentes, cada um com centenas de arquivos de sequência que contêm sequências ortólogas. Os arquivos de sequência são nomeados de forma semelhante para cada um dos diretórios de espécies. Quero concatenar os arquivos com nomes idênticos dos diretórios de 40 espécies em um único arquivo de sequência com nome semelhante.

Por exemplo, tenho os seguintes 3 diretórios: "Species1", "Species2", "Species3". Dentro desses diretórios estão arquivos com nomes semelhantes: "SequenceA.fasta", "SequenceB.fasta", "SequenceC.fasta". Preciso concatenar todo o conteúdo dos diferentes arquivos SequenceA.fasta em um novo arquivo chamado "SequenceA.fasta" em outro diretório. Como eu faço isso?

Eu tentei com o seguinte loop, que falhou. Os arquivos são criados, mas estão vazios:

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

Obrigado por qualquer conselho ou ajuda!

(Desculpe por qualquer postagem cruzada em potencial, postei acidentalmente esta pergunta em um fórum errado anteriormente)

Responder1

Há várias coisas a serem observadas nesta resposta.

  1. Geralmente é uma má ideia analisar a saída lsse você pode usar globpadrões de shell para fazer o que deseja - consulte [http://mywiki.wooledge.org/ParsingLs]. Não usei a opção shell nullglob para portabilidade, mas isso tornaria os scripts um pouco mais curtos.

  2. Você quer ter certeza de que seus padrões glob não são muito amplos, então você diz catpara usar o mesmo nome de arquivo para entrada e saída. Se fizer isso, você poderá encher seu disco rígido muito rapidamente enquanto tenta criar um arquivo de tamanho infinito.

  3. Se você fornecer um padrão semelhante *.fastae ele não corresponder a nenhum arquivo, a string literal *.fastaserá usada.

  4. Se você tiver um arquivo chamado *.fasta, uma maneira de saber a diferença entre ele e o padrão é ver se ele é legível.

  5. Colocar --fim à análise de argumentos é uma boa ideia se houver nomes de arquivos não autorizados.

Primeiro um script simples.

# 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

Isso pressupõe que "Species1" possui todos os arquivos "SequenceX.fasta". Se este não for o caso, provavelmente você precisará de um loop duplo. Isso é mais robusto, mas mais longo e mais lento.

# 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

informação relacionada