2010-07-21 6 views
22

j'ai de nombreuses lignes de la formegroupes de capture dans sed

ko04062 ko:CXCR3 
ko04062 ko:CX3CR1 
ko04062 ko:CCL3 
ko04062 ko:CCL5 
ko04080 ko:GZMA 

et aimerait bien se débarrasser du ko: bit de la colonne de droite. Je suis en train d'utiliser sed, comme suit:

echo "ko05414 ko:ITGA4" | sed 's/\(^ko\d{5}\)\tko:\(.*$\)/\1\2/' 

qui sort simplement la chaîne d'origine I echo'd. Je suis très nouveau dans les scripts de ligne de commande, sed, pipes etc, alors s'il vous plaît ne soyez pas trop en colère si/quand je fais quelque chose de très bête.

La principale chose qui me trouble est que la même chose se produit si j'inverse le bit \1\2 pour lire \2\1 ou simplement utiliser un groupe. Cela suppose, je suppose, qu'il me manque quelque chose à propos de la mécanique de la sortie d'écho dans sed, ou que mon expression rationnelle est fausse ou que j'utilise sed mal ou que sed n'imprime pas les résultats de la substitution .

Toute aide serait grandement appréciée!

+4

Une raison pour laquelle vous ne pouvez pas utiliser sed 's/ko \: // g'? – Anders

+0

une raison pour laquelle vous n'utilisez pas Perl? :-P – eruciform

+4

ne sait pas Perl! apprendre Sed maintenant. Will apprendre perl, et toute autre chose, au fur et à mesure des besoins ... –

Répondre

21

sed génère son entrée car la substitution ne correspond pas. Puisque vous utilisez probablement GNU sed, essayez ceci:

echo "ko05414  ko:ITGA4" | sed 's/\(^ko[0-9]\{5\}\)\tko:\(.*$\)/\1\2/' 
  • \ d -> [0-9] depuis GNU sed ne reconnaît pas \ d {
  • } -> \ {\} puisque GNU sed par défaut utilise des expressions régulières de base.
+2

cela me donne toujours la même erreur. Je suis en OSX - je ne sais pas comment savoir si j'utilise GNU sed ... –

+7

@Mike Dewar - ooh, c'est une information importante ... je pense qu'OS X utilise un sed semblable à BSD, alors que c'est un hypothèse commune ici que les gens utilisent GNU sed –

+0

c'est important de savoir! Merci beaucoup! –

9

Cela devrait le faire. Vous pouvez également ignorer le dernier groupe et simplement utiliser, \1 à la place, mais puisque vous apprenez sed et regex c'est une bonne chose. Je voulais utiliser un groupe non-capturant au milieu (:?) mais je ne pouvais pas obtenir ça pour jouer avec sed pour une raison quelconque, peut-être que ce n'est pas supporté.

sed --posix 's/\(^ko[0-9]\{5\}\)\(ko:\)\(.*$\)/\1 \3/g' file > result 

Et vous pouvez utiliser ofcourse

sed --posix 's/ko://' 
+0

Merci beaucoup pour ça! J'ai voté pour votre réponse parce que vous avez totalement cloué ceci, et le 's/ko: //' est génial (mais que fait ce backtick?). Je donne la tique à ninjalj cos sa réponse + commentaires a expliqué ce que je faisais mal. Mais je colle définitivement à 's/ko: //' ou peut-être même à la chaîne remplacée par getekha! Je vais voir qui est le plus rapide ... –

+0

Mon mauvais, les restes d'une variable. Ouais je le lui donnerais aussi, il a vraiment pris la peine d'expliquer. – Anders

5

Vous ne besoin sed pour cette

Voici comment vous pouvez le faire avec bash:

var="ko05414 ko:ITGA4" 
echo ${var//"ko:"} 

$ {var // "ko:"} remplace tout "ko:" par ""

Voir Manipulating Strings pour plus d'infos

+0

Lire les commentaires, il a dit qu'il apprend sed. – Anders

+3

pendant que je suis/apprends sed, cette approche me semble aussi brillante et simple. Je n'avais aucune idée de cette syntaxe. Toute cette ligne de commande fu est géniale. –

+1

Mon erreur, je m'excuse de getekha. – Anders

0

@OP, si vous voulez juste pour se débarrasser de "ko", puis

$ cat file 
ko04062 ko:CXCR3 
ko04062 ko:CX3CR1 
ko04062 ko:CCL3 
ko04062 ko:CCL5 
some text with a legit ko: this ko: will be deleted if you use gsub. 
ko04080 ko:GZMA 

$ awk '{sub("ko:","",$2)}1' file 
ko04062 CXCR3 
ko04062 CX3CR1 
ko04062 CCL3 
ko04062 CCL5 
some text with a legit ko: this ko: will be deleted if you use gsub. 
ko04080 GZMA 

jsut une note. Bien que vous puissiez utiliser la substitution pure chaîne de bash, c'est seulement plus efficace quand vous changez une seule chaîne. Si vous avez un fichier, en particulier un gros fichier, utiliser la boucle de lecture de bash est encore plus lent que d'utiliser sed ou awk.

Questions connexes