Campo de texto com informação duplicada

1

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.

    
por innocentunremarkable 13.05.2016 / 17:33

3 respostas

0

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.

    
por 13.05.2016 / 17:59
1

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 ' ; '

    
por 13.05.2016 / 17:59
0

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 '...'

    
por 14.05.2016 / 05:14

Tags