Ich schreibe ein Skript für bioinformatische Verwendung. Ich habe eine Datei mit 2 Spalten, in der Spalte A zeigt eine Nummer und Spalte B eine bestimmte Zeichenfolge. Ich brauche ein Skript, das die Datei nach der Zeichenfolge in Spalte B durchsucht. Wenn Duplikate gefunden werden, sollte die Zahl in Spalte A addiert werden, Duplikate sollten entfernt werden, und nur eine Zeile mit Spalte A mit der Summe und Spalte B String sollte bleiben.Duplikate finden und Summe der Werte in Spalte daneben geben (UNIX) (mit Lösung -> brauche schneller Weg)
Ich habe etwas geschrieben, das genau das tut, aber weil ich nicht wirklich ein Programmierer bin, bin ich sicher, dass es einen viel schnelleren Weg gibt. Meine Dateien enthalten manchmal 500k Zeilen und mein Code braucht solche Dateien. Bitte sehen Sie es sich an und sehen Sie, was ich ändern könnte, um die Dinge zu beschleunigen. Auch kann ich nicht uniq
verwenden, weil für diese ID muss auch sort
verwenden, aber die Reihenfolge der Zeilen müssen so bleiben, wie sie sind!
13 ABCD
15 BGDA
12 ABCD
10 BGDA
10 KLMN
17 BGDA
sollte
25 ABCD
42 BGDA
10 KLMN
Dies macht es sich aber für eine Datei mit 500k Zeilen zu lange dauert:
for AASEQUENCE in file.txt;
do
#see how many lines the file has and save that number in $LN
LN="$(wc -l $AASEQUENCE | cut -d " " -f 1)"
for ((i=1;i<=${LN};i++));
do
#Create a variable that will have just the string from column B
#save it in $STRING
STRING="$(cut -f2 $AASEQUENCE | head -n $i| tail -n 1 | cut -f1)";
#create $UNIQ: a variable that will have number+string of that
#line. This will be used in the ELSE-statement, IF there are no
#duplicates of the string, it will just be added to the
# output file without further processing
UNIQ="$(head -n $i $AASEQUENCE | tail -n 1)"
for DUPLICATE in $AASEQUENCE;
do
#create variable that will display the number of lines
#of duplicates. IF its 1 the IF-statement will jump to the ELSE
#part as there are no duplicates
VAR="$(grep -w "${STRING}" $DUPLICATE | wc -l)"
#Now add up all the numbers from column A that have $STRING in
#column B
TOTALCOUNT="$(grep -w "${STRING}" $DUPLICATE | cut -f1 | awk
'{SUM += $1} END {print SUM}')"
#Create a file that the single line can be put into it
touch MERGED_`basename $AASEQUENCE`
#The IF-statement checks if the AA occurs more than once
#If it does a second IF-statement checks if this AA-sequence has
#already been added.
#If it hasnt been added, it will be, if not nothing happens.
ALREADYMATCHED="$(grep -w "${STRING}" MERGED_`basename
$AASEQUENCE` | wc -l)"
if [[ "$VAR" > 1 ]];
then if [[ "$ALREADYMATCHED" != 0 ]]; then paste <(echo
"$TOTALCOUNT") <(echo "$STRING") --delimiters ' '>>
MERGED_`basename $AASEQUENCE` ;fi;
else echo $UNIQ >> MERGED_`basename $AASEQUENCE` ;fi
done;
done;
done;
PS: Wenn ich DateiA.txt fileB.txt haben. .. und benutze Datei * Die Schleife bleibt immer nach der ersten Datei stehen. Irgendwelche Vorschläge warum?
Ich hätte hier erst nachfragen sollen, bevor ich dieses (für mich) extrem komplexe Skript schreibe. Vielen Dank! Ich muss den Befehl 'awk' mehr kennenlernen. – Vaxin
lassen Sie mich wissen, wie schnell es für Ihre 500k Linien ist! – Jerzyk
@ Vaxin auf einer Randnotiz - Python ist schön, mit DNA-Sequenzen zu spielen: http://pythonforbiologists.com/ – Jerzyk