Tôi muốn tìm tất cả các tệp theo độ dài của tên tệp.
Ví dụ: nếu tôi muốn tìm các tệp có độ dài 1, chẳng hạn như a.go
, b.go
.
Tôi đặt:
grep '.\{1\}' file
Dường như không hiệu quả. Tôi có thể sử dụng lệnh nào để tìm tệp theo độ dài tên tệp?
Tôi muốn tìm tất cả các tệp theo độ dài của tên tệp.
Ví dụ: nếu tôi muốn tìm các tệp có độ dài 1, chẳng hạn như a.go
, b.go
.
Tôi đặt:
grep '.\{1\}' file
Dường như không hiệu quả. Tôi có thể sử dụng lệnh nào để tìm tệp theo độ dài tên tệp?
Câu trả lời:
grep
tìm kiếm các mẫu trong nội dung của các tập tin Nếu bạn muốn xem tên của các tệp, bạn chỉ có thể sử dụng shell shell (nếu bạn chỉ muốn xem xét tên tệp trong thư mục hiện tại):
echo ?.go
(Nhân tiện, đây là cái vỏ đánh giá toàn cầu, không phải echo
lệnh.)
Nếu bạn muốn tìm trong các thư mục theo cách đệ quy, bắt đầu với thư mục hiện tại, công cụ để sử dụng là find
:
find . -name '?.go'
(Lưu ý rằng bạn phải trích dẫn mẫu để ngăn vỏ đánh giá nó là một quả địa cầu trước khi find
được gọi.)
Nếu bạn chỉ muốn tìm tên tệp, bạn có thể sử dụng lệnh sau:
find -exec basename '{}' ';' | egrep '^.{100,}$'
Điều đó sẽ chạy find
, kéo ra tên của tệp hoặc thư mục bằng cách sử dụng basename
và sau đó tìm bất kỳ tên tệp hoặc tên thư mục nào có ít nhất 100 ký tự. Nếu bạn muốn tìm một tên tệp có độ dài chính xác, hãy sử dụng {100}
thay vì {100,}
.
Nếu bạn muốn tìm tên tệp bao gồm đường dẫn, hãy làm điều này:
find | egrep '/[^/]{100,}$'
Điều này sẽ trả lại tên tệp bao gồm đường dẫn tương đối đến nơi bạn đã chạy lệnh find.
Trước hết, grep
tìm kiếm thông qua nội dung của tập tin, nó sẽ không tìm kiếm tên tập tin. Cho rằng bạn muốn find
. Nó không có tùy chọn để đặt độ dài tên tệp nhưng bạn có thể phân tích cú pháp đầu ra của nó để có được những gì bạn muốn. Dưới đây là một số ví dụ mà tôi chạy trong một thư mục chứa các tệp sau:
$ tree
.
├── a
├── ab
├── abc
├── abcd
└── dir
├── a
├── ab
├── abc
└── abcd
Tìm kiếm các tập tin trong thư mục này trả về:
$ find . -type f | sort
./a
./ab
./abc
./abcd
./dir/a
./dir/ab
./dir/abc
./dir/abcd
Vì vậy, để tìm các tệp có độ dài X, chúng ta sẽ cần xóa đường dẫn và chỉ khớp các ký tự sau cùng /
:
$ find . -type f | grep -P '/.{3}$'
Các sed
lệnh chỉ loại bỏ ./
. Các -P
cờ kích hoạt Perl Regular Expressions Tương thích đó là cần thiết cho {n}
đó là một điều PCRE và $
có nghĩa là "phù hợp với sự kết thúc của chuỗi".
Bạn cũng có thể chỉ cần làm điều này:
find . -type f | grep -P '/...$'
Điều đó tốt cho những con số nhỏ gõ 15 chấm để khớp với tên tệp có độ dài 15 không hiệu quả lắm.
Cuối cùng, nếu bạn muốn bỏ qua tiện ích mở rộng và chỉ khớp với tên của tệp, hãy thực hiện việc này (như @slm đề xuất):
find . -type f | grep -P '/.{1}\.'
Tuy nhiên, điều này cũng sẽ tìm thấy các tập tin như a.bo.go
. Điều này tốt hơn nếu tên tệp của bạn có thể chứa nhiều hơn một .
:
find . -type f | grep -P '/.{1}\.[^.]+$'
LƯU Ý: Giải pháp ở trên giả định rằng bạn có tên tệp tương đối lành mạnh không chứa ký tự dòng mới, v.v ... Nó cũng sẽ được tính không bỏ qua khoảng trắng trong tên tệp khi tính toán độ dài có thể không phải là thứ bạn muốn. Nếu một trong hai vấn đề này, hãy cho tôi biết và tôi sẽ cập nhật câu trả lời của mình.
Bạn không chỉ định nhưng nếu các tệp nằm trong cấu trúc thư mục, bạn có thể sử dụng find
để định vị các tệp có độ dài 1, với sự trợ giúp của grep
:
$ find . -type f | grep -P '/.{1}\.'
$ find . -type f | grep -P '/.{1}\.' | head -10
./util-linux-2.19/include/c.h
./88366/a.bash
./89186/a.bash
./89563/b.txt
./89563/a.txt
./89563/c.txt
./89563/d.txt
./91734/2.c
./91734/4.c
./91734/1.c
ggrep
: heystephenwood.com/2013/09/install-gnu-grep-on-mac-osx.html . Cũng nhận ra rằng Q này không được gắn thẻ là OSX nên việc sử dụng grep
là apt.
Tôi sẽ sử dụng một cái gì đó như thế này.
find . -type f -name "?.go"
Vì vậy, nếu bạn đặt hai "?" sau đó bạn đang tìm kiếm tên tệp có hai ký tự và phần mở rộng.
Khi bạn muốn sử dụng lệnh ex thường xuyên trong lệnh find, bạn nên sử dụng ""
như:
find /var/log -iname "*.err"
cho trường hợp sử dụng:
find yourpath -type f -a -name "?.go"
Bạn nên thay thế đường dẫn thực sự của mình bằng yourpath, -a
có And
-type f
nghĩa là bạn chỉ tìm kiếm các tệp thông thường.
?
trong truy vấn của bạn có nghĩa là một charachter như DOS nếu bạn nhớ lại.
ls ?.*
sẽ cho bạn kết quả mong muốn.
a.go
là tên tệp có độ dài 4.a
là tên tệp có độ dài 1. Đây là Unix, không phải DOS trong đó tên và phần mở rộng là riêng biệt và ẩn.
luôn là một phần của tên tệp.