Supondo que você nunca terá mais de um símbolo @
,
sed 's/_.*@/@/' file.txt
... deve funcionar.
Eu tenho os seguintes casos:
[email protected]
[email protected]
[email protected]
Estou tentando convertê-los em
[email protected]
[email protected]
[email protected]
Portanto, deve remover tudo, desde o primeiro '_' (incluindo-o) até o @ (não incluindo isso).
Eu tenho algo, mas não funciona corretamente:
Baseado neste tópico: Corte baseado em dois Delimitadores de uma só vez , e este U & Q & A: Divisão da string pela primeira ocorrência de um delimitador .
sed 's/^.*_\([^ ]*\) .*\@\([^$]*\)$/ /' infile
Mas sem sorte. Alguém quer falar sobre isso?
Não tenho certeza do que você está realmente fazendo com isso, mas você pode fazer isso com sed
:
$ sed 's/\(case\).*\(@test.com\)//' 87529.txt
[email protected]
[email protected]
[email protected]
Isso reduz efetivamente tudo entre case
e @
.
Você pode fazer algo semelhante com awk
:
$ awk -F@ '{split($1,a,"_"); print a[1]"@"$2}' 87529.txt
Também pode ser feito com perl
(semelhante à abordagem do evilsoup):
$ perl -p -e 's/_.*@/@/g' 87529.txt
Ou você pode fazer uso da instalação lookahead de perl
:
$ perl -p -e 's/_.*(?=@)//g' 87529.txt
OBSERVAÇÃO: Lookahead e lookbehind em perl
permitem que você inclua strings no padrão regex com as quais você está combinando, sem que elas sejam incluídas na operação que será executada no regex . Pense nelas como versões dinâmicas do cursor ( ^
) - início de uma linha e dólar ( $
) - fim da linha. Isso é um pouco menos hacky, depois ter que adicionar o @
de volta, depois de removê-lo.
Se as linhas puderem conter mais de um @
:
sed 's/^\([^@_]*\)_[^@]*@/@/'
Ou:
awk -F@ -vOFS=@ 'NF >= 2 {sub(/_.*/,"",$1)};1'
Se o seu shell suporta expansão de parâmetros, você pode fazer algo como
while read line; do
printf "%s\n" "${line%%_*}@${line#*@}"
done < your_file_here
A expansão ${line%%_*}
remove o _
mais à esquerda e tudo o que o segue, enquanto a expansão ${line#*@}
remove o @
mais à esquerda e tudo o que o precede.
do Evilsoup solução parece ser perfeita!
Ainda outra solução usando sed
e awk
.
sed 's/_/ /g; s/@/ /g' file_name | awk '{ print $1"@"$NF '}
Isso não conta exatamente para eficiência, mas pode ser simples de entender, talvez, quando não se quer mexer com expressões regulares. O código acima faz o seguinte:
sed
substitui "_" por um espaço em branco. sed
substitui "@" por um espaço em branco. Então, agora, o conteúdo do arquivo é dividido em várias colunas: case test.com
case 1_2 test.com
case 1 test.com
awk
simplesmente imprime a primeira e a última colunas do conteúdo separado. Aqui, NF
é um símbolo especial em awk
que fornece o número de campos seguidos. Aqui está outro caminho gawk
:
gawk -F_ '{if(NF>1){print $1$NF} else {print $NF}}'
Usando _
como um delimitador de campo, informamos gawk
para imprimir o primeiro e o último campo se houver mais de um campo e o último campo se houver apenas um único campo.
Tags bash awk sed shell-script cut