Làm cách nào tôi có thể tạo danh sách các tệp có đường dẫn tuyệt đối của chúng trong Linux?


304

Tôi đang viết một kịch bản shell lấy đường dẫn tệp làm đầu vào.

Vì lý do này, tôi cần tạo danh sách tệp đệ quy với đường dẫn đầy đủ. Ví dụ: tệp barcó đường dẫn:

/home/ken/foo/bar

nhưng, theo như tôi có thể thấy, cả hai lsfindchỉ đưa ra danh sách đường dẫn tương đối:

./foo/bar   (from the folder ken)

Có vẻ như là một yêu cầu rõ ràng, nhưng tôi không thể thấy bất cứ điều gì trong các trang findhoặc lsngười đàn ông.

Làm cách nào tôi có thể tạo danh sách các tệp trong trình bao gồm các đường dẫn tuyệt đối của chúng?


sử dụng:find /home/ken/foo/bar -exec ls -ld $PWD/{} \;
Người học

Câu trả lời:


305

Nếu bạn đưa ra findmột đường dẫn tuyệt đối để bắt đầu, nó sẽ in các đường dẫn tuyệt đối. Ví dụ: để tìm tất cả các tệp .htaccess trong thư mục hiện tại:

find "$(pwd)" -name .htaccess

hoặc nếu shell của bạn mở rộng $PWDđến thư mục hiện tại:

find "$PWD" -name .htaccess

find chỉ cần chuẩn bị đường dẫn mà nó đã được cung cấp cho một đường dẫn tương đối đến tệp từ đường dẫn đó.

Greg Hewgill cũng đề xuất sử dụng pwd -Pnếu bạn muốn giải quyết các liên kết tượng trưng trong thư mục hiện tại của mình.


9
Lưu ý rằng nếu bạn cũng muốn giải quyết các liên kết tượng trưng, ​​hãy sử dụng pwd -P.
Greg Hewgill

5
Điều này hữu ích, nhưng tôi nghĩ phản hồi của người dùng 431529 dưới đây hợp lệ hơn: ls -d -1 $PWD/**/*nhưng tôi đoán find $PWDcũng hoạt động (được thử nghiệm trong bash)
Brian

9
@Brian Tại sao? find $PWDThì đơn giản. Câu lsthần chú rất phức tạp và khó sử dụng (trừ khi bạn đặt bí danh cho nó). findkhông phụ thuộc vào mở rộng toàn cầu shell, vì vậy sẽ hoạt động trong bất kỳ shell nào. findcũng linh hoạt hơn rất nhiều, tôi có thể nhận được một danh sách đệ quy của tất cả các tệp, hoặc có thể của tất cả các thư mục hoặc có thể tôi muốn một danh sách tất cả các tệp xml hoặc tất cả các tệp đã thay đổi trong tuần trước. Tất cả những gì có thể với find, nhưng không dễ dàng với ls.
Matthew Scharley

12
Tôi đã phải sử dụng find "`pwd`" -name .htaccessvì khoảng trắng trong tên thư mục
Paulo Casaretto

Tôi không hiểu, lệnh này không cung cấp cho tôi đường dẫn tuyệt đối của tệp I, trong khi các câu trả lời khác trong danh sách thực hiện công việc.
Bjørn Otto Vasbotten

202
readlink -f filename 

đưa ra con đường tuyệt đối đầy đủ. nhưng nếu tệp là một liên kết tượng trưng, ​​bạn sẽ nhận được tên được giải quyết cuối cùng.


8
Đẹp. Không hoạt động trên Biến thể BSD của readlink (tức là Mac). Tôi sử dụng gnucoreutils trên mac. Và do đó có thể sử dụng greadlink hoạt động với giải pháp trên.
sheki

12
Không đi trên Mac OS X.
Andrew Lazarus

1
@AndrewLazarus - Đối với Mac OS X, realpaththay vào đó hãy sử dụng
cz

nếu bạn cài đặt công cụ bash qua brew install coreutils, sau đó thực thi sẽ được cài đặt như/usr/local/opt/coreutils/libexec/gnubin/readlink
có hương thơm

121

Sử dụng này cho dirs ( /sau** cần thiết bash để giới hạn nó vào thư mục):

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

cái này cho các tập tin và thư mục ngay dưới thư mục hiện tại, có tên chứa một . :

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

cái này cho mọi thứ:

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

Lấy từ đây http://www.zsh.org/mla/users/2002/msg00033.html

Trong bash, **là đệ quy nếu bạn kích hoạt shopt -s globstar.


1
ls -d -1 $ PWD / ** / * không tái diễn. Ước gì tôi có thể lấy lại +1 của mình. Bạn có thể làm ** cho mỗi độ sâu bạn cần phải đi.
dùng606723

4
Toán tử ** là toán tử Globing đệ quy. Nếu bạn sử dụng lệnh trong shell hỗ trợ nó (chẳng hạn như zsh), nó sẽ hoạt động đúng.
zebediah49

ls -d1 "$ PWD /" nb*,.*} để bắt các tệp (dấu chấm) bị ẩn. Đối với tôi, phiên bản đệ quy trong câu trả lời đã không đưa ra đường dẫn tuyệt đối đến các tệp trong các thư mục con.
Zael

Tôi nghĩ rằng tôi sẽ phải sử dụng find ... Tôi nhận được -> bash: / bin / ls: Danh sách đối số quá dài
TelamonAegisthus

30

Bạn có thể dùng

find $PWD 

trong bash


3
Điều đó sẽ đưa ra đường dẫn của thư mục hiện tại, và tất cả các tệp và thư mục bên dưới nó. Đó có lẽ không phải là những gì mọi người đang tìm kiếm.
Hóa đơn

18
ls -d "$PWD/"*

Điều này chỉ trông trong thư mục hiện tại . Nó trích dẫn "$ PWD" trong trường hợp nó chứa khoảng trắng.


Đây vẫn là một câu trả lời rất hợp lệ, nhưng sẽ rất tốt nếu bao gồm thông tin rằng nó không hoạt động theo cách đệ quy (đó là những gì tôi đang tìm kiếm trên thực tế!)
bbbco

1
Đối với sử dụng đệ quy: tìm. -exec ls -ld $ PWD / {} \;
Học viên

10

Chỉ huy: ls -1 -d "$PWD/"*

Điều này sẽ đưa ra các đường dẫn tuyệt đối của tập tin như dưới đây.

[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

8

Đây $PWDlà một lựa chọn tốt của Matthew ở trên. Nếu bạn muốn tìm chỉ in các tệp thì bạn cũng có thể thêm tùy chọn -type f để chỉ tìm kiếm các tệp bình thường. Các tùy chọn khác là "d" chỉ cho các thư mục, v.v. Vì vậy, trong trường hợp của bạn, nó sẽ là (nếu tôi chỉ muốn tìm kiếm các tệp có .c ext):

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

hoặc nếu bạn muốn tất cả các tệp:

find $PWD -type f

Lưu ý: Bạn không thể tạo bí danh cho lệnh trên, vì $ PWD được tự động hoàn thành vào thư mục chính của bạn khi bí danh đang được đặt bởi bash.


Trên thực tế, -d không có nghĩa là chỉ các thư mục - nó có nghĩa là nó xử lý các thư mục như các tệp. Vì vậy, nếu bạn là -d / nhà, bạn sẽ quay lại "/ nhà", không phải là danh sách những gì trong / nhà.
Travis

@Travis: anh đang nói về lựa chọn tìm, không phải ls. Trong trường hợp của mình, "find / -type d" sẽ chỉ tìm thấy các thư mục - như ông nói.
oligofren

6

Nếu bạn cho lệnh find một đường dẫn tuyệt đối, nó sẽ nhổ kết quả ra với một đường dẫn tuyệt đối. Vì vậy, từ thư mục Ken nếu bạn định gõ:

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

(thay vì đường dẫn tương đối find . -name bar -print)

Bạn sẽ nhận được:

/home/ken/foo/bar

Do đó, nếu bạn muốn ls -lvà yêu cầu nó trả về đường dẫn tuyệt đối, bạn chỉ cần nói lệnh find để thực thi ls -lbất cứ thứ gì nó tìm thấy.

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

LƯU Ý: Có khoảng cách giữa {};

Bạn sẽ nhận được một cái gì đó như thế này:

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

Nếu bạn không chắc chắn vị trí của tệp, bạn luôn có thể thay đổi vị trí tìm kiếm. Miễn là đường dẫn tìm kiếm bắt đầu bằng "/", bạn sẽ nhận được đường dẫn tuyệt đối. Nếu bạn đang tìm kiếm một vị trí (như /) nơi bạn sẽ nhận được rất nhiều lỗi bị từ chối cấp phép, thì tôi khuyên bạn nên chuyển hướng lỗi tiêu chuẩn để bạn thực sự có thể thấy kết quả tìm thấy:

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

( 2>là cú pháp của shell Borne và Bash, nhưng sẽ không hoạt động với shell C. Nó cũng có thể hoạt động trong các shell khác, nhưng tôi chỉ biết chắc chắn rằng nó hoạt động trong Bourne và Bash).


Bạn có thể chuyển nhiều đối số cho cùng một lsquy trình với -exec ls -ld {} +. (Bạn có thể muốn -dkhông có lsdanh sách nội dung thư mục). Hoặc tốt hơn, sử dụng find-tích lshợp với find ... name bar -ls. Ngoài ra, bạn có cú pháp sai cho một đối số cho mỗi lệnh: bạn phải trích dẫn dấu chấm phẩy từ trình bao, vì vậy nó {} \;.
Peter Cordes

5

fd

Sử dụng fd(thay thế cho find), sử dụng cú pháp sau:

fd . foo -a

Trong trường hợp .là mô hình tìm kiếm và foolà thư mục gốc.

Ví dụ: để liệt kê tất cả các tệp theo etccách đệ quy, hãy chạy : fd . /etc -a.

-a, --absolute-path Hiển thị tuyệt đối thay vì đường dẫn tương đối


2

Chỉ là một thay thế cho

ls -d "$PWD/"* 

để xác định đó *là mở rộng vỏ, vì vậy

echo "$PWD/"*

sẽ làm tương tự (nhược điểm bạn không thể sử dụng -1để phân tách bằng các dòng mới, không phải khoảng trắng).


bạn có thể nói rõ hơn về điều này? mở rộng vỏ là gì? Làm thế nào để sử dụng -1để phân tách bởi các dòng?
Antonio Araujo

@Antonio Araujo, mở rộng shell là shell (ví dụ bash) sẽ thay thế * bằng danh sách các tệp - có thể đọc thêm trên trang bash man. -1 là tùy chọn lệnh ls, echo là lệnh khác, nó không có tùy chọn tương tự.
Marisha

1
lspwd() { for i in $@; do ls -d -1 $PWD/$i; done }

1

Đây là một ví dụ in ra một danh sách mà không có thêm một khoảng thời gian và điều đó cũng cho thấy cách tìm kiếm một tập tin khớp. Hi vọng điêu nay co ich:

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

1

Điều này làm việc cho tôi. Nhưng nó không liệt kê theo thứ tự bảng chữ cái.

find "$(pwd)" -maxdepth 1

Lệnh này liệt kê theo thứ tự abc cũng như liệt kê các tập tin ẩn.

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

1

stat

Đường dẫn tuyệt đối của một tệp duy nhất:

stat -c %n "$PWD"/foo/bar

1

Bạn có thể muốn thử điều này.

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

Bạn có thể nhận đường dẫn abs bằng forvòng lặp và echođơn giản là không có find.


0

Nếu bạn cần danh sách tất cả các tệp trong thư mục hiện tại cũng như thư mục con

find $PWD -type f

Nếu bạn cần danh sách tất cả các tệp chỉ trong thư mục hiện tại

find $PWD -maxdepth 1 -type f

0

Điều này sẽ đưa ra đường dẫn chính tắc (sẽ giải quyết các liên kết tượng trưng): realpath FILENAME

Nếu bạn muốn đường dẫn chính đến symlink, thì: realpath -s FILENAME


0

Hầu hết nếu không phải tất cả các phương thức được đề xuất đều dẫn đến các đường dẫn không thể được sử dụng trực tiếp trong một số lệnh đầu cuối khác nếu đường dẫn chứa khoảng trắng. Lý tưởng nhất là kết quả sẽ có dấu gạch chéo. Điều này làm việc cho tôi trên macOS:

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

-1

find / -print sẽ làm điều này


1
... thật không may, nó sẽ làm một cái gì đó khác (như hiển thị 'một số' tệp khác trừ khi được lọc)
DerMike

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.