Quero encontrar todos os arquivos pelo comprimento dos nomes dos arquivos.
Por exemplo, se eu quiser encontrar arquivos de comprimento 1, como a.go
, b.go
.
Eu coloco:
grep '.\{1\}' file
Mas isso não funciona. Que comando posso usar para localizar arquivos pelo comprimento do nome do arquivo?
Responder1
Se você deseja apenas encontrar os nomes dos arquivos, pode usar o seguinte comando:
find -exec basename '{}' ';' | egrep '^.{100,}$'
Isso será executado find
, extraindo o nome do arquivo ou diretório usando basename
e, em seguida, procurará qualquer nome de arquivo ou diretório que tenha pelo menos 100 caracteres. Se você quiser encontrar um nome de arquivo com comprimento exato, use {100}
em vez de {100,}
.
Se você quiser encontrar os nomes dos arquivos incluindo o caminho, faça o seguinte:
find | egrep '/[^/]{100,}$'
Isso retornará o nome do arquivo, incluindo o caminho relativo para onde você executou o comando find.
Responder2
grep
procura padrões no conteúdo dos arquivos. Se você quiser dar uma olhada nonomesdos arquivos, você pode apenas usar um shell glob (se quiser considerar apenas nomes de arquivos no diretório atual):
echo ?.go
(A propósito, é o shell que avalia o glob, não o echo
comando.)
Se você quiser procurar diretórios recursivamente, começando pelo diretório atual, a ferramenta a ser usada é find
:
find . -name '?.go'
(Observe que você deve citar o padrão para evitar que o shell o avalie como um glob antes de find
ser invocado.)
Responder3
Em primeiro lugar, grep
pesquise noconteúdode arquivos, ele não procurará nomes de arquivos. Para isso você quer find
. Ele não tem a opção de definir o comprimento do nome do arquivo, mas você pode analisar sua saída para obter o que deseja. Aqui estão alguns exemplos que executo em um diretório contendo os seguintes arquivos:
$ tree
.
├── a
├── ab
├── abc
├── abcd
└── dir
├── a
├── ab
├── abc
└── abcd
A pesquisa de arquivos neste diretório retorna:
$ find . -type f | sort
./a
./ab
./abc
./abcd
./dir/a
./dir/ab
./dir/abc
./dir/abcd
Portanto, para encontrar os arquivos com comprimento X, precisaremos remover o caminho e combinar apenas os caracteres após o último /
:
$ find . -type f | grep -P '/.{3}$'
O sed
comando apenas remove o arquivo ./
. O -P
sinalizador ativa expressões regulares compatíveis com Perl que são necessárias para {n}
as quais é uma coisa PCRE e $
significa "corresponder ao final da string".
Você também pode simplesmente fazer isso:
find . -type f | grep -P '/...$'
Isso é bom para números pequenos, digitar 15 pontos para corresponder a nomes de arquivos de comprimento 15 não é muito eficiente.
Finalmente, se você quiser ignorar a extensão e corresponder apenas ao nome do arquivo, faça isso (como sugerido por @slm):
find . -type f | grep -P '/.{1}\.'
No entanto, isso também encontrará arquivos como a.bo.go
. Isso é melhor se seus nomes de arquivos puderem conter mais de um .
:
find . -type f | grep -P '/.{1}\.[^.]+$'
NOTA: A solução acima pressupõe que você tenha nomes de arquivos relativamente sensatos que não contenham caracteres de nova linha, etc. Também contará e não ignorará espaços em nomes de arquivos ao calcular o comprimento que pode não ser o que você deseja. Se algum desses for um problema, avise-me e atualizarei minha resposta.
Responder4
Você não especifica, mas se os arquivos estiverem dentro de uma estrutura de diretórios, você pode usar find
para localizar arquivos de comprimento 1, com a ajuda de grep
:
$ find . -type f | grep -P '/.{1}\.'
Exemplo
$ find . -type f | grep -P '/.{1}\.' | head -10
./util-linux-2.19/include/c.h
./88366/a.bash
./89186/a.bash
./89563/b.txt
./89563/a.txt
./89563/c.txt
./89563/d.txt
./91734/2.c
./91734/4.c
./91734/1.c