Tenho dificuldade em descobrir como remover sequências de texto duplicadas, mas incompletas. Nenhum sucesso usando perl
, awk
ou sed
.
Eu preciso transformar:
a b
a b c
a b c d
a b c d e
a b c d x
a b c d z
em
a b
a b c d e
a b c d x
a b c d z
Todo padrão incompleto deve ser excluído, mas (1) nem cada string final completa e única e (2) nem strings com duas palavras de comprimento.
Todas as respostas que encontrei foram remoção de endereços de duplicatas idênticas.
Supondo que todas as seguintes condições sejam atendidas:
As strings neste arquivo são classificadas (ou seja, as "duplicatas incompletas" que você deseja remover são seguidas pela linha que as contém)
Você deseja corresponder apenas ao INÍCIO da linha, então por exemplo, na sequência seguinte, a primeira linha não será removida (a segunda linha contém a primeira linha, mas não começa com a mesma sequência
Do que isso é muito semelhante a: Usando sed ou awk, como posso excluir uma linha sempre que a próxima linha começar com o mesmo conteúdo seguido por uma barra? .
Aqui está uma solução possível:
Multilinha para legibilidade:
prev
e pule para a próxima linha.prev" "
(prev
com um espaço extra no final) corresponde ao início (índice 1) da linha atual ($0
). Caso contrário, imprima a linha anterior.split(prev, _) == 2
), imprima-a mesmo assim_
apenassplit(prev, _)
como uma dica de que não usarei o array resultante desplit
.$0
) paraprev
.awk
terminar de ler o arquivo, imprima a última linha (prev
), a menos que o arquivo esteja vazio.Exemplo:
Usando qualquer
awk
esort
:O
" "
no final de cada string inindex()
é necessário para quea b d
não corresponda falsamente como uma substring dea b dog
, assumindo que queremos apenas comparações de palavras inteiras, ea b e
corresponda a si mesmo, assumindo que queremos excluir linhas duplicadas exatas, bem como linhas de substring, por exemplo dada esta entrada de amostra mais abrangente:obtemos a saída esperada:
Com o script acima, classificamos a entrada primeiro para que strings mais longas apareçam antes de strings mais curtas que começam com os mesmos caracteres, tornando mais fácil para o awk testar se a string atual é uma substring da anterior, então classificamos novamente para o resultado final.
Essa abordagem de classificação primeiro significa que funcionará independentemente da ordem em que a entrada estiver, por exemplo:
Se também quiséssemos que a ordem de saída fosse igual à ordem de entrada dada a entrada não classificada como acima, poderíamos aplicar um idioma Decorate-Sort-Undecorate para adicionar números de linha originais primeiro, depois classificar e remover aqueles no final: