Câu trả lời:
Trong bash với "Mở rộng tham số" $ {tham số: offset: length}
$ var=abcdef
$ echo ${var:0:1}
a
$ echo ${var:3:1}
d
Chỉnh sửa: Không mở rộng tham số (không thanh lịch lắm, nhưng đó là điều đến với tôi trước)
$ charpos() { pos=$1;shift; echo "$@"|sed 's/^.\{'$pos'\}\(.\).*$/\1/';}
$ charpos 8 what ever here
r
echo ${var: -2:1}
zsh
và mksh
.
Thay thế cho việc mở rộng tham số là expr substr
substr STRING POS LENGTH
substring of STRING, POS counted from 1
Ví dụ:
$ expr substr hello 2 1
e
substr
không được bao gồm trong expr từ FreeBSD, NetBSD hoặc OS X. Đây không phải là một giải pháp di động.
substr
ban đầu không phải là phần mở rộng GNU. Việc triển khai ban đầu expr
đến từ PWB Unix vào cuối những năm 70 và đã có substr
(nhưng không :
).
cut -c
Nếu biến không chứa dòng mới, bạn có thể làm:
myvar='abc'
printf '%s\n' "$myvar" | cut -c2
đầu ra:
b
awk substr
là một thay thế POSIX khác hoạt động ngay cả khi biến có dòng mới:
myvar="$(printf 'a\nb\n')" # note that the last newline is stripped by
# the command substitution
awk -- 'BEGIN {print substr (ARGV[1], 3, 1)}' "$myvar"
đầu ra:
b
printf '%s\n'
là để tránh các vấn đề với các ký tự thoát: /programming//a/40423558/895245 ví dụ:
myvar='\n'
printf '%s\n' "$myvar" | cut -c1
đầu ra \
như mong đợi.
Xem thêm: /programming/1405611/extracting-first-two-char character-of-a-String-shell-scripting
Đã thử nghiệm trong Ubuntu 19.04.
printf '%s' "$myvar" | cut -c2
không phải là POSIX vì đầu ra của printf
không phải là văn bản trừ khi $myvar
kết thúc bằng ký tự dòng mới. Mặt khác, nó giả sử biến không chứa các ký tự dòng mới khi cut
cắt từng dòng đầu vào của nó.
awk
ta sẽ hiệu quả và đáng tin cậy hơn vớiawk -- 'BEGIN {print substr (ARGV[1], 2, 1)}' "$myvar"
cut
, điều đó không hoạt động đối với các ký tự nhiều byte (tương tự với mawk hoặc busybox awk)
printf 'abc '| cut -c2
là sai vì không \n
(điều này tôi không biết), hoặc lệnh sẽ thất bại nếu myvar có dòng mới (điều này tôi đồng ý)?
cut
không được chỉ định nếu đầu vào không phải là văn bản (mặc dù cut
việc triển khai là bắt buộc để xử lý các dòng hoặc độ dài tùy ý). Đầu ra của printf abc
không phải là văn bản vì nó không kết thúc bằng một ký tự dòng mới. Trên thực tế phụ thuộc vào việc thực hiện, nếu bạn ống đó để cut -c2
, bạn nhận được một trong hai b
, b<newline>
hoặc không có gì cả. Bạn cần printf 'abc\n' | cut -c2
có một hành vi được chỉ định bởi POSIX (bắt buộc phải xuất b<newline>
)
Với zsh
hoặc yash
, bạn sẽ sử dụng:
$ text='€$*₭£'
$ printf '%s\n' "${text[3]}"
*
(trong zsh
, bạn có thể rút ngắn nó xuống printf '%s\n' $text[3]
).
Bạn có thể sử dụng lệnh cắt. Để có được tư thế thứ 3:
echo "SAMPLETEXT" | cut -c3
Kiểm tra liên kết này http://www.folkstalk.com/2012/02/cut-command-in-unix-linux-examples.html
( Các trường hợp nâng cao ) Tuy nhiên, sửa đổi IFS cũng là một điều tốt, đặc biệt là khi đầu vào của bạn có thể có khoảng trắng. Trong trường hợp đó, sử dụng một trong những dưới đây
saveifs=$IFS
IFS=$(echo -en "\n\b")
echo "SAMPLETEXT" | cut -c3
IFS=$saveifs
IFS
để chơi trong mã mà bạn đã đăng.