Listar arquivos recursivamente na CLI do Linux com o caminho relativo ao diretório atual

224

Isso é semelhante a esta pergunta , mas quero incluir o caminho relativo ao diretório atual no unix. Se eu fizer o seguinte:

ls -LR | grep .txt

Não inclui os caminhos completos. Por exemplo, eu tenho a seguinte estrutura de diretórios:

test1/file.txt
test2/file1.txt
test2/file2.txt

O código acima retornará:

file.txt
file1.txt
file2.txt

Como posso incluir os caminhos relativos ao diretório atual usando comandos padrão do Unix?

Darryl Hein
fonte
4
Isso apenas mostra que ls está faltando esse recurso.
Arjun Singri 14/05
1
É uma pena que todas essas soluções exijam findou tree. Estou ssh'ing em um dispositivo Android onde eu parecem ter apenas ls, e nenhuma dessas outras ferramentas: /
Ponkadoodle

Respostas:

304

Use find:

find . -name \*.txt -print

Em sistemas que usam o GNU find, como a maioria das distribuições GNU / Linux, você pode deixar de fora a impressão.

Andru Luvisi
fonte
11
... e, nesse caso, você pode deixar de fora o '.'
Adam Mitz 29/10/08
7
Para caminhos absolutos, usefind $(pwd) -name \*.txt
Zags
2
Se o padrão tiver parte do nome do diretório, use em -path "*docs/*.txt"vez de -name. -wholenameé o mesmo que-path
dashesy 23/02
9
Use -type fpara retornar apenas arquivos, e não diretórios, links simbólicos etc.
user
2
-name "*.txt"vai NÃO corresponder file.TXT- sempre usar -iname "*.txt"em vez que é case-insensitive.
Ccpizza
73

Use tree, com -f(caminho completo) e -i(sem linhas de indentação):

tree -if --noreport .
tree -if --noreport directory/

Você pode usar greppara filtrar os que deseja.


Se o comando não for encontrado, você pode instalá-lo:

Digite o seguinte comando para instalar o comando tree no RHEL / CentOS e Fedora linux:

# yum install tree -y

Se você estiver usando Debian / Ubuntu, o Mint Linux digite o seguinte comando no seu terminal:

$ sudo apt-get install tree -y
Stephen Irons
fonte
2
alguma configuração para listar apenas os arquivos e excluir pastas?
thebugfinder
25

Tente find. Você pode procurar exatamente na página de manual, mas é mais ou menos assim:

find [start directory] -name [what to find]

então para o seu exemplo

find . -name "*.txt"

deve dar o que você quer.

Jonathan Adelson
fonte
9

Você pode usar o find:

find . -name '*.txt'
Sherm Pendley
fonte
5

Isso faz o truque:

ls -R1 $PWD | while read l; do case $l in *:) d=${l%:};; "") d=;; *) echo "$d/$l";; esac; done | grep -i ".txt"

Mas faz isso "pecando" com a análise de ls, no entanto, que é considerada má forma pelas comunidades GNU e Ghostscript.

El Guesto
fonte
2
@ CAFEBABE: é considerado tabu analisar os resultados lsporque geralmente leva a erros. A frase em questão estava tentando chamar isso. Também tinha uma piada que eu removi.
Adam Katz
4
DIR=your_path
find $DIR | sed 's:""$DIR""::'

'sed' apagará 'your_path' de todos os resultados 'find'. E você recebe em relação ao caminho 'DIR'.

h-dima
fonte
isso é exatamente o que eu preciso, mas ainda cospe o caminho completo para mim?
v3nt
1
não use o apóstrofo - find / tmp | sed s: "/ tmp" :: | mais
Kieren Dixon
4

Para obter os nomes reais dos arquivos de caminho completo dos arquivos desejados usando o comando find, use-o com o comando pwd:

find $(pwd) -name \*.txt -print
ZaSter
fonte
1

Aqui está um script Perl:

sub format_lines($)
{
    my $refonlines = shift;
    my @lines = @{$refonlines};
    my $tmppath = "-";

    foreach (@lines)
    {
        next if ($_ =~ /^\s+/);
        if ($_ =~ /(^\w+(\/\w*)*):/)
        {
            $tmppath = $1 if defined $1;    
            next;
        }
        print "$tmppath/$_";
    }
}

sub main()
{
        my @lines = ();

    while (<>) 
    {
        push (@lines, $_);
    }
    format_lines(\@lines);
}

main();

uso:

ls -LR | perl format_ls-LR.pl
Eric Keller
fonte
Este é um programa Perl terrível. Provavelmente é 2-3 vezes mais longo e complicado do que precisa ser.
Brad Gilbert
1

Você pode criar uma função shell, por exemplo, no seu .zshrcou .bashrc:

filepath() {
    echo $PWD/$1
}

filepath2() {
    for i in $@; do
        echo $PWD/$i
    done
}

O primeiro funcionaria apenas em arquivos únicos, obviamente.

rxw
fonte
1

Encontre o arquivo chamado "filename" no seu sistema de arquivos iniciando a pesquisa no diretório raiz "/". O "nome do arquivo"

find / -name "filename" 
user2101432
fonte
1

Se você deseja preservar os detalhes, como ls como o tamanho do arquivo, etc, na sua saída, isso deve funcionar.

sed "s|<OLDPATH>|<NEWPATH>|g" input_file > output_file
rajeshk
fonte
1

No shell do peixe , você pode fazer isso para listar todos os pdfs recursivamente, incluindo os do diretório atual:

$ ls **pdf

Apenas remova 'pdf' se você quiser arquivos de qualquer tipo.

rien333
fonte
0

Você pode implementar essa funcionalidade como esta
Primeiramente, usando o comando ls apontado para o diretório de destino. Mais tarde, usando o comando find, filtre o resultado. Do seu caso, parece que - sempre o nome do arquivo começa com uma palavra file***.txt

ls /some/path/here | find . -name 'file*.txt'   (* represents some wild card search)
Sireesh Yarlagadda
fonte
0

No mycase, com comando em árvore

Caminho relativo

tree -ifF ./dir | grep -v '^./dir$' | grep -v '.*/$' | grep '\./.*' | while read file; do
  echo $file
done

Caminho absoluto

tree -ifF ./dir | grep -v '^./dir$' | grep -v '.*/$' | grep '\./.*' | while read file; do
  echo $file | sed -e "s|^.|$PWD|g"
done
Matsumoto Kazuya
fonte