Bagaimana saya bisa menghasilkan daftar file dengan path absolutnya di Linux?

304

Saya menulis skrip shell yang mengambil jalur file sebagai input.

Untuk alasan ini, saya perlu membuat daftar file rekursif dengan path lengkap. Misalnya, file tersebut barmemiliki path:

/home/ken/foo/bar

tetapi, sejauh yang saya bisa lihat, keduanya lsdan findhanya memberikan daftar jalur relatif:

./foo/bar   (from the folder ken)

Sepertinya persyaratan jelas, tapi aku tidak bisa melihat apa-apa di findatau lsmanusia halaman.

Bagaimana saya bisa menghasilkan daftar file di shell termasuk jalur absolutnya?

Ken
sumber
gunakan:find /home/ken/foo/bar -exec ls -ld $PWD/{} \;
Pelajar

Jawaban:

305

Jika Anda memberikan findpath absolut untuk memulai, itu akan mencetak path absolut. Misalnya, untuk menemukan semua file .htaccess di direktori saat ini:

find "$(pwd)" -name .htaccess

atau jika shell Anda mengembang $PWDke direktori saat ini:

find "$PWD" -name .htaccess

find hanya menambahkan path yang diberikan ke path relatif ke file dari path itu.

Greg Hewgill juga menyarankan untuk menggunakan pwd -Pjika Anda ingin menyelesaikan symlink di direktori Anda saat ini.

Matthew Scharley
sumber
9
Perhatikan bahwa jika Anda juga ingin menyelesaikan symlink, gunakan pwd -P.
Greg Hewgill
5
Ini membantu, tapi saya pikir respons pengguna431529 di bawah ini lebih valid: ls -d -1 $PWD/**/*tapi saya kira find $PWDjuga berfungsi (diuji dalam bash)
Brian
9
@ Brian Kenapa? find $PWDsederhana. The lsmantera kompleks dan berat (kecuali jika Anda alias itu). findtidak tergantung pada ekspansi shell glob, sehingga akan bekerja di shell apa pun. findjuga jauh lebih fleksibel, saya bisa mendapatkan daftar rekursif semua file, atau mungkin semua direktori, atau mungkin saya ingin daftar semua file xml, atau semua file berubah dalam seminggu terakhir. Semua itu mungkin dengan find, tetapi tidak dengan mudah ls.
Matthew Scharley
12
Saya harus menggunakan find "`pwd`" -name .htaccesskarena spasi dalam nama direktori
Paulo Casaretto
Saya tidak mengerti, perintah ini tidak memberi saya jalur absolut dari file I, sementara jawaban lain pada daftar melakukan pekerjaan.
Bjørn Otto Vasbotten
202
readlink -f filename 

memberikan jalan absolut penuh. tetapi jika file tersebut adalah symlink, Anda akan mendapatkan nama terselesaikan akhir.

balki
sumber
8
Bagus. Tidak berfungsi pada varian BSD dari readlink (yaitu Mac). Saya menggunakan gnucoreutils di mac. Dan karenanya dapat menggunakan greadlink yang berfungsi dengan solusi di atas.
sheki
12
Jangan gunakan Mac OS X.
Andrew Lazarus
1
@AndrewLazarus - Untuk Mac OS X, gunakan realpathsebagai gantinya
cz
jika Anda menginstal bash tools via brew install coreutils, maka executable akan diinstal sebagai/usr/local/opt/coreutils/libexec/gnubin/readlink
redolent
121

Gunakan ini untuk dirs ( /setelah **ini diperlukan di bash untuk membatasi ke direktori):

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

ini untuk file dan direktori langsung di bawah direktori saat ini, yang namanya mengandung .:

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

ini untuk semuanya:

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

Diambil dari sini http://www.zsh.org/mla/users/2002/msg00033.html

Dalam bash, **bersifat rekursif jika Anda mengaktifkan shopt -s globstar.

pengguna431529
sumber
1
ls -d -1 $ PWD / ** / * tidak berulang. Seandainya saya bisa mengambil kembali +1 saya. Anda dapat melakukan ** untuk setiap kedalaman yang Anda butuhkan.
user606723
4
Operator ** adalah operator globbing rekursif. Jika Anda menggunakan perintah di shell yang mendukungnya (seperti zsh), itu akan berfungsi dengan baik.
zebediah49
ls -d1 "$ PWD /"{*,.*} untuk juga menangkap file (titik) yang tersembunyi. Bagi saya versi rekursif dalam jawabannya tidak menambahkan path absolut ke file dalam subfolder.
Zael
Saya pikir saya harus menggunakan find ... Saya dapatkan -> bash: / bin / ls: Daftar argumen terlalu lama
TelamonAegisthus
30

Kamu bisa memakai

find $PWD 

di bash

Vinko Vrsalovic
sumber
3
Itu akan memberikan jalur direktori saat ini, dan semua file dan direktori di bawahnya juga. Mungkin itu bukan yang dicari orang.
Tagihan
18
ls -d "$PWD/"*

Ini hanya terlihat di direktori saat ini . Itu mengutip "$ PWD" dalam kasus mengandung spasi.

didi
sumber
Ini masih jawaban yang sangat valid, tetapi akan lebih baik untuk memasukkan info bahwa ini tidak bekerja secara rekursif (yang sebenarnya saya cari!)
bbbco
1
Untuk penggunaan rekursif: temukan. -exec ls -ld $ PWD / {} \;
Learner
10

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

Ini akan memberikan path absolut dari file seperti di bawah ini.

[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
sumber
8

Ini $PWDadalah pilihan yang baik oleh Matius di atas. Jika Anda ingin menemukan hanya mencetak file maka Anda juga dapat menambahkan opsi -type f untuk mencari hanya file normal. Pilihan lain adalah "d" untuk direktori saja dll. Jadi dalam kasus Anda itu akan menjadi (jika saya ingin mencari hanya file dengan .c ext):

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

atau jika Anda ingin semua file:

find $PWD -type f

Catatan: Anda tidak dapat membuat alias untuk perintah di atas, karena $ PWD otomatis dilengkapi ke direktori home Anda ketika alias sedang diatur oleh bash.

Gurpreet
sumber
Sebenarnya, -d tidak hanya berarti direktori - ini berarti direktori memperlakukan file seperti file. Jadi jika Anda ls -d / home, Anda akan kembali "/ home", bukan daftar apa yang ada di / home.
Travis
@ Travis: dia berbicara tentang opsi untuk menemukan, bukan ls. Dalam kasusnya "find / -type d" hanya akan menemukan direktori - seperti katanya.
oligofren
6

Jika Anda memberi perintah find jalur absolut, itu akan memuntahkan hasilnya dengan jalur absolut. Jadi, dari direktori Ken jika Anda mengetik:

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

(bukannya jalur relatif find . -name bar -print)

Anda harus mendapatkan:

/home/ken/foo/bar

Oleh karena itu, jika Anda menginginkan ls -ldan mengembalikannya ke jalur absolut, Anda bisa memberi tahu perintah find untuk mengeksekusi ls -lpada apa pun yang ditemukannya.

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

CATATAN: Ada ruang antara {}dan;

Anda akan mendapatkan sesuatu seperti ini:

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

Jika Anda tidak yakin di mana file itu berada, Anda selalu dapat mengubah lokasi pencarian. Selama jalur pencarian dimulai dengan "/", Anda akan mendapatkan jalur absolut sebagai balasannya. Jika Anda mencari lokasi (seperti /) di mana Anda akan mendapatkan banyak kesalahan yang ditolak izin, maka saya akan merekomendasikan redirect kesalahan standar sehingga Anda benar-benar dapat melihat hasil pencarian:

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

( 2>adalah sintaks untuk shell Borne dan Bash, tetapi tidak akan bekerja dengan shell C. Mungkin juga bekerja di shell lain, tetapi saya hanya tahu pasti bahwa itu bekerja di Bourne dan Bash).

Trudius
sumber
Anda dapat mengirimkan beberapa argumen ke lsproses yang sama dengannya -exec ls -ld {} +. (Anda mungkin ingin -dtidak memiliki lsdaftar isi direktori). Atau lebih baik, gunakan fitur bawaan lsdengan find ... name bar -ls. Juga, Anda memiliki sintaks yang salah untuk satu arg per perintah: Anda harus mengutip tanda koma dari shell, jadi begitu {} \;.
Peter Cordes
5

fd

Menggunakan fd(alternatif untuk find), gunakan sintaks berikut:

fd . foo -a

Di mana .pola pencarian dan foodirektori root.

Misalnya untuk daftar semua file dalam etcrekursif, jalankan: fd . /etc -a.

-a, --absolute-path Tampilkan absolut sebagai ganti jalur relatif

kenorb
sumber
2

Hanya sebuah alternatif

ls -d "$PWD/"* 

untuk menunjukkan bahwa *ekspansi shell, jadi

echo "$PWD/"*

akan melakukan hal yang sama (kelemahan yang tidak dapat Anda gunakan -1untuk memisahkan dengan baris baru, bukan spasi).

Marisha
sumber
dapatkah Anda menjelaskan lebih lanjut tentang ini? apa ekspansi shell? bagaimana cara menggunakan -1untuk memisahkan dengan garis?
Antonio Araujo
@Antonio Araujo, ekspansi shell adalah shell (misalnya bash) akan mengganti * dengan daftar file - dapat membaca lebih lanjut di halaman bash man. -1 adalah opsi perintah ls, gema adalah perintah lain, tidak memiliki opsi yang sama.
Marisha
1
lspwd() { for i in $@; do ls -d -1 $PWD/$i; done }
rxw
sumber
1

Berikut adalah contoh yang mencetak daftar tanpa periode tambahan dan yang juga menunjukkan cara mencari kecocokan file. Semoga ini membantu:

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

Ini berhasil untuk saya. Tapi itu tidak tercantum dalam urutan abjad.

find "$(pwd)" -maxdepth 1

Perintah ini mencantumkan secara alfabetis dan juga daftar file yang tersembunyi.

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

stat

Path absolut dari satu file:

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

Anda mungkin ingin mencoba ini.

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

Anda bisa mendapatkan jalur abs menggunakan forloop dan echotanpa itu find.

fangxl mr
sumber
0

Jika Anda perlu daftar semua file saat ini serta sub-direktori

find $PWD -type f

Jika Anda perlu daftar semua file hanya di direktori saat ini

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

Ini akan memberikan jalur kanonik (akan menyelesaikan symlink): realpath FILENAME

Jika Anda ingin jalur kanonik ke symlink itu sendiri, maka: realpath -s FILENAME

JGurtz
sumber
0

Sebagian besar jika tidak semua metode yang disarankan menghasilkan jalur yang tidak dapat digunakan secara langsung di beberapa perintah terminal lain jika jalur tersebut berisi spasi. Idealnya hasilnya akan dipotong miring. Ini berfungsi untuk saya di macOS:

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

find / -print akan melakukan ini

David Arno
sumber
1
... sayangnya itu akan melakukan sesuatu yang lain (seperti menampilkan 'beberapa' file lain kecuali difilter)
DerMike
-1
ls -1 | awk  -vpath=$PWD/ '{print path$1}'
Albert
sumber