E a obrigatória sed
solution:
sed '1s/^/#/;x;G;\_#\([^#]*\)#.*\n/_s/\n.*//;s/\n\(.*\)/#/;h;$! d;x;s/^#//;s/#$//;y/#/\n/'
O script coleta caminhos no espaço de armazenamento. Para cada nova linha, o espaço de espera é anexado ao espaço padrão para verificar se já ocorreu.
Esta solução assume que o caractere #
não é usado no arquivo. Caso contrário, use um caractere diferente ou, se você usar o GNU sed
, use a versão curta na parte inferior da postagem.
Explicação detalhada:
1s/^/#/
Para portabilidade, o caractere #
é usado para separar os caminhos no espaço de armazenamento. Para a primeira linha, precisamos começar com um #
inicial
x;G
By exchanging the spaces and appending the hold space, we have the list of already occured buffers first, then the new path.
\_#\([^#]*\)#.*\n/_s/\n.*//
Se o endereço \_..._
corresponder, o novo caminho será um subcaminho de um caminho anterior, portanto, remova-o.
s/\n\(.*\)/#/
Ainda há uma nova linha no nosso espaço, então o caminho é novo e nós o adicionamos à lista.
h;$! d
Salve a nova lista no espaço de espera e comece de novo, se esta não for a última linha.
x;s/^#//;s/#$//;y/#/\n/
Para a última linha, remova o #
no início e no final e substitua o outro #
por novas linhas.
Alternativa para o% GNUsed
Isso pode ser feito de forma mais compacta com as extensões GNU em sed
, se você não se importar se o pedido for revertido:
sed 'G;\_^\([^\n]*\)/.*\n\n_s/[^\n]*\n//;h;$! d;x;s/^\n//;s/\n$//'
Explicação como acima, mas usando as novas linhas como separadores em vez de adicionar #
.