Como posso gerar uma lista de arquivos com seu caminho absoluto no Linux?

304

Estou escrevendo um script de shell que usa caminhos de arquivo como entrada.

Por esse motivo, preciso gerar listagens de arquivos recursivos com caminhos completos. Por exemplo, o arquivo bartem o caminho:

/home/ken/foo/bar

mas, tanto quanto eu posso ver, tanto lse findsó dão listagens de caminho relativo:

./foo/bar   (from the folder ken)

Parece que uma exigência óbvia, mas eu não posso ver nada nos findou lshomem páginas.

Como posso gerar uma lista de arquivos no shell, incluindo seus caminhos absolutos?

Ken
fonte
use:find /home/ken/foo/bar -exec ls -ld $PWD/{} \;
Aluno

Respostas:

305

Se você der findum caminho absoluto para começar, ele imprimirá caminhos absolutos. Por exemplo, para encontrar todos os arquivos .htaccess no diretório atual:

find "$(pwd)" -name .htaccess

ou se o seu shell se expandir $PWDpara o diretório atual:

find "$PWD" -name .htaccess

find simplesmente acrescenta o caminho que foi dado a um caminho relativo para o arquivo desse caminho.

Greg Hewgill também sugeriu o uso pwd -Pse você quiser resolver links simbólicos no diretório atual.

Matthew Scharley
fonte
9
Observe que se você também quiser resolver links simbólicos, use pwd -P.
Greg Hewgill 29/10/08
5
Isso é útil, mas acho que a resposta das user431529 abaixo é mais válida: ls -d -1 $PWD/**/*mas eu acho que find $PWDtambém funciona (testado em bash)
Brian
9
@Brian Why? find $PWDé simples. O lsencantamento é complexo e pesado (a menos que você o atinja). findnão depende de expansões glob do shell, portanto funcionará em qualquer shell. findtambém é muito mais flexível, posso obter uma lista recursiva de todos os arquivos, ou talvez de todos os diretórios, ou talvez eu queira uma lista de todos os arquivos xml ou todos os arquivos alterados na última semana. Tudo isso é possível com find, mas não facilmente com ls.
Matthew Scharley
12
Eu tive que usar find "`pwd`" -name .htaccesspor causa de espaços em nomes de diretório
Paulo Casaretto
Não entendi, esse comando não me fornece o caminho absoluto do arquivo I, enquanto outras respostas na lista fazem o trabalho.
Bjørn Otto Vasbotten
202
readlink -f filename 

fornece o caminho absoluto completo. mas se o arquivo for um link simbólico, você obterá o nome final resolvido.

balki
fonte
8
Agradável. Não funciona na variante BSD do readlink (ou seja, Mac) .Eu uso gnucoreutils no mac. E, portanto, pode usar o greadlink, que funciona com a solução acima.
Sheki
12
Não vá no Mac OS X.
Andrew Lazarus
1
@AndrewLazarus - Para Mac OS X, utilize realpathvez
CZ
se você instalar o bash tools via brew install coreutils, o executável será instalado como/usr/local/opt/coreutils/libexec/gnubin/readlink
redolent
121

Use isso para dirs (o /after **é necessário no bash para limitá-lo aos diretórios):

ls -d -1 "$PWD/"**/

isso para arquivos e diretórios diretamente no diretório atual, cujos nomes contêm um .:

ls -d -1 "$PWD/"*.*

isso para tudo:

ls -d -1 "$PWD/"**/*

Retirado daqui http://www.zsh.org/mla/users/2002/msg00033.html

Na festança, ** é recursivo se você ativar shopt -s globstar.

user431529
fonte
1
ls -d -1 $ PWD / ** / * não é remunerado. Gostaria de poder recuperar meu +1. Você pode fazer ** para cada profundidade que precisar percorrer.
user606723
4
O operador ** é um operador de globbing recursivo. Se você usar o comando em um shell que o suporte (como o zsh), ele funcionará corretamente.
Zebediah49 02/09/19
ls -d1 "$ PWD /"{*,.*} para também capturar os arquivos ocultos (pontos). Para mim, a versão recursiva na resposta não precedeu o caminho absoluto dos arquivos nas subpastas.
Zael
Eu acho que vou ter que usar find ... eu recebo -> bash: / bin / ls: lista de argumentos muito longa
TelamonAegisthus
30

Você pode usar

find $PWD 

na festança

Vinko Vrsalovic
fonte
3
Isso fornecerá o caminho do diretório atual e todos os arquivos e diretórios abaixo dele também. Provavelmente não é isso que as pessoas estão procurando.
Bill
18
ls -d "$PWD/"*

Isso parece apenas no diretório atual . Cita "$ PWD", caso contenha espaços.

didi
fonte
Esta é ainda uma resposta muito válida, mas seria bom para incluir a informação que este não funciona de forma recursiva (que é o que eu estava procurando, na verdade!)
bbbco
1
Para uso recursivo: encontre. -exec ls -ld $ PWD / {} \;
quer
10

Comando: ls -1 -d "$PWD/"*

Isso fornecerá os caminhos absolutos do arquivo, como abaixo.

[root@kubenode1 ssl]# ls -1 -d "$PWD/"*
/etc/kubernetes/folder/file-test-config.txt
/etc/kubernetes/folder/file-test.txt
/etc/kubernetes/folder/file-client.txt
GSM
fonte
8

A $PWDé uma boa opção por Matthew acima. Se você deseja encontrar apenas arquivos de impressão, também pode adicionar a opção -type f para pesquisar apenas arquivos normais. Outras opções são "d" apenas para diretórios etc. Portanto, no seu caso, seria (se eu quiser procurar apenas arquivos com .c ext):

find $PWD -type f -name "*.c" 

ou se você quiser todos os arquivos:

find $PWD -type f

Nota: Você não pode criar um alias para o comando acima, porque $ PWD é preenchido automaticamente no diretório inicial quando o alias está sendo definido pelo bash.

Gurpreet
fonte
Na verdade, -d não significa apenas diretórios - significa que trata diretórios como arquivos. Portanto, se você ls -d / home, voltará "/ home", não uma lista do que está em / home.
Travis
@ Travis: ele estava falando sobre a opção de encontrar, não ls. No caso dele, "find / -type d" encontraria apenas diretórios - como ele disse.
oligofren
6

Se você der ao comando find um caminho absoluto, ele cuspirá os resultados com um caminho absoluto. Portanto, no diretório Ken, se você digitar:

find /home/ken/foo/ -name bar -print    

(em vez do caminho relativo find . -name bar -print)

Voce deveria pegar:

/home/ken/foo/bar

Portanto, se você deseja ls -lque ele retorne o caminho absoluto, basta dizer ao comando find para executar um ls -lno que encontrar.

find /home/ken/foo -name bar -exec ls -l {} ;\ 

NOTA: Há um espaço entre {}e;

Você obterá algo como isto:

-rw-r--r--   1 ken admin       181 Jan 27 15:49 /home/ken/foo/bar

Se você não tiver certeza de onde está o arquivo, sempre poderá alterar o local da pesquisa. Desde que o caminho de pesquisa comece com "/", você receberá um caminho absoluto em troca. Se você estiver pesquisando um local (como /) no qual obterá muitos erros de permissão negada, recomendo redirecionar o erro padrão para que você possa realmente ver os resultados da pesquisa:

find / -name bar -exec ls -l {} ;\ 2> /dev/null

( 2>é a sintaxe dos shells Borne e Bash, mas não funcionará com o shell C. Ele também pode funcionar em outros shells, mas só tenho certeza de que funciona em Bourne e Bash).

Trudius
fonte
Você pode passar vários argumentos para o mesmo lsprocesso com -exec ls -ld {} +. (Você provavelmente -dnão deseja ter o lsconteúdo do diretório da lista). Ou melhor, use o find's incorporado lscom find ... name bar -ls. Além disso, você tem a sintaxe errada para um argumento por comando: você precisa citar o ponto-e-vírgula do shell, por isso é {} \;.
Peter Cordes
5

fd

Usando fd(alternativa a find), use a seguinte sintaxe:

fd . foo -a

Onde .está o padrão de pesquisa efoo o diretório raiz.

Por exemplo, para listar todos os arquivos na etcforma recursiva, execute: fd . /etc -a.

-a, --absolute-path Mostrar absoluta em vez de caminhos relativos

kenorb
fonte
2

Apenas uma alternativa para

ls -d "$PWD/"* 

para identificar que *é a expansão do shell, então

echo "$PWD/"*

faria o mesmo (a desvantagem que você não pode usar -1para separar por novas linhas, não por espaços).

Marisha
fonte
você pode elaborar mais sobre isso? o que é uma expansão de shell? como usar -1para separar por linhas?
Antonio Araujo
@ Antonio Araujo, a expansão do shell é o shell (por exemplo, bash) substituirá * a lista de arquivos - pode ler mais na página de manual do bash. -1 é a opção de comando ls, echo é outro comando, não possui as mesmas opções.
Marisha 23/02
1
lspwd() { for i in $@; do ls -d -1 $PWD/$i; done }
rxw
fonte
1

Aqui está um exemplo que imprime uma lista sem um período extra e também demonstra como procurar uma correspondência de arquivo. Espero que isto ajude:

find . -type f -name "extr*" -exec echo `pwd`/{} \; | sed "s|\./||"
Mike Behr
fonte
1

Isso funcionou para mim. Mas não listou em ordem alfabética.

find "$(pwd)" -maxdepth 1

Este comando lista alfabeticamente e também os arquivos ocultos.

ls -d -1 "$PWD/".*; ls -d -1 "$PWD/"*;
Raveen Kumar
fonte
1

stat

Caminho absoluto de um único arquivo:

stat -c %n "$PWD"/foo/bar
kenorb
fonte
1

Você pode tentar isso.

for name in /home/ken/foo/bar/*
do
    echo $name
done

Você pode obter o caminho do abs usando forloop e echosimplesmente sem find.

fangxl mr
fonte
0

Se você precisar de uma lista de todos os arquivos nos diretórios atual e subdiretório

find $PWD -type f

Se você precisar de uma lista de todos os arquivos apenas no diretório atual

find $PWD -maxdepth 1 -type f
Thyag
fonte
0

Isso fornecerá o caminho canônico (resolverá os links simbólicos): realpath FILENAME

Se você deseja um caminho canônico para o próprio link simbólico, então: realpath -s FILENAME

JGurtz
fonte
0

A maioria, se não todos os métodos sugeridos, resultam em caminhos que não podem ser usados ​​diretamente em algum outro comando do terminal se o caminho contiver espaços. Idealmente, os resultados terão barras pré-adicionadas. Isso funciona para mim no macOS:

find / -iname "*SEARCH TERM spaces are okay*" -print 2>&1  | grep -v denied |grep -v permitted |sed -E 's/\ /\\ /g'
Adão
fonte
-1

find / -print vai fazer isso

David Arno
fonte
1
... infelizmente ele vai fazer outra coisa (como a exibição 'alguns' outros ficheiros a não ser filtrada)
DerMike
-1
ls -1 | awk  -vpath=$PWD/ '{print path$1}'
Albert
fonte