Cat ähnlich benannte Dateien aus verschiedenen Verzeichnissen in eine einzige Datei mit demselben Namen

Cat ähnlich benannte Dateien aus verschiedenen Verzeichnissen in eine einzige Datei mit demselben Namen

Kann mir jemand bei folgendem Problem helfen? Ich habe etwa 40 Verzeichnisse verschiedener Arten, jedes mit Hunderten von Sequenzdateien, die orthologe Sequenzen enthalten. Die Sequenzdateien sind für jedes der Artenverzeichnisse ähnlich benannt. Ich möchte die gleichnamigen Dateien der 40 Artenverzeichnisse zu einer einzigen Sequenzdatei zusammenfassen, die ähnlich benannt ist.

Ich habe z. B. die folgenden 3 Verzeichnisse: „Species1“, „Species2“, „Species3“. In diesen Verzeichnissen befinden sich ähnlich benannte Dateien: „SequenceA.fasta“, „SequenceB.fasta“, „SequenceC.fasta“. Ich muss alle Inhalte der verschiedenen SequenceA.fasta-Dateien in einer neuen Datei namens „SequenceA.fasta“ in einem anderen Verzeichnis zusammenfassen. Wie mache ich das?

Ich habe es mit der folgenden Schleife versucht, was jedoch fehlschlug. Dateien werden erstellt, sind aber leer:

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

Vielen Dank für jeden Rat und jede Hilfe!

(Entschuldigen Sie das mögliche Crossposting, ich habe diese Frage vorher versehentlich im falschen Forum gepostet.)

Antwort1

Zu dieser Antwort sind mehrere Dinge zu beachten.

  1. Es ist im Allgemeinen keine gute Idee, die Ausgabe von zu analysieren, lswenn Sie stattdessen Shell-Muster verwenden können, globum das zu tun, was Sie möchten - siehe [http://mywiki.wooledge.org/ParsingLs]. Aus Gründen der Portabilität habe ich die Shell-Option „Nullglob“ nicht verwendet, aber dadurch wären die Skripte etwas kürzer geworden.

  2. Sie möchten sicherstellen, dass Ihre Glob-Muster nicht zu breit sind, also geben Sie an, catfür Eingabe und Ausgabe denselben Dateinamen zu verwenden. Andernfalls kann Ihre Festplatte sehr schnell voll werden, wenn Sie versuchen, eine Datei mit unendlicher Größe zu erstellen.

  3. Wenn Sie ein Muster wie angeben *.fastaund es mit keiner Datei übereinstimmt, *.fastawird die wörtliche Zeichenfolge verwendet.

  4. Wenn Sie eine Datei mit dem Namen haben *.fasta, können Sie den Unterschied zwischen dieser Datei und dem Muster erkennen, indem Sie prüfen, ob sie lesbar ist.

  5. --Wenn die Möglichkeit besteht, dass es fehlerhafte Dateinamen gibt, ist es sinnvoll, die Argumentanalyse zu beenden .

Zuerst ein einfaches Skript.

# 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

Dies setzt voraus, dass „Species1“ alle „SequenceX.fasta“-Dateien hat. Wenn dies nicht der Fall ist, benötigen Sie wahrscheinlich eine Doppelschleife. Dies ist robuster, dauert aber länger und ist langsamer.

# 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

verwandte Informationen