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}
zshvà 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
substrkhô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.
substrban đầ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 -c2không phải là POSIX vì đầu ra của printfkhông phải là văn bản trừ khi $myvarkế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 cutcắt từng dòng đầu vào của nó.
awkta 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 -c2là 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 ý)?
cutkhông được chỉ định nếu đầu vào không phải là văn bản (mặc dù cutviệ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 abckhô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 -c2có một hành vi được chỉ định bởi POSIX (bắt buộc phải xuất b<newline>)
Với zshhoặ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.