Bạn có thể quan tâm đến những người nghèo của người nghèo find
:
shopt -s globstar
shopt -s
s ets tùy chọn shell được đặt tên (s). Các globstar
tùy chọn được định nghĩa như sau trong bash (1) :
Nếu được đặt, mẫu **
được sử dụng trong ngữ cảnh mở rộng tên tệp / tên đường dẫn sẽ khớp với tệp [sic] và không hoặc nhiều thư mục và thư mục con. Nếu mẫu được theo sau bởi một /
, chỉ các thư mục và thư mục con phù hợp.
Vì vậy, sau khi bạn thực hiện xong shopt -s globstar
, bất kỳ lệnh nào sau đây:
ls -d1 - source / ** # Ký tự sau 'd' là chữ số.
ls -d - nguồn / ** | cat # tức là nó sẽ ghi nó vào một ống dẫn tới bất kỳ lệnh nào.
nguồn in "% s \ n" / **
sẽ tạo ra đầu ra:
source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png
Thật không may, điều này bao gồm cả tên thư mục. Nó có thể giúp bạn một chút để biết rằng
printf "%s\n" source/**/
sẽ tạo ra đầu ra:
source/
source/fonts
source/images
tức là chỉ có tên thư mục Bạn có thể chuyển hướng đầu ra của một trong những tập đầu tiên của lệnh vào một tập tin, chuyển hướng đầu ra của trên vào một tập tin thứ hai, và sau đó sử dụng comm
, diff
hoặc một cái gì đó tương tự, trừ các tập tin thứ hai từ đầu tiên, chỉ để lại đơn giản tập tin (không phải thư mục). Nhưng đừng làm vậy.
Một cách tiếp cận khác (không tốt hơn nhiều ) là
ls -d --file-type -- source/** | grep -v '/$'
Các --file-type
tùy chọn cho ls
hiển thị một /
vào cuối mỗi tên thư mục (và các nhân vật khác ở tận cùng khác (đặc biệt) các loại tập tin), như sau:
nguồn // # Đã thêm một
nguồn / phông chữ / # Đã thêm một nguồn
nguồn / phông chữ / fontello
nguồn / hình ảnh / # Đã thêm một
nguồn / hình ảnh / bg1.png
nguồn / hình ảnh / eng.png
nguồn / hình ảnh / fra.png
và sau đó grep -v '/$'
loại bỏ các dòng kết thúc bằng /
; tức là tên thư mục Thật không may, --file-type
tùy chọn không được chỉ định bởi POSIX . Nếu phiên bản của ls
bạn không hỗ trợ nó, hãy sử dụng -F
. Điều đó giống như --file-type
ngoại trừ nó cũng hiển thị *
ở cuối tên của các tệp thực thi, điều mà một số người thấy khó chịu. Bạn có thể loại bỏ chúng bằng sed
:
ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'
Nếu bạn muốn làm một cái gì đó với tất cả các tệp (và chỉ các tệp), bạn có thể làm
cho f trong nguồn / **
làm
nếu [-f "$ f"]
sau đó
Chèn các lệnh sẽ được áp dụng cho các tập tin đơn giản ở đây.
fi
làm xong
Ghi chú:
- Khi
ls
xuất ra một thiết bị đầu cuối và nó không ở chế độ -l
( l ong), nó sẽ ghi nhiều tên trên mỗi dòng (trừ khi các tên rất dài). Bạn có thể buộc nó viết một tên trên mỗi dòng bằng cách chỉ định -1
(một) hoặc bằng cách chuyển hướng đầu ra sang tệp hoặc đường ống.
- Bạn có lẽ không thực sự cần
--
trong ls
lệnh kể từ khi bạn đang liệt kê một thư mục có nội dung mà bạn đã tạo. Bạn nên sử dụng nó khi liệt kê *
trong một thư mục không xác định, vì bảo vệ chống lại tên tệp bắt đầu bằng -
.
- Đừng cố phân tích đầu ra từ
ls
.
- Các
globstar
tùy chọn vỏ dường như không được định nghĩa bởi POSIX. (Trên thực tế, tôi không chắc POSIX nhận ra bất kỳ tùy chọn shell nào .) Mặc dù có vẻ như là một bash
ism, hãy cẩn thận - nó có thể không có trong tất cả các phiên bản bash.
Nếu fonts
hoặc images
có các thư mục con, **
sẽ liệt kê tất cả, theo cách đệ quy, tất cả các đường dẫn xuống. Một cách (hơi khó hiểu và không đáng tin cậy) để giới hạn độ sâu là
ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
trong đó loại bỏ các dòng chứa ba hoặc nhiều /
ký tự.
find
sai; đặc biệt, nếu bạn đang chạyfor file in $(find ...)
, bạn đã nhấn một trong số chúng).