Excluir até a primeira ocorrência de dois pontos usando sed

16

Meu comando sed é,

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

Deve retornar,

bcde:cdeaf

(ou seja) todos os caracteres antes do primeiro dois pontos na linha e o próprio dois pontos devem ser removidos.

Mas isso não está removendo nada.

Minha confusão surge principalmente devido a,

1) As parênteses para a correspondência de padrões precisam ser escapadas dentro dos regex-es sed?

2) Nos dois casos (com escape / sem escape), ele não está funcionando. Eu tentei,

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

fonte
1
você quer sed 's/[^:]*://'. E você não está dexcluindo a linha de entrada, a propósito, está modificando-a com um s///comando de substituição. Você precisa substituir o primeiro bit que não é cólon e o cólon que o segue com nada.
mikeserv
que resolve isso ... obrigado, cara ... esse é um exemplo que eu peguei para aprender a correspondência de padrões regex dentro do sed ... então, estou procurando uma resposta que use correspondência de grupo / padrão com
3
Ou, apenas usando o bash: printf "%s\n" "${line#*:}"...
jasonwryan
1
@jasonwryan - bom argumento, considerando a fonte de exemplo. é definitivamente a maneira mais eficiente de lidar com isso. mas se é um while read lineque recebe o $line, provavelmente seddeve ser o preferido.
mikeserv

Respostas:

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

O primeiro ^significa o início da linha. O [^:]é apenas a única maneira que eu sei como escrever não um cólon . O *após o cólon significa qualquer número de coisas que estão diante de mim (neste caso, o não-cólon). Finalmente, o :seleciona o cólon.

Em outras palavras, selecione o início da linha, qualquer número de coisas que não sejam dois pontos e o primeiro dois pontos.

Os //gmeios excluem todas as instâncias correspondentes.

user1717828
fonte
3
você não precisa ^ancorar sua correspondência, exceto porque você também adiciona uma gbandeira global. só pode haver uma 1ª ocorrência de um padrão e, portanto, a gbandeira lobal não remove todos os [^:]*:padrões de uma linha, como faria se você não o ^ancorasse. em vez de complicar o regex com dois sinalizadores desnecessários que servem apenas para desequilibrar um ao outro, você pode simplesmente excluí-los, que é o que a versão editada desta resposta demonstrou antes de você reverter. por que você insistiria em divulgar informações ruins, eu não sei, mas isso faz uma resposta ruim.
mikeserv
@ mikeserv, como eu já disse, obrigado por apontar isso. Agradeço sinceramente que você me ajude a melhorar minhas sedhabilidades. Eu sou novo sede ainda não me sinto confortável em me afastar da sintaxe muito limitada que peguei até agora. Isso sed(heh), acho que minha resposta resolve o problema do OP, mesmo que não seja a melhor (ou seja, sua) resposta. Este é o Stack Exchange, não o Wikipedia, então me corrija se eu estiver errado, mas se você souber uma resposta melhor, deve publicá-la para que as pessoas possam ver a variedade de abordagens e compará-las. Por favor, não transforme minha resposta em sua resposta com a função de edição .
user1717828
4
não foi a minha resposta. foi sua resposta, editada. Isso é tudo. e foi bom . não é mais.
mikeserv
4

Para operar com colunas, existe cut:

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

o mesmo

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

E outra versão com sed(mais rápido para big data):

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

E bastante exótico em 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
fonte
Você também pode adicionar a maneira correta de fazê-lo com sed, que ésed 's/[^:]*://'
don_crissti
@don_crissti A versão está anotada na resposta acima. Além disso, devido ao uso do regexp , é mais lento, pois é necessário compilar a expressão em cada linha.
Costas
Não, não é. A resposta acima é péssima e merece muitos votos negativos - especialmente se você ler as revisões e os comentários.
31817 don_crissti