Comment puis-je tout supprimer après le deuxième deux-points de la deuxième colonne et conserver tout le reste?
J'ai un fichier ( file.bim
) avec environ 1,5 million. lignes qui ressemblent à ceci:
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
Dans la deuxième colonne, je voudrais supprimer le deuxième deux-points et les trois caractères suivants, et conserver les colonnes restantes telles quelles. La sortie souhaitée est la suivante ( 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
J'ai essayé d'utiliser awk
, mais ici seuls les deux points sont supprimés, mais les lettres entre eux restent:
awk -F":" '{ print $1":"$2,$3,$4,$5,$6 }' file.bim > updated_file.bim
Réponses
Vous pouvez utiliser le awk
programme suivant :
awk '{sub(/:[^:]*:[^:]*$/,"",$2)}1' file.bim > updated_file.bim
ou
awk '{sub(/(:[^:]*){2}$/,"",$2)}1' file.bim > updated_file.bim
Cela utilisera la sub()
fonction pour éditer la deuxième colonne ( $2
) en remplaçant les deux dernières :
et le texte qui les suit par "rien", supprimant ainsi effectivement cette partie.
Si le fichier de sortie doit être séparé par des tabulations, utilisez awk -v OFS="\t" ' ... '
.
Sinon , si votre fichier est délimité par des groupes de plus d'un «espace» et que vous voulez vous assurer que la mise en forme du délimiteur est complètement inchangée, vous pouvez utiliser
awk '{sub(/:[^:]*:[^: ]* /," ")}1' file.bim > updated_file.bim
qui recherchera le motif " :
, suivi du texte, suivi de :
, suivi du texte, suivi de l'espace", et remplacera celui-ci par un seul "espace". Dans votre entrée, ce modèle se produit uniquement à la fin de la colonne 2, de sorte que le remplacement n'affectera que cette colonne.
Enfin , si à tout moment dans le futur le nombre de :
champs séparés dans la deuxième colonne peut changer, mais que vous ne voulez toujours conserver que les deux premiers, vous pouvez recourir à ma variante originale bien que moins portable, qui remplace la deuxième colonne par seulement le texte autour du premier :
(au lieu du texte derrière les deux derniers avec "rien"):
awk '{$2=gensub(/([^:]+:[^:]+).*/,"\\1","1",$2)}1' file.bim > updated_file.bim
Supprimez tout après le deuxième deux-points dans la deuxième colonne et conservez tout le reste:
awk '{ c=split($2, s, ":"); $2=s[1] (c>1?":":"") s[2]; }1' infile
comme vous l'avez remarqué, cela supprime les espaces répétés lorsque nous réévaluons la deuxième colonne si ce n'est pas le gros problème de votre côté; sinon utilisez ci-dessous sed
comme alternative:
sed -E 's/^([^ ]* *)([^: ]*:[^: ]*):[^ ]* (.*)/\1\2 \3/' infile
date du test;
::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
résultat:
::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
Avec GNU sed pour \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
ou avec n'importe quel sed POSIX:
$ 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
Utilisez sed pour remplacer tous les espaces vides par ":" puis ignorez les champs $ 6 et $ 7 et mettez le contenu de 4 $ et 5 $ sur 5 $ avec awk:
sed 's/ /:/g' bim | awk -F':' '{ $6=""; $7="" ; $4=$4$5; $5="" }1' > updated_file.bim
SANS SED:
awk '{ gsub(/ /,":",$0); FS=":";$6=""; $7="" ; $4=$4$5; $5="" }1' bim > updated_file.bim
avec d' awk
abord avec substr($2, 1, 8)
vous sélectionnez à partir de 2 $ ce dont vous avez besoin. Et imprimez la valeur de s
au lieu de $2
. Donc, votre code avec ceci peut être:
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
Mis à jour, pour garder les espaces:
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
La sortie suivante peut être obtenue à l'aide de la sed
commande
cat file.bim | sed 's/:[a-zA-Z]//g' >> updated_file.bim
or
cat file.bim | sed 's/:[[:alpha:]]//g' >> updated_file.bim
Production :
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