Trích xuất từ ​​thứ hai từ một biến chuỗi


11

Tôi có một chuỗi "rtcpOnNbActive true"được lưu trữ trong một biến x. Tôi muốn trích xuất "true" dưới dạng chuỗi con và lưu trữ trong một biến. Tôi có thể làm cái này như thế nào?


Sẽ luôn có một khoảng trắng xngay trước chuỗi con bạn muốn trích xuất chứ?
PM 2Ring

Câu trả lời:


21

Hãy thử cách này:

y=$(echo $x | awk '{print $2}')
echo $y
  • echo $xhiển thị giá trị của x.
  • awk '{print $2}'in trường thứ hai của hiển thị trước đó x.
  • $(... )Giữ đầu ra và gán nó cho y.

3
echo $xkhông hiển thị giá trị củax . printf '%s\n' "$x"sẽ là
Stéphane Chazelas

2
awk '{print $2}'in trường thứ hai của mỗi dòng được hiển thị trước đó x.
Stéphane Chazelas

9

Giả sử rằng có ít nhất một khoảng trắng trước chuỗi con bạn muốn trích xuất (và chuỗi con đó không chứa bất kỳ khoảng trắng nào), bạn có thể thực hiện việc này bằng cách mở rộng tham số đơn giản:

x="rtcpOnNbActive     true"
y="${x##* }"
echo "[$y]"

đầu ra

[true]

3
echokhông thể mang theo cho bất kỳ thứ gì ngoài chuỗi ký tự không bắt đầu -và không chứa bất kỳ chuỗi thoát nào. Hành vi của nó thay đổi ngay cả đối với nội dung bash, tùy thuộc vào cách nó được biên dịch và liệu có XPG_ECHOđược đặt hay không. Giả sử chuỗi không chứa chuỗi thoát, điều này sẽ ổn, nhưng printf '[%s]\n' "$y"vẫn tốt hơn.
nyuszika7h

1
@ nyuszika7h: Điểm hay, và sau khi đọc Stéphane Chazelas nói những điều tương tự ở đây và trong những câu hỏi gần đây khác, tôi thực sự nên bỏ thói quen sử dụng echođể hiển thị giá trị của các biến, ngay cả trong các ví dụ "vứt đi" như thế này.
PM 2Ring

4

bạn có thể sử dụng awk:

echo "rtcpOnNbActive         true" | awk '{print $NF}'
true

NF số trường trong hồ sơ hiện tại

sử dụng sed:

echo "rtcpOnNbActive         true" | sed 's/.* //g'
true

sử dụng biểu thức chuỗi:

 a="rtcpOnNbActive         true"
 echo ${a##* }
 true

sử dụng grep:

 echo "rtcpOnNbActive         true" | grep -Eo "[a-z]+$"
 true

-o chỉ đưa ra kết hợp chính xác, [a-z]+sẽ khớp chữ cái từ az và $có nghĩa là ở cuối


2
Đừng đăng nội dung câu trả lời khác cho bạn trong cùng một câu hỏi, xin vui lòng.
αғsнιη

1
Những gì người khác trả lời ????
Hackaholic

anh ta có thể lưu nó trong biến nó không phải là một vấn đề lớn ở đây
Hackaholic

echokhông thể mang theo cho bất kỳ thứ gì ngoài chuỗi ký tự không bắt đầu -và không chứa bất kỳ chuỗi thoát nào. Hành vi của nó thay đổi ngay cả đối với nội dung bash, tùy thuộc vào cách nó được biên dịch và liệu có XPG_ECHOđược đặt hay không. Ngoài ra, bạn phải luôn luôn nhân đôi mở rộng biến số và thay thế lệnh (với một số ngoại lệ nhất định, trong trường hợp không cần thiết nhưng nó cũng không gây hại gì). Với một chuỗi như OP, điều này sẽ ổn, nhưng nếu bạn muốn chắc chắn printf '%s\n' "${a##* }"sẽ tốt hơn.
nyuszika7h

3

Có thể sử dụng mảng bash cho điều đó, ví dụ:

arr="(first second third)"
echo ${arr[1]}

2

Bạn có thể sử dụng tích readhợp sẵn

read -r _ y <<<"$x"
printf "%s\n" "$y"
true

Tại sao liên quan read? Nó không phải readlà sự phân chia - nó là $IFS. Vì một số lý do, rất nhiều người cho rằng việc chia tách $IFS chỉ khi readcó liên quan. Bạn chỉ có thể làm: set -f; IFS=' '; printf %.0s%s $xhoặc bất cứ điều gì. Trong mọi trường hợp - bạn cần chỉ định $IFSgiá trị của đây tại đây.
mikeerv

@mikeerv, nó readđang thực hiện phân tách bằng cách sử dụng IFS, kiểm tra tài liệu . Ưu điểm chính của việc sử dụng read là nó đặt các biến (là một yêu cầu OP) và được cho rằng nó có thể phân tách các chuỗi và điền vào một mảng, rất tốt để trích xuất các trường tùy ý từ một chuỗi. Ngoài ra, tôi giả sử mặc định IFSở đây, nhưng đủ dễ để đặt nếu cần, IFS=$' \n\t' read -r _ y <<<"$x"sẽ thực hiện thủ thuật
iruvar 14/12/14

không, nó không phải readphân công, $IFSchia nhỏ. nếu bạn muốn điền vào một mảng, hãy sử dụng set- bạn không cần chuỗi vô nghĩa nhân tạo ở đây trong trường hợp đó. unset IFSđược mặc định hành vi $ IFS.
mikeerv

@mikeerv, bạn ra khỏi danh sách thiệp Giáng sinh của tôi.
iruvar

bah humbug. xmas là cho kẻ hút.
mikeerv
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.