Supprimer jusqu'à la première occurrence du côlon à l'aide de sed

16

Ma commande sed est,

 sed '/(.*:)/d' <<< 'abcd:bcde:cdeaf'

Il doit revenir,

bcde:cdeaf

(c'est-à-dire) tous les caractères avant le premier deux-points de la ligne et le deux-points lui-même doivent être supprimés.

Mais cela ne supprime rien.

Ma confusion provient principalement de,

1) Faut-il échapper les parens pour la correspondance des motifs à l'intérieur des regex-es sed?

2) Dans les deux cas (avec échappement / sans escpaing), cela ne fonctionne pas. J'ai essayé,

sed -E '/\\(.*:\\)/d' <<< 'abcd:bcde'

la source
1
tu veux sed 's/[^:]*://'. Et vous dn'effacez pas la ligne d'entrée, d'ailleurs, vous la modifiez avec une s///commande d'ubstitution. Vous devez remplacer le premier bit non-colon et le colon qui le suit par rien du tout.
mikeserv
qui résout le problème ... merci, mec ... ceci est un exemple que j'ai pris pour apprendre la correspondance de motifs regex à l'intérieur de sed ... donc, je cherche une réponse qui utilise la correspondance de groupe / motif avec des
3
Ou, en utilisant simplement bash: printf "%s\n" "${line#*:}"...
jasonwryan
1
@jasonwryan - bon point, compte tenu de l'exemple de source. c'est certainement le moyen le plus efficace de le gérer. mais si c'est un while read linequi obtient le $line, seddevrait probablement être préféré.
mikeserv

Réponses:

23
$ echo 'abcd:bcde:cdeaf' | sed 's/^[^:]*://g'
bcde:cdeaf

Le premier ^signifie le début de la ligne. C'est [^:]juste la seule façon dont je sais écrire pas un deux-points . L' *après le colon signifie un certain nombre de choses juste devant moi (dans ce cas, le non-colon). Enfin, le :sélectionne les deux points.

En d'autres termes, sélectionnez le début de la ligne, un nombre quelconque de choses qui ne sont pas des deux points et le premier deux-points.

Le //gmoyen supprime chaque instance correspondante.

user1717828
la source
3
vous n'avez pas besoin d' ^ancrer votre match, sauf que vous ajoutez également un gdrapeau global. il ne peut y avoir qu'une seule première occurrence d'un motif, et donc le gdrapeau lobal ne supprime pas tous les [^:]*:motifs d'une ligne, comme il le ferait si vous ne l' ^ancrez pas. plutôt que de compliquer l'expression régulière avec deux indicateurs inutiles qui ne servent qu'à déséquilibrer l'un l'autre, vous pouvez simplement les laisser de côté, c'est ce que la version éditée de cette réponse a démontré avant de l'annuler. pourquoi vous insisteriez pour diffuser de mauvaises informations, je ne sais pas, mais cela en fait une mauvaise réponse.
mikeserv
@mikeserv, comme je l'ai déjà dit, merci de l'avoir signalé. J'apprécie sincèrement que vous m'aidiez à améliorer mes sedcompétences. Je suis nouveau sedet je ne suis pas encore à l'aise de m'éloigner de la syntaxe très limitée que j'ai choisie jusqu'à présent. Cela sed(heh), je pense que ma réponse résout le problème d'OP même si ce n'est pas la réponse optimale (c'est-à-dire votre). Il s'agit de Stack Exchange, pas de Wikipedia, alors corrigez-moi si je me trompe, mais si vous connaissez une meilleure réponse, vous devez la publier afin que les gens puissent voir la variété des approches et les comparer. Veuillez ne pas transformer ma réponse en votre réponse avec la fonction d' édition .
user1717828
4
ce n'était pas ma réponse. c'était votre réponse, éditée. c'est tout. et c'était bien . ce n'est plus.
mikeserv
4

Pour fonctionner avec des colonnes, il y a cut:

echo 'abcd:bcde:cdeaf' | cut -d: -f2-

faire de même

echo 'abcd:bcde:cdeaf' | cut -d: -f1 --complement

Et autre version avec sed(plus rapide pour le big data):

echo 'abcd:bcde:cdeaf' | sed 's/^://;t;s/:/\n:/;D'

Et plutôt exotique dans bash

echo 'abcd:bcde:cdeaf' | { IFS=: read -r first last ; echo "$last" ; }

ou

echo 'abcd:bcde:cdeaf' | { read -r line ; echo ${line#*:} ; }

ou

echo 'abcd:bcde:cdeaf' | { IFS=: read -a a ; printf '%b:' "${a[@]:1}\c" ; echo ;}
Costas
la source
Vous pouvez également ajouter la bonne façon de le faire avec sed, c'est-à-diresed 's/[^:]*://'
don_crissti
@don_crissti La version est notée dans la réponse ci-dessus. De plus, en raison de l' utilisation de regexp, il est plus lent que pour compiler l'expression dans chaque ligne.
Costas
Non ce n'est pas. La réponse ci-dessus aspire beaucoup de temps et mérite beaucoup de downvotes - surtout si vous lisez les révisions et les commentaires là-bas.
don_crissti