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.
Es ist im Allgemeinen keine gute Idee, die Ausgabe von zu analysieren,
ls
wenn Sie stattdessen Shell-Muster verwenden können,glob
um 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.Sie möchten sicherstellen, dass Ihre Glob-Muster nicht zu breit sind, also geben Sie an,
cat
fü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.Wenn Sie ein Muster wie angeben
*.fasta
und es mit keiner Datei übereinstimmt,*.fasta
wird die wörtliche Zeichenfolge verwendet.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.--
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