Wie entferne ich alles nach dem zweiten Doppelpunkt in der zweiten Spalte und behalte alles andere?

Nov 19 2020

Ich habe file ( file.bim) mit ca. 1,5 mill. Linien, die so aussehen:

1   1:819959:C:T    0   819959  T   C
1   1:821249:G:A    0   821249  A   G
1   1:821477:A:G    0   821477  G   A
1   1:821843:C:T    0   821843  T   C
1   1:823963:A:C    0   823963  C   A
1   1:824357:C:T    0   824357  T   C
1   1:824398:A:C    0   824398  C   A
1   1:827972:G:A    0   827972  A   G
1   1:828539:A:T    0   828539  T   A

In der zweiten Spalte möchte ich den zweiten Doppelpunkt und die drei folgenden Zeichen entfernen und die verbleibenden Spalten unverändert lassen. Die gewünschte Ausgabe lautet wie folgt ( updated_file.bim):

1   1:819959    0   819959  T   C
1   1:821249    0   821249  A   G
1   1:821477    0   821477  G   A
1   1:821843    0   821843  T   C
1   1:823963    0   823963  C   A
1   1:824357    0   824357  T   C
1   1:824398    0   824398  C   A
1   1:827972    0   827972  A   G
1   1:828539    0   828539  T   A

Ich habe versucht, zu verwenden awk, aber hier werden nur die Doppelpunkte entfernt, aber die Buchstaben zwischen ihnen bleiben:

awk -F":" '{ print $1":"$2,$3,$4,$5,$6 }' file.bim > updated_file.bim

Antworten

2 AdminBee Nov 19 2020 at 18:20

Sie können das folgende awkProgramm verwenden:

awk '{sub(/:[^:]*:[^:]*$/,"",$2)}1' file.bim > updated_file.bim

oder

awk '{sub(/(:[^:]*){2}$/,"",$2)}1' file.bim > updated_file.bim

Dies verwendet die sub()Funktion, um die zweite Spalte ( $2) zu bearbeiten, indem die letzten beiden :und der darauf folgende Text durch "nichts" ersetzt werden, wodurch dieser Teil effektiv entfernt wird.

Wenn die Ausgabedatei durch Tabulatoren getrennt werden soll, verwenden Sie awk -v OFS="\t" ' ... '.

Wenn Ihre Datei durch Gruppen mit mehr als einem "Leerzeichen" begrenzt ist und Sie sicherstellen möchten, dass die Formatierung des Trennzeichens vollständig unverändert bleibt, können Sie sie alternativ verwenden

awk '{sub(/:[^:]*:[^: ]* /," ")}1' file.bim > updated_file.bim

Dabei wird nach dem Muster " :, gefolgt von Text, gefolgt von :Text, gefolgt von Leerzeichen" gesucht und dieses durch ein einzelnes "Leerzeichen" ersetzt. In Ihrer Eingabe tritt dieses Muster nur am Ende von Spalte 2 auf, sodass das Ersetzen nur diese Spalte betrifft.

Schließlich , wenn zu irgendeinem Zeitpunkt in der Zukunft die Zahl der :kann -separated Felder in der zweiten Spalte ändern, aber Sie wollen immer noch nur die ersten beiden behalten, können Sie auf meine Zuflucht original wenn auch weniger portable Variante, die die zweite Säule ersetzt durch nur der Text um den ersten :(anstelle des Textes hinter den letzten beiden mit "nichts"):

awk '{$2=gensub(/([^:]+:[^:]+).*/,"\\1","1",$2)}1' file.bim > updated_file.bim
2 αғsнιη Nov 19 2020 at 18:45

Entfernen Sie alles nach dem zweiten Doppelpunkt in der zweiten Spalte und behalten Sie alles andere bei:

awk '{ c=split($2, s, ":"); $2=s[1] (c>1?":":"") s[2]; }1' infile

Wie Sie bemerkt haben, werden dadurch die wiederholten Leerzeichen entfernt, wenn wir die zweite Spalte neu bewerten, wenn dies nicht das große Problem auf Ihrer Seite ist. Andernfalls verwenden Sie unten sedals Alternative:

sed -E 's/^([^ ]* *)([^: ]*:[^: ]*):[^ ]* (.*)/\1\2 \3/' infile

Testdatum;

::1   1:81995:9:C:T    0   8::199:59  T   C
1:a:  :1821249GA:    0   821:2:4  A   G
111   1:828539::    0   :::828539  T   A

Ergebnis:

::1   1:81995    0   8::199:59  T   C
1:a:  :1821249GA    0   821:2:4  A   G
111   1:828539    0   :::828539  T   A
1 EdMorton Nov 20 2020 at 06:59

Mit GNU sed für \S:

$ sed 's/\(:[^:]*\)\S*/\1/' file
1   1:819959    0   819959  T   C
1   1:821249    0   821249  A   G
1   1:821477    0   821477  G   A
1   1:821843    0   821843  T   C
1   1:823963    0   823963  C   A
1   1:824357    0   824357  T   C
1   1:824398    0   824398  C   A
1   1:827972    0   827972  A   G
1   1:828539    0   828539  T   A

oder mit einem POSIX sed:

$ sed 's/\(:[^:]*\)[^[:space:]]*/\1/' file
1   1:819959    0   819959  T   C
1   1:821249    0   821249  A   G
1   1:821477    0   821477  G   A
1   1:821843    0   821843  T   C
1   1:823963    0   823963  C   A
1   1:824357    0   824357  T   C
1   1:824398    0   824398  C   A
1   1:827972    0   827972  A   G
1   1:828539    0   828539  T   A
RedaSalih Nov 19 2020 at 18:07

Verwenden sed alle leeren Räume mit ersetzen „:“ dann entlassen $ 6 und $ 7 Felder und den Inhalt setzt $ 4 und $ 5 auf $ 5 mit awk:

sed  's/ /:/g' bim | awk  -F':' '{ $6=""; $7="" ; $4=$4$5; $5="" }1' > updated_file.bim 

OHNE SED:

awk  '{ gsub(/ /,":",$0); FS=":";$6=""; $7="" ; $4=$4$5; $5="" }1' bim > updated_file.bim 
CarlosPascual Nov 19 2020 at 19:05

mit awkzuerst mit substr($2, 1, 8)Sie von $ 2 , was Sie brauchen. Und drucken Sie den Wert von sstatt $2. Ihr Code damit kann also sein:

awk 's = substr($2, 1, 8) {print $1, s, $3, $4, $5, $6}' file
1 1:819959 0 819959 T C
1 1:821249 0 821249 A G
1 1:821477 0 821477 G A
1 1:821843 0 821843 T C
1 1:823963 0 823963 C A
1 1:824357 0 824357 T C
1 1:824398 0 824398 C A
1 1:827972 0 827972 A G
1 1:828539 0 828539 T A

Aktualisiert, um die Leerzeichen zu behalten:

awk -F '[[:blank:]]{2,}' '$2 = substr($2, 1, 8) {print $1, $2, $3, $4, $5, $6}' file | column -t
1  1:819959  0  819959  T  C
1  1:821249  0  821249  A  G
1  1:821477  0  821477  G  A
1  1:821843  0  821843  T  C
1  1:823963  0  823963  C  A
1  1:824357  0  824357  T  C
1  1:824398  0  824398  C  A
1  1:827972  0  827972  A  G
1  1:828539  0  828539  T  A
codeholic24 Nov 19 2020 at 19:16

Die folgende Ausgabe kann mit dem sedBefehl erreicht werden

cat file.bim | sed 's/:[a-zA-Z]//g' >> updated_file.bim

or

cat file.bim | sed 's/:[[:alpha:]]//g' >> updated_file.bim

Ausgabe :

1   1:819959    0   819959  T   C
1   1:821249    0   821249  A   G
1   1:821477    0   821477  G   A
1   1:821843    0   821843  T   C
1   1:823963    0   823963  C   A
1   1:824357    0   824357  T   C
1   1:824398    0   824398  C   A
1   1:827972    0   827972  A   G
1   1:828539    0   828539  T   A