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