Điểm:7

BASH: Làm cách nào tôi có thể kết hợp hai (hoặc nhiều) thao tác chuỗi biến trong một bước?

lá cờ tr

Có thể kết hợp hai hoặc nhiều chức năng thao tác chuỗi của một biến trong BASH (hoặc bất kỳ lệnh Linux tiêu chuẩn nào khác)?

Hãy cùng nói nào ví dụ. tôi có biến $XDG_CURRENT_DESKTOP trong đó giữ chuỗi Ubuntu:Gnome.
Bây giờ, tôi có thể truy xuất chuỗi con thứ hai bằng cách ${XDG_CURRENT_DESKTOP##*:} â Gnome.
Tôi cũng có thể truy xuất chuỗi chữ thường thông qua ${XDG_CURRENT_DESKTOP,,} â Ubuntu:gnome.

Nhưng làm thế nào tôi có thể kết hợp cả hai chức năng thần lùn) Trong một â giản dị lệnh mà không sử dụng chuyển hướng đến sed, awk, tiếng kêu hoặc bất kỳ thứ nào khác trong số này â trọng lượng khá nặng lệnh và không có bước lưu trữ bộ đệm bổ sung? ví dụ.:

local mybuffer="${XDG_CURRENT_DESKTOP##*:}"
tiếng vang "${mybuffer,,}"

Tôi muốn tránh cấu trúc lệnh gọi hàm hoặc "tập lệnh phụ" như vậy để đạt được điều này và tôi đã thử bất kỳ kết hợp nào của cả hai được đề cập nhưng có vẻ như là vô ích.
Còn cách nào khác không?
Hay tôi cần nâng cấp bash? (sử dụng: GNU bash 4.3.11)
Hoặc bất kỳ vỏ nào khác có thể làm điều đó?

lá cờ hr
`zsh` có thể làm được, với cờ mở rộng tham số `L` cũ. `${(L)XDG_CURRENT_DESKTOP##*:}`
Jens avatar
lá cờ tr
@steeldriver: Ồ, tuyệt quá! _THAT_ chính xác là những gì tôi đang tìm kiếm! Đã đến lúc dành cho `zsh`. Cám ơn rất nhiều! :))
terdon avatar
lá cờ cn
@steeldriver cũng có thể đăng câu trả lời đó vì OP cũng đã yêu cầu các vỏ khác.
Jens avatar
lá cờ tr
@terdon: d'accord
Điểm:4
lá cờ cn

Bạn có thể làm điều này trong đánh đập nếu bạn dùng đọc để đọc hai biến:

$ tiếng vang "$XDG_CURRENT_DESKTOP"
Ubuntu:Gnome
$ IFS=':' đọc var1 var2 <<<"${XDG_CURRENT_DESKTOP@L}"
$ tiếng vang "$var2"
thần lùn

Các ${biến@L} cấu trúc trả về giá trị của biến $ chuyển thành chữ thường. Sau đó, NẾU = ':' đọc đặt dấu tách trường đầu vào thành : cho đọc lệnh, theo cách này, IFS chung không thay đổi sau khi lệnh thoát, và sau đó đọc var1 var2 sẽ tách đầu vào của nó trên : và lưu kết quả vào hai biến biến1var2. Lưu ý rằng nếu bạn có nhiều hơn một : trên cùng một dòng trong đầu vào, biến1 sẽ có mọi thứ lên đến đầu tiên :var2 mọi thứ khác. Cuối cùng, <<< là một "chuỗi ở đây", một cách đơn giản để chuyển một biến làm đầu vào cho một lệnh.

Jens avatar
lá cờ tr
Cách giải quyết tốt đẹp! Nhưng thật không may, cấu trúc này còn dài và có lẽ có nhiều quy trình nền _(â nguyên tắc KISS)_. Nhân tiện, với phiên bản bash này, tôi nghĩ rằng tôi có thể áp dụng kết hợp tương tự như đề xuất zsh từ @steeldriver ở trên. Dù sao, 1+ cho nguồn cảm hứng!
terdon avatar
lá cờ cn
@Jens hoàn toàn dài và khó sử dụng để viết. Zsh có xu hướng thanh lịch hơn với loại điều này. Nhưng nhiều quá trình nền? Tại sao? Đây là tất cả các công cụ dựng sẵn 100% bash, tôi không nghĩ sẽ có nhiều (bất kỳ?) Liên quan đến forking.
Jens avatar
lá cờ tr
Điểm tốt! Tôi chỉ đang cố gắng triển khai một cái gì đó giống như _"chỉ thị thống nhất/hằng số"_ mà thực sự không cần phải mã hóa nhiều _and_ xử lý nền.Trong khi đó, dù sao thì tôi cũng nhận ra rằng `zsh` có thể phản tác dụng do thực tế là nó dường như không được phân phối rộng rãi. Vì vậy, nó không có nhiều ý nghĩa.
terdon avatar
lá cờ cn
@Jens zsh đang ngày càng trở nên phổ biến và là trình bao mặc định trên một số hệ thống không phải Ubuntu (macOS theo như tôi biết, nhưng có thể là các hệ thống khác) nhưng vâng, bạn không thể cho rằng nó sẽ khả dụng. Nhưng sau đó bạn cũng không thể cho rằng bash có sẵn :). Để có tính di động thực sự, bạn cần sử dụng shell POSIX cơ bản như `sh` hoặc `dash`. Câu trả lời của tôi phụ thuộc vào bashism, cách di động sẽ là chuyển sang một công cụ di động bên ngoài như `sed` hoặc `perl`. Tuy nhiên, tất cả những điều này không có chủ đề ở đây, chúng tôi chỉ xử lý Ubuntu. Bạn có thể muốn xem [linux.se] để biết các câu hỏi về tính di động.
Jens avatar
lá cờ tr
sh, dash, bash, zsh, v.v. ⦠quá nhiều lựa chọn ⦠Tôi nghĩ rằng tôi đã mất dấu vết của chế độ xem toàn cục với chi tiết này ;oP Tôi phải thừa nhận rằng, tôi chưa xem xét vấn đề trình bao này. Có lẽ bây giờ tôi nên ở lại với `bash`. Từ quan điểm này, mã của bạn trông đẹp hơn nhiều khi tôi nghĩ về nó xD
Điểm:0
lá cờ ng

Đây là tập lệnh bash5 (không phải bash4):

phần 2() {
   cục bộ -n var=$1
   var=${var#*:}
}
lc() {
   cục bộ -n var=$1
   var=${var,,}
}
fred="ubuntu:gnome"
phần 2
lc fred
printf "%s\n" "$fred"

Đầu ra:

thần lùn

Chức năng phần 2lc sửa đổi biến có tên được truyền cho chúng mà không cần rẽ nhánh. Cuối cùng, biến ban đầu (fred) đã được sửa đổi. Tuy nhiên, bạn vẫn cần biến phụ.

Giải pháp thay thế, sẽ hoạt động trên bash4, giống như thế này:

part2() { printf "%s" "${1#*:}"; }
lc() { printf "%s" "${1,,}" ; }
fred="ubuntu:GNOME"
printf "%s\n" "$(lc "$(part2 "$fred")")"

cái này không sửa đổi bất kỳ biến nào (nó chỉ thao tác các giá trị), nhưng nó tạo ra các nhánh bổ sung.

Jens avatar
lá cờ tr
Trước hết: cảm ơn bạn đã nỗ lực. Kết quả là tốt. FYI: _all_ mã của bạn là Bash4 trong chứng thư ;-).Tôi thực sự đánh giá cao lập trình mô-đun, nhưng trong trường hợp này, tôi đã tìm kiếm một mã lệnh đơn lẻ nhiều hơn hoặc cách khác là một lớp lót. Xin lỗi, nhưng dù sao cũng cảm ơn bạn rất nhiều.

Đăng câu trả lời

Hầu hết mọi người không hiểu rằng việc đặt nhiều câu hỏi sẽ mở ra cơ hội học hỏi và cải thiện mối quan hệ giữa các cá nhân. Ví dụ, trong các nghiên cứu của Alison, mặc dù mọi người có thể nhớ chính xác có bao nhiêu câu hỏi đã được đặt ra trong các cuộc trò chuyện của họ, nhưng họ không trực giác nhận ra mối liên hệ giữa câu hỏi và sự yêu thích. Qua bốn nghiên cứu, trong đó những người tham gia tự tham gia vào các cuộc trò chuyện hoặc đọc bản ghi lại các cuộc trò chuyện của người khác, mọi người có xu hướng không nhận ra rằng việc đặt câu hỏi sẽ ảnh hưởng—hoặc đã ảnh hưởng—mức độ thân thiện giữa những người đối thoại.