
Ich habe eine Datei wie diese:
id target_id length eff_length
1 intron_FBgn0000721:20_FBgn0000721:18 1136 243.944268
1 intron_FBgn0000721:19_FBgn0000721:18 1122 240.237419
2 intron_FBgn0264373:2_FBgn0264373:3 56 0
3 intron_FBgn0027570:4_FBgn0027570:3 54 0
Für die 2. Spalte target_id
möchte ich nur die Zeichenfolge (nicht immer FBgnXXXX
, manchmal andere Namen) zwischen intron_
und der ersten behalten :
. Die neue Ausgabedatei enthält also den einfacheren Wert für Spalte 2, aber der Rest der Datei bleibt gleich.
Ich habe es mit dem Sed-Befehl versucht, weiß aber nicht, wie ich den Teil löschen kann, den ich nicht brauche.
Antwort1
Verwenden von sed
und column
:
$ sed -E 's/ intron_([^:]*):[^[:space:]]*/ \1/' file | column -t
id target_id length eff_length
1 FBgn0000721 1136 243.944268
1 FBgn0000721 1122 240.237419
2 FBgn0264373 56 0
Der Schlüssel dazu ist der Ersetzungsbefehl:
s/ intron_([^:]*):\S*/ \1/
Es sucht intron_
und speichert alles nach intron_
und vor dem ersten Doppelpunkt in der Variable 1
. [^[:space:]]*
stimmt mit allem von diesem Doppelpunkt bis zum Ende des Felds überein. All das wird durch den in der Variable gespeicherten Text ersetzt 1
.
Verwendung awk
mit tab-getrennter Ausgabe:
$ awk -v "OFS=\t" '{$2=$2;sub(/intron_/, "", $2); sub(/:.*/, "", $2); print}' file
id target_id length eff_length
1 FBgn0000721 1136 243.944268
1 FBgn0000721 1122 240.237419
2 FBgn0264373 56 0
Erläuterung:
-v "OFS=\t"
Dadurch wird als Ausgabefeldtrennzeichen ein Tabulatorzeichen festgelegt. Dies hilft beim Ausrichten der Spalten und macht möglicherweise
column
unnötige Spalten überflüssig.$2=$2
Beim Drucken einer Zeile
awk
wird unser neu festgelegter Ausgabefeldtrenner nicht geändert, es sei denn, wir ändern etwas in der Zeile. Die Zuweisung des zweiten Felds zum zweiten Feld reicht aus, um sicherzustellen, dass die Ausgabe Tabulatoren enthält.sub(/intron_/, "", $2)
intron_
Dadurch wird es aus dem zweiten Feld entfernt .sub(/:.*/, "", $2)
Dadurch wird alles nach dem ersten Doppelpunkt aus dem zweiten Feld entfernt.
print
Dadurch wird unsere neue Zeile gedruckt.
Verwendung awk
mit benutzerdefinierter Spaltenformatierung
Dies ist wie das obige, wird aber verwendet, printf
damit wir Spaltenbreiten und -ausrichtungen nach Wunsch individuell formatieren können:
$ awk '{sub(/intron_/, "", $2); sub(/:.*/, "", $2); printf "%-3s %-12s %8s %3s\n",$1,$2,$3,$4}' file
id target_id length eff_length
1 FBgn0000721 1136 243.944268
1 FBgn0000721 1122 240.237419
2 FBgn0264373 56 0
Hier printf "%-3s %-12s %8s %3s\n",$1,$2,$3,$4
wählt die Anweisung Spaltenbreiten und -ausrichtungen im gewohnten printf
Stil.
Verwenden sed
und Konvertieren von Tabulator-getrennten zu Komma-getrennten
$ sed -E 's/ intron_([^:]*):[^[:space:]]*/ \1/; s/[[:space:]][[:space:]]*/,/g' file
id,target_id,length,eff_length
1,FBgn0000721,1136,243.944268
1,FBgn0000721,1122,240.237419
2,FBgn0264373,56,0
Antwort2
Sie können Folgendes verwenden perl
:
$ perl -anle '
BEGIN {$" = "\t"}
print "@{[@F]}" and next if $. == 1;
$F[1] = $1 if /_([^:]*):/;
print "@{[@F]}";
' file
id target_id length eff_length
1 FBgn0000721 1136 243.944268
1 FBgn0000721 1122 240.237419
2 FBgn0264373 56 0
3 FBgn0027570 54 0
Erläuterung
-a
: Jede Zeile automatisch in ein Array aufteilen@F
.BEGIN {$" = "\t"}
: Wir setzen den Listentrenner auf Tabulator\t
. Er wird verwendet, wenn ein Array oder ein Array-Segment in eine Zeichenfolge in doppelten Anführungszeichen interpoliert wird.print "@{[@F]}" and next if $. == 1
: Wir drucken die Kopfzeile und gehen zur nächsten Zeile über.$F[1] = $1 if /_([^:]*):/
: Wir erhalten den Wert zwischen_
und dem ersten:
und speichern ihn im zweiten Element in@F
.print "@{[@F]}"
: Drucken Sie einfach die gewünschte Ausgabe aus.
Antwort3
sed -e 'h;s/.*intron_[^:]*\(:[^[:space:]]*\).*/\1/;s/./ /g;;G;;s/\(.*\)\n\(.*\)intron_\([^:]*\):[^[:space:]]*/\2\3\1/' YourFile
In 1 sed (kein Pipe) wird die Spalte beibehalten. Es wird der Haltepuffer verwendet
Posix-Version (also --posix
unter GNU sed)