Trong một tập hợp các thư mục, làm cách nào để tìm một tệp có tên bao gồm một chuỗi đã cho, chẳng hạn như "abcde"?
Trong một tập hợp các thư mục, làm cách nào để tìm một tệp có tên bao gồm một chuỗi đã cho, chẳng hạn như "abcde"?
Câu trả lời:
find
sẽ xem qua cấu trúc thư mục và trả về kết quả dựa trên toàn cầu :
find /your/dir -name "*abcde*"
Thêm công -type f
tắc sẽ tinh chỉnh tiêu chí tìm kiếm của bạn để chỉ trả lại tệp.
find /your/dir -type f -name "*abcde*"
Bạn cũng có thể bao gồm các công tắc khác muốn -maxdepth 2
giới hạn tìm kiếm ở 2 cấp độ thư mục dưới mức được chỉ định.
Bằng cách này, bạn có thể xây dựng một lệnh tìm kiếm phong phú, được nhắm mục tiêu cao sẽ nhanh chóng trả về chính xác những gì bạn cần.
man find
có rất nhiều chi tiết, bao gồm các hành động như -exec
chạy một lệnh trên các tệp được trả về find
và các tùy chọn để sử dụng các biểu thức thông thường.
Sử dụng tìm :
find path-to-search -name '*abcde*'
Nếu locate
phù hợp với bạn (nó nhanh, nhưng chỉ tốt như lần chạy gần đây nhất sudo updatedb
). Bạn có thể chạy locate
bằng tiện ích regex tích hợp sẵn của nó ...
Đây là một kịch bản điều khiển tham số để làm những gì bạn muốn. Gọi nó với $ 1 là "abcde" mà bạn đang tìm kiếm và với các tham số tiếp theo là các thư mục:
#!/bin/bash
a=("$@"); r=''
for ((i=1;i<${#a[@]};i++)); do r="$r|${a[i]}"; done
locate --regex "(${r:1}).*/[^/]*${a[0]}[^/]*$"
Một cuộc gọi ví dụ trông như thế này:
$ ./script_name 'z' "$HOME/bin/perl" "$HOME/type/stuff"
Theo đề xuất của jasonwryan , đây là phiên bản nhận xét của kịch bản.
Hãy nhớ rằng locate
luôn luôn xuất ra các đường dẫn đủ điều kiện.
#!/bin/bash
# Note: Do not use a trailing / for directory names
#
# Any of the args can be an extended regex pattern.
#
# Create an array `a` which contains "$1", "$2", "$3", etc... (ie. "$@")
# writing the $-args to an array like this (using quotes) solves
# any possible problem with embedded whitespace
a=("$@")
#
# Set up an empty string which is to be built into a regex pattern
# of all directroy names (or an appropriate regex pattern)
r=''
#
# Each regex pattern is to be an extended regex
# Each regex pattern is concatenated to the preceding one
# with the extended-regex 'or' operator |
#
# Step through the array, starting at index 1 (ie, $2),
# and build the 'regex-pattern' for the directories
for ((i=1;i<${#a[@]};i++)); do r="$r|${a[i]}"; done
#
# Run 'locate' with
# |the target file pattern $1 |
# |zero-to-| |preceded and followed by |
# |-many | |zero-to-many non-slash chars|
# |anything| | |‾‾‾‾‾‾‾‾‾‾‾‾
# ‾‾‾‾‾‾‾|| | |
locate --regex "(${r:1}).*/[^/]*${a[0]}[^/]*$"
# ________| | |
# |directory-regex| last
# | in brackets ()| slash
# |stripped of its|
# |leading "|" |
#
locate abcde | egrep "(dirA|dirB|dirC)"
cho tập hợp các thư mục dirA, dirB, dirC.
Hoặc 3 lệnh tìm.
-type f
vàofind
để bạn chỉ nhận được kết quả là các tệp.find /your/dir -type f -name "*abcde*"