Encontre pastas que começam com a mesma string

0

Eu tenho mais de 1000 subdiretórios em uma pasta. Alguns deles começam com a mesma string e eu quero encontrar todos os diretórios onde os 5 primeiros caracteres de seu nome são também os 5 primeiros de outro diretório.

Eu não quero procurar por uma string específica, eu preciso de uma maneira de ler o nome do primeiro subdiretório e compará-lo aos 5 primeiros caracteres dos nomes dos outros subdiretórios. Então preciso repetir o processo para o segundo subdiretório, etc.

Todos esses nomes encontrados devem ser gravados em um arquivo de texto.

    
por llizard14 03.07.2016 / 16:16

4 respostas

4

O comando abaixo fará o que você quiser.

find . -maxdepth 1 -type d | sort | uniq -D -w 7

O find lista todos os diretórios no diretório atual, filtra-os por sort (um pré-requisito para usar uniq ) e, em seguida, usa uniq para imprimir todos os duplicados, usando apenas os 7 primeiros caracteres comparação. Usamos 7 caracteres em vez de 5, porque os primeiros 2 caracteres serão ./ .

    
por 03.07.2016 / 18:47
1

Você pode usar a expansão de parâmetro para verificar os 5 primeiros caracteres de uma string.

Apenas faça um loop pelos dirnames ordenados. Os diretórios com o mesmo prefixo devem estar adjacentes em tal lista.

$keep contém o primeiro diretório com um prefixo diferente, $printed é um sinalizador que impede que o $keep seja impresso várias vezes se houver vários diretórios com o mesmo prefixo.

#! /bin/bash
printed=0
keep=''
for dir in */ ; do
    if [[ ${dir:0:5} == ${keep:0:5} ]] ; then
        if ((!printed)) ; then
            echo "$keep"
            printed=1
        fi
        echo "$dir"
    else
        printed=0
        keep=$dir
    fi
done
    
por 03.07.2016 / 16:58
0

Se os nomes dos seus diretórios não contiverem espaços, você pode fazer:

find . -type d -printf '%f\n' | 
    perl -lne '/.{1,5}/; push @{$k{$&}},$_; 
               END{ 
                    map{print if scalar(@{$k{$_}})>1}keys(%k)
               }' > results.txt

Isso localizará todos os subdiretórios do diretório atual e imprimirá seus nomes ( -printf '%f\n' , isso assume o find supports printf ). O script perl usa os primeiros 5 caracteres de cada nome e os usa como chaves para um hash de matrizes cujos valores são os nomes dos diretórios. Em seguida, quaisquer nomes de nomes encontrados mais de uma vez serão impressos.

Se os nomes de seus diretórios puderem conter novas linhas, você poderá ad BEGIN{$/="%code%"} no início do script Perl:

find . -type d -printf '%f
find . -type d -printf '%f\n' | 
    perl -lne '/.{1,5}/; push @{$k{$&}},$_; 
               END{ 
                    map{print if scalar(@{$k{$_}})>1}keys(%k)
               }' > results.txt
' | perl -lne 'BEGIN{$/="
find . -type d -printf '%f%pre%' | 
    perl -lne 'BEGIN{$/="%pre%"} /.{1,5}/; push @{$k{$&}},$_; 
               END{
                 map{print if scalar(@{$k{$_}})>1}keys(%k)
               }' > results.txt
"} /.{1,5}/; push @{$k{$&}},$_; END{ map{print if scalar(@{$k{$_}})>1}keys(%k) }' > results.txt
    
por 03.07.2016 / 18:42
0

Obrigado por todas as sugestões e pelas soluções postadas! Acabei usando find . - maxdepth 1 -type d -print0 | sort -z | uniq -zD -w 7 | tr '%code%' '\n'

Embora não mostre a saída em ordem alfabética adequada, MAS as "duplicatas" são mostradas adjacentes - e isso é o mais importante. Aprendi muito aqui (novamente: -)

    
por 04.07.2016 / 23:21