Nếu bạn đang sử dụng Bash, bạn thậm chí không phải sử dụng grep
:
files="*.jpg"
regex="[0-9]+_([a-z]+)_[0-9a-z]*"
for f in $files # unquoted in order to allow the glob to expand
do
if [[ $f =~ $regex ]]
then
name="${BASH_REMATCH[1]}"
echo "${name}.jpg" # concatenate strings
name="${name}.jpg" # same thing stored in a variable
else
echo "$f doesn't match" >&2 # this could get noisy if there are a lot of non-matching files
fi
done
Tốt hơn là đặt regex trong một biến. Một số mẫu sẽ không hoạt động nếu được bao gồm theo nghĩa đen.
Điều này sử dụng =~
đó là toán tử khớp regex của Bash. Kết quả của trận đấu được lưu vào một mảng được gọi là $BASH_REMATCH
. Nhóm chụp đầu tiên được lưu trữ trong chỉ mục 1, nhóm thứ hai (nếu có) trong chỉ mục 2, v.v. Chỉ số 0 là khớp hoàn toàn.
Bạn nên lưu ý rằng không có neo, regex này (và sử dụng grep
) sẽ khớp với bất kỳ ví dụ nào sau đây và hơn thế nữa, có thể không phải là thứ bạn đang tìm kiếm:
123_abc_d4e5
xyz123_abc_d4e5
123_abc_d4e5.xyz
xyz123_abc_d4e5.xyz
Để loại bỏ các ví dụ thứ hai và thứ tư, hãy tạo regex của bạn như thế này:
^[0-9]+_([a-z]+)_[0-9a-z]*
trong đó nói rằng chuỗi phải bắt đầu bằng một hoặc nhiều chữ số. Các carat đại diện cho sự bắt đầu của chuỗi. Nếu bạn thêm ký hiệu đô la vào cuối regex, như thế này:
^[0-9]+_([a-z]+)_[0-9a-z]*$
sau đó, ví dụ thứ ba cũng sẽ bị loại vì dấu chấm không nằm trong số các ký tự trong biểu thức chính quy và ký hiệu đô la biểu thị phần cuối của chuỗi. Lưu ý rằng ví dụ thứ tư cũng thất bại trong trận đấu này.
Nếu bạn có GNU grep
(khoảng 2,5 trở lên, tôi nghĩ, khi \K
toán tử được thêm vào):
name=$(echo "$f" | grep -Po '(?i)[0-9]+_\K[a-z]+(?=_[0-9a-z]*)').jpg
Các \K
nhà điều hành (chiều dài thay đổi nhìn đằng sau) gây ra các mô hình trước để phù hợp, nhưng không bao gồm các trận đấu trong kết quả. Tương đương độ dài cố định là (?<=)
- mẫu sẽ được đưa vào trước dấu ngoặc đơn đóng. Bạn phải dùng\K
nếu quantifiers có thể phù hợp với chuỗi có độ dài khác nhau (ví dụ +
, *
, {2,4}
).
Các (?=)
trận đấu khai thác cố định hoặc các mẫu chiều dài thay đổi và được gọi là "nhìn về phía trước". Nó cũng không bao gồm chuỗi phù hợp trong kết quả.
Để làm cho khớp không phân biệt chữ hoa chữ thường, (?i)
toán tử được sử dụng. Nó ảnh hưởng đến các mô hình theo nó để vị trí của nó là đáng kể.
Regex có thể cần được điều chỉnh tùy thuộc vào việc có các ký tự khác trong tên tệp hay không. Bạn sẽ lưu ý rằng trong trường hợp này, tôi đưa ra một ví dụ về nối chuỗi cùng lúc với chuỗi con được bắt.