Dateien nach einem bestimmten Muster aufteilen

Dateien nach einem bestimmten Muster aufteilen

Eine Datei, mit der ich arbeite, ist wie

NAMES   n0  n1  n2  n3  n4  n5  n6  n7
REGION  chr 1   100000
404 AAAAAAGA
992 TTTTTTTA
1146    CCCCGGCC
1727    CCCCCACC
1778    GCCCCCCC

Meine gewünschte Ausgabe ist (bitte beachten Sie Zeile zwei und wie die Zahlen dort angeordnet sind)

file1
 NAMES  n0  n1  n2  n3  n4  n5  n6  n7
    REGION  chr 404 992
    404 AAAAAAGA
    992 TTTTTTTA

file2
 NAMES  n0  n1  n2  n3  n4  n5  n6  n7
     REGION chr 1146    1778
1146 CCCCGGCC
1727 CCCCCACC
1778 GCCCCCCC

Ich habe es in awk versucht

awk 'function print_vals() {
   fn="file" c;
   print hdr > fn;
   print "REGION  chr", sn, en >> fn;
   for (i in a)
      print a[i] >> fn;
} NR == 1 {
   hdr=$0;
   c=0;
   next
} NF==2 && $1 >= 1000000*c {
   if (c)
      print_vals();
   delete a;
   i=0;
   c++;
   sn=$1;
} NF==2 {
   a[++i]=$0;
   en=$1;
} END {
   print print_vals();
 }' file

Für die Beispieldaten hat es funktioniert und ich bekomme die Ausgabe, aber für den realen Datensatz funktioniert es nicht. Der Datensatz ist hierhttps://www.dropbox.com/s/h6ukumbj08cwk99/arg_t1.gz?dl=0 Es sieht so aus

NAMES   n1  n2  n3  n4  n5  n6  n7  n8  n9  n10     n11     n12     n13     n14     n15     n16 $
REGION  chr     1   10000000
69  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
474     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
584     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
627     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
676     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
690     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
894     AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
1104    AAAAAAAAAAAAAAAAA

mit dem Ausgang, der irgendwie umgeschaltet ist...es ist nicht so, wie es sein sollte

NAMES   n1  n2  n3  n4  n5  n6  n7  n8  n9  n10     n11     n12     n13     n14     n15     n16 $
REGION  chr 69 999927
561321  AAAAAACAAAAAAAAACAAAAAAAAAAAAAAAAAACCCAAAACAACAAAACAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAACAAAAACCAACA$
561362  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
562011  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
562029  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
562162  AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA$
562171

kann mir jemand sagen, wie ich das beheben kann oder eine andere Funktion vorschlagen?

Antwort1

In awkassoziativen Arrays werden in einer nicht festgelegten Reihenfolge durchlaufen. Ersetzen Sie Ihre

for (i in a)

von

n = i
for(i=1;i<=n;i++)

Um Ihr awk in ein Bash-Skript einzuschließen, können Sie etwas wie

#!/bin/bash
for file
do  awk -v file="$file" '....' "$file"
done

Stellen Sie sicher, dass Sie chmod a+rxdie Skriptdatei ausführen. Ersetzen Sie auch die Zeile

fn="file" c;

in Ihrem Awk-Skript durch

fn = c "_" file;

Diese Zeile gibt an, wie Ihr neuer Dateiname aufgebaut wird: Die Variable awk fileerhält zunächst als Wert den Namen der zu verarbeitenden Datei (die Syntax lautet: awk -v Variable=Wert). Die Variable awk fnist Ihr neuer Dateiname und ist die Variable c, die die Nummer enthält, die mit dem Zeichen _und der Variable des Dateinamens verknüpft ist.

Sie können diesen Bash-Befehl mit mehreren Dateien als Argumente ausführen. Sie werden vom awk nacheinander verarbeitet.


Endergebnis:

#!/bin/bash
for file
do awk -v file="$file" 'function print_vals() {
   fn = c "_" file;
   print hdr > fn;
   print "REGION  chr", sn, en >> fn;
   n = i
   for(i=1;i<=n;i++)
      print a[i] >> fn;
 } NR == 1 {
   hdr=$0;
   c=0;
   next
 } NF==2 && $1 >= 1000000*c {
   if (c)
      print_vals();
   delete a;
   i=0;
   c++;
   sn=$1;
 } NF==2 {
   a[++i]=$0;
   en=$1;
 } END {
   print print_vals();
 }'  "$file"
done

verwandte Informationen