POSIXly:
sed -e 's/\([^;][^;]*\);//g' <file
Você também pode usar:
sed -E 's/([^;]+);//g' <file
que foi suportado pelo GNU e BSD sed, e se tornará padrão no próximo POSIX.
Eu tenho um arquivo de dados delimitado por tabulação com campos de texto, onde alguns campos têm informações duplicadas, delimitados por ponto-e-vírgula:
2000;2000
05/19/2016;05/19/2016
foo;foo
Como posso usar o sed
para remover a parte duplicada? Os pontos-e-vírgulas podem aparecer regularmente em outros campos, então acho que preciso pesquisar em uma string encontrada nos dois lados de um ponto-e-vírgula, vinculada por tabulações, ou seja, \t$1;$1\t
( \t
significou representar a tabulação) e substitua com a mesma instância $1
sem o ponto e vírgula e campo duplicado. Estou aberto a outros comandos de análise de texto.
Com isso no arquivo tabbed.input
(sem espaços, todos os espaços em branco consecutivos são uma única guia):
abc bd c 2000;2000 d 2;00;2;01
e 05/19/2016;05/19/2016 foo;foo f g
o seguinte programa em Python:
def cleaned(f):
length = len(f)
if (length % 2) == 0:
return f # even number of characters in field, middle one never ';'
half_way = length // 2
if f[half_way] != ';':
return f
before, after = f[:half_way], f[half_way+1:]
if before == after:
return before
return f
with open('tabbed.input') as fp:
for line in fp:
fields = line[:-1].split('\t')
cleaned_fields = [cleaned(f) for f in fields]
print('\t'.join(cleaned_fields))
sua saída será:
012345670123456701234567012345670123456701234567
abc bd c 2000 d 2;00;2;01
e 05/19/2016 foo f g
Ao testar um número par de caracteres e ter um ' ;
' no meio de um campo, isso também funcionará quando os dados duplicados contiverem um ' ;
'
com perl
:
perl -F'\t' -e 'map {s/(.+);$1/$1/} @F; print join("\t",@F)'
Diferentemente da solução sed
, isso processa cada campo individualmente, o que impede a possibilidade de uma duplicata de campo cruzado ser detectada e excluída (por exemplo, foo;<TAB>foo
- a TAB e a segunda foo
são excluídas pela sed
solução, mas não por essa perl
solution). Dependendo de seus dados de entrada, isso provavelmente não é um problema em seu uso no mundo real.
A versão a seguir elimina várias duplicatas em um campo (por exemplo, a;b;a;b;a;b
- > a;b
):
perl -F'\t' -e 'map {while(/(.+);$1/) {s/(.+);$1/$1/g}} @F;print join("\t",@F)'
NOTA: eles pressupõem uma versão recente de perl
, em que -F
implica -a
e -n
. Se você tiver uma versão mais antiga, use perl -F'\t' -ane '...'
Tags sed