Câu trả lời:
Ba ký tự cuối cùng của string
:
${string: -3}
hoặc là
${string:(-3)}
(nhớ khoảng trống giữa :
và -3
ở dạng đầu tiên).
Vui lòng tham khảo Mở rộng Thông số Vỏ trong sách hướng dẫn tham khảo :
${parameter:offset}
${parameter:offset:length}
Expands to up to length characters of parameter starting at the character
specified by offset. If length is omitted, expands to the substring of parameter
starting at the character specified by offset. length and offset are arithmetic
expressions (see Shell Arithmetic). This is referred to as Substring Expansion.
If offset evaluates to a number less than zero, the value is used as an offset
from the end of the value of parameter. If length evaluates to a number less than
zero, and parameter is not ‘@’ and not an indexed or associative array, it is
interpreted as an offset from the end of the value of parameter rather than a
number of characters, and the expansion is the characters between the two
offsets. If parameter is ‘@’, the result is length positional parameters
beginning at offset. If parameter is an indexed array name subscripted by ‘@’ or
‘*’, the result is the length members of the array beginning with
${parameter[offset]}. A negative offset is taken relative to one greater than the
maximum index of the specified array. Substring expansion applied to an
associative array produces undefined results.
Note that a negative offset must be separated from the colon by at least one
space to avoid being confused with the ‘:-’ expansion. Substring indexing is
zero-based unless the positional parameters are used, in which case the indexing
starts at 1 by default. If offset is 0, and the positional parameters are used,
$@ is prefixed to the list.
Vì câu trả lời này nhận được một vài lượt xem thường xuyên, hãy để tôi thêm một khả năng để giải quyết bình luận của John Rix ; như anh ấy đề cập, nếu chuỗi của bạn có độ dài nhỏ hơn 3, ${string: -3}
sẽ mở rộng thành chuỗi trống. Trong trường hợp này, nếu bạn muốn mở rộng string
, bạn có thể sử dụng:
${string:${#string}<3?0:-3}
Điều này sử dụng ?:
toán tử if bậc ba, có thể được sử dụng trong Shell Arithmetic ; vì như đã được tài liệu, offset là một biểu thức số học, điều này là hợp lệ.
deppfx@localhost:/tmp$ echo ${$(hostname): -3}
-bash: ${$(hostname): -3}: bad substitution
temp=$(hostname); echo "${temp: -3}"
. Bash cũng có HOSTNAME
biến (có thể khác hoặc không với đầu ra của hostname
). Nếu bạn muốn sử dụng nó, chỉ cần làm echo "${HOSTNAME: -3}"
.
some func | echo ${string: -3}
- làm cách nào để gán kết quả đầu ra some func
cho string
?
string=$(some func)
và sau đó echo "${string: -3}"
.
Một giải pháp khác là sử dụng grep -o
với một chút ma thuật regex để có ba ký tự theo sau là cuối dòng:
$ foo=1234567890
$ echo $foo | grep -o ...$
890
Để làm cho nó tùy chọn lấy từ 1 đến 3 ký tự cuối cùng, trong trường hợp chuỗi có ít hơn 3 ký tự, bạn có thể sử dụng egrep
với regex này:
$ echo a | egrep -o '.{1,3}$'
a
$ echo ab | egrep -o '.{1,3}$'
ab
$ echo abc | egrep -o '.{1,3}$'
abc
$ echo abcd | egrep -o '.{1,3}$'
bcd
Bạn cũng có thể sử dụng các phạm vi khác nhau, chẳng hạn như 5,10
để lấy năm đến mười ký tự cuối cùng.
Để khái quát câu hỏi và câu trả lời của gniourf_gniourf (vì đây là những gì tôi đang tìm kiếm), nếu bạn muốn cắt một loạt các ký tự từ thứ 7 từ cuối đến thứ 3 từ cuối, bạn có thể sử dụng cú pháp này:
${string: -7:4}
Trong đó 4 là độ dài của khóa học (7-3).
Ngoài ra, trong khi giải pháp của gniourf_gniourf rõ ràng là tốt nhất và gọn gàng nhất, tôi chỉ muốn thêm một giải pháp thay thế bằng cách sử dụng cut :
echo $string | cut -c $((${#string}-2))-$((${#string}))
Điều này dễ đọc hơn nếu bạn thực hiện nó thành hai dòng bằng cách xác định độ dài $ {# string} là một biến riêng biệt.
cut
cách tiếp cận này để tính điểm bắt đầu / dừng trước và sau đó chỉ sử dụng các biến này trong phần mở rộng tham số (cũng đáng nói rằng cut
và hiệu số bash bắt đầu từ 1 và 0, vì vậy điều này sẽ cần để được tính vào các tính toán, mà tôi không làm gì ở đây): start=$((${#string}-3)); stop=$((${#string}));
và sau đó echo ${string: $start : $stop}
vsecho $string | cut -c "$start"-"$stop"