Comando ls: como posso obter uma listagem de caminho completo recursiva, uma linha por arquivo?

493

Como faço para que o ls cuspa uma lista simples de caminhos recursivos de uma por linha?

Por exemplo, eu quero apenas uma lista simples de arquivos com seus caminhos completos:

/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow
/home/dreftymac/stackoverflow/alpha.txt
/home/dreftymac/stackoverflow/bravo.txt
/home/dreftymac/stackoverflow/charlie.txt

ls -a1 quase faz o que preciso, mas não quero fragmentos de caminho, quero caminhos completos.

dreftymac
fonte
Veja também: tree
dreftymac 19/02/19

Respostas:

386

Se você realmente deseja usar ls, formate sua saída usando o awk:

ls -R /path | awk '
/:$/&&f{s=$0;f=0}
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}
NF&&f{ print s"/"$0 }'
ghostdog74
fonte
5
@dreftymac, o que significa que essa é, objetivamente falando, a resposta certa para a pergunta que você escreveu, intencionalmente ou não. Sim, possivelmente não era a resposta certa para a pergunta que você esperava ter escrito. E, embora eu concorde com o seu argumento maior: "quando o sábio aponta para a lua, o tolo olha para o dedo" é justo que minimizemos o impacto da subjetividade para avaliar a correção, especialmente quando os critérios não têm ambiguidade possível
Lurscher # 30/12
1
@dreftymac, eu vou ser feliz para mudar o meu voto, mas agora está bloqueado, você precisa editar a pergunta para que eu possa atualizar o voto
lurscher
7
Alguém pode explicar as awkexpressões acima ?
Mert Nuhoglu 10/10
2
Esta solução não omitir os diretórios (cada diretório tem sua própria linha)
JayB
2
Obrigado. Btw, seria bom ter isso em 1 linha para copiar e colar rapidamente.
Leo Ufimtsev
567

Use find:

find .
find /home/dreftymac

Se você deseja apenas arquivos (omita diretórios, dispositivos etc.):

find . -type f
find /home/dreftymac -type f
stefanB
fonte
2
pode lsparâmetros como --sort=extension"redimido" por esta solução?
N611x007
Você ainda pode usar a saída printf para exibir informações contextuais necessárias (por exemplo, encontrar -type f -printf '% p% u \ n'.)
xsubira
Isso pode ser formatado com um falg? ie python pprint.pprint (arquivos)
Nathan
72

ls -ld $(find .)

se você deseja classificar sua saída por tempo de modificação:

ls -ltd $(find .)

outras
fonte
11
-bash: / bin / ls: Lista de argumentos muito longa
jperelli 1/12
1
+1 funcionou para mim com 12106 arquivos, e eu poderia usar o --sort=extensionparâmetro dels
n611x007
3
Obrigado. Eu não teria pensado por mim de que (agradável e curto) sintaxe - eu teria usado find . -name "*" -exec ls -ld '{}' \;(que um funciona independentemente do número de arquivos é), mas o seu comando é o caminho mais curto para escrever;)
SRG
1
ls -ld $ (find.) quebra para mim se eu estiver listando um disco NTFS em que os arquivos têm espaços: ls: não pode acessar ./System: Nenhum arquivo ou diretório, no entanto, é encontrado com aspas por @SRG works
kuz8
Uma alternativa mais curta (dependendo de suas necessidades) seria find . -ls.
IANS
59

Tente da seguinte maneira mais simples:

find "$PWD"
Ivan Alegre
fonte
9
find "`pwd`"se o caminho contiver espaços ou outros caracteres especiais.
usar o seguinte código
7
Como isso é diferente find .? -.-
Salman von Abbas
7
@SalmanPK Se você encontrar um caminho absoluto pwdpara começar, ele imprimirá caminhos absolutos. By the way, "Como isso é diferente do que find" ;-)
yckart
44

O melhor comando é: tree -fi

Para usar os arquivos, mas não os links, você deve remover >da sua saída:

tree -fi |grep -v \>

Se você deseja conhecer a natureza de cada arquivo (para ler apenas arquivos ASCII, por exemplo) com dois whiles:

tree -fi | \
grep -v \> | \
while read first ; do 
    file ${first}
done | \
while read second; do 
    echo ${second} | grep ASCII
done
kerkael
fonte
Obrigado, eu não sabia tree!
9788 Dan Filimon
@Nakilon, qual é a coisa mais próxima? Ele exibe a saída da mesma forma? Como você exibia facilmente resultados semelhantes com um comando curto ?
Om01 18/09/2013
6
@ om01: no OSX é uma difícil como brew install tree, dado que você está usando homebrew
ccpizza
não consegui listar os arquivos com exclusividade. ele sempre lista os diretórios também. Como eu posso fazer isso?
usar o seguinte código
Isso deve ser avaliado muito mais alto!
Der_grund 05/07/19
44

Oh, realmente uma longa lista de respostas. Ajudou bastante e, por fim, criei o meu próprio que estava procurando:

Para listar todos os arquivos em um diretório e seus subdiretórios:

find "$PWD" -type f

Para listar todos os diretórios em um diretório e seus subdiretórios:

find "$PWD" -type d

Para listar todos os diretórios e arquivos em um diretório e seus subdiretórios:

find "$PWD"
Padrinho
fonte
2
E para filtrar por extensão:find "$PWD" -type f | grep '\.json$'
Killroy 15/01/19
2
Não há necessidade de pós-processamento com grep, use -name em find like: find "$ PWD" -type f -name * .json e se você deseja excluir os arquivos listados: localize "$ PWD" -type f -name * .json -exec rm {} \; da mesma forma, se você quiser copiá-lo, substitua rm por cp e destination: -exec cp {} destination
Godfather
18

Não sei o caminho completo, mas você pode usar -Rpara recursão. Como alternativa, se você não se interessa ls, pode fazê-lo find *.

Justin Johnson
fonte
16

Usando nenhum comando externo além de ls:

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

Idelic
fonte
Opção desconhecida '-1'. Abortando.
ILW
15
du -a

Útil para alguns reservatórios de eletrodomésticos limitados, onde a localização / localização não está disponível.

Rob D
fonte
1
alguma idéia de como posso remover o tamanho do arquivo sem awk?
Arnold Roa
12

encontre / fará o truque

Dmitry
fonte
10

Não torne complicado. Eu apenas usei isso e obtive uma saída bonita:

ls -lR /path/I/need
KellyC
fonte
3
O OP quer apenas o caminho completo e nada mais. ls -lRnão atingiria esse objetivo.
codeforester
Desculpe, não fazê-lo
Aryeh Beitz
9

A maneira mais fácil para todas as futuras pessoas é simplesmente:

du

No entanto, isso também mostra o tamanho do conteúdo de cada pasta. Você pode usar o awk para gerar apenas o nome da pasta:

du | awk '{print $2}'

Edit- Desculpe, desculpe, meu mal. Eu pensei que eram apenas as pastas que eram necessárias. Vou deixar isso aqui, caso alguém no futuro precise de qualquer maneira ...

6112115
fonte
Interessante, porque me mostra coisas que eu não sabia que queria saber - como o Google sugere. Acontece que eu gosto de saber quanto espaço cada arquivo ocupa.
Jake Toronto
9

Com a liberdade de usar todas as opções possíveis de ls:

find -type f | xargs ls -1

Grzegorz Luczywo
fonte
9

Para uma lista simples, acho que a melhor maneira é:

find -D tree /fullpath/to-dir/ 

(ou para salvá-lo em um arquivo txt)

find -D tree /fullpath/to-dir/ > file.txt
Dimitrios
fonte
3
Tentei no Mac OS 10.13.3. find: illegal option -- D
Jayant Bhawal
8

Execute um comando bash com o seguinte formato:

find /path -type f -exec ls -l \{\} \;
Denio Mariz
fonte
6

Aqui está uma resposta parcial que mostra os nomes dos diretórios.

ls -mR * | sed -n 's/://p'

Explicação:

ls -mR * lista os nomes completos de diretórios que terminam em ':' e, em seguida, lista os arquivos nesse diretório separadamente

sed -n 's/://p' localiza linhas que terminam em dois pontos, retira os dois pontos e imprime a linha

Ao iterar sobre a lista de diretórios, também devemos encontrar os diretórios. Ainda trabalhando nisso. É um desafio obter os curingas através do xargs.

Kevin
fonte
ótima resposta .. exatamente o que eu precisava!
Selvin 30/01
5

A adição de um curinga ao final de um diretório ls força os caminhos completos. Agora você tem o seguinte:

$ ls /home/dreftymac/
foo.txt
bar.txt
stackoverflow
stackoverflow/alpha.txt
stackoverflow/bravo.txt
stackoverflow/charlie.txt

Você poderia fazer isso:

$ ls /home/dreftymac/*
/home/dreftymac/.
/home/dreftymac/foo.txt
/home/dreftymac/bar.txt
/home/dreftymac/stackoverflow:
alpha.txt
bravo.txt
charlie.txt

Infelizmente, isso não imprime o caminho completo dos diretórios retornados, portanto pode não ser a solução completa que você está procurando.

Koeselitz
fonte
Infelizmente, você também não pode sudo ls com um curinga (porque o curinga é expandido como o usuário normal).
andrew lorien
4

Muitas respostas eu vejo. Este é meu, e acho útil se você estiver trabalhando no Mac.

Tenho certeza de que você sabe que existem alguns arquivos "bundle" ( .app , .rtfd , .workflow e assim por diante). E olhando para a janela do Finder, eles parecem arquivos únicos. Mas eles não são. E $ lsou $ findvê-los como diretórios ... Portanto, a menos que você precise listar o conteúdo deles, isso funciona para mim:

find . -not -name ".*" -not -name "." | egrep -v "\.rtfd/|\.app/|\.lpdf/|\.workflow/"

Claro que isso é para o diretório que está funcionando e você pode adicionar extensões de outros pacotes (mas sempre com um /depois deles). Ou quaisquer outras extensões, se não o pacote, sem o /.

Bastante interessante o " .lpdf/" (pdf multilíngue). Tem .pdfextensão " " normal (!!) ou nenhuma no Finder. Dessa forma, você obtém (ou conta apenas 1 arquivo) por isso pdfe não um monte de coisas…

Steve
fonte
4

ls -lR é o que você estava procurando, ou pelo menos eu estava. Felicidades

sivi
fonte
O OP quer apenas o caminho completo e nada mais. ls -lRnão atingiria esse objetivo.
Hadrien TOMA
3

Se o diretório for passado como um caminho relativo e você precisará convertê-lo em um caminho absoluto antes de chamar find. No exemplo a seguir, o diretório é passado como o primeiro parâmetro para o script:

#!/bin/bash

# get absolute path
directory=`cd $1; pwd`
# print out list of files and directories
find $directory
John Keyes
fonte
Se o seu sistema tiver, readlinkvocê pode fazerdirectory=$(readlink -e $1)
Pausado até novo aviso.
É verdade, mas a combinação cd / pwd funcionará em todos os sistemas. readlinkno OS X 10.5.8 não suporta a opção -e.
John Keyes
3
tar cf - $PWD|tar tvf -             

Isso é lento, mas funciona recursivamente e imprime diretórios e arquivos. Você pode canalizá-lo com o awk / grep se quiser apenas os nomes dos arquivos sem todas as outras informações / diretórios:

tar cf - $PWD|tar tvf -|awk '{print $6}'|grep -v "/$"          
RegraB
fonte
2
você também pode usar simplesmente: tar cvf / dev / null $ PWD
RuleB
2

@ ghostdog74: Pequenos ajustes na sua solução.
O código a seguir pode ser usado para pesquisar arquivos com seu caminho absoluto completo.

sudo ls -R / | awk '<br/>
/:$/&&f{s=$0;f=0}<br/>
/:$/&&!f{sub(/:$/,"");s=$0;f=1;next}<br/>
NF&&f{ print s"/"$0 }' | grep [file_to_search]
Chaitanya
fonte
1

Eu sabia o nome do arquivo, mas também queria o diretório.

encontre $ PWD | nome do arquivo fgrep

funcionou perfeitamente no Mac OS 10.12.1

hpj
fonte