Score:7

BASH: ฉันจะรวมการจัดการสตริงตัวแปรสองตัว (หรือมากกว่า) ในขั้นตอนเดียวได้อย่างไร

ธง tr

เป็นไปได้หรือไม่ที่จะรวมฟังก์ชันการจัดการสตริงสองฟังก์ชันขึ้นไปของตัวแปรใน BASH (หรือคำสั่ง Linux มาตรฐานอื่น ๆ )?

สมมติว่า เช่น. ฉันมีตัวแปร $XDG_CURRENT_DESKTOP ซึ่งเก็บสาย อูบุนตู:GNOME.
ตอนนี้ฉันสามารถดึงสตริงย่อยที่สองได้โดย ${XDG_CURRENT_DESKTOP##*:} â จีโนม.
ฉันยังสามารถดึงสตริงตัวพิมพ์เล็กผ่าน ${XDG_CURRENT_DESKTOP,,} â อูบุนตู: คำพังเพย.

แต่ฉันจะรวมทั้งสองฟังก์ชันได้อย่างไร คำพังเพย) ใน หนึ่ง â เรียบง่าย â คำสั่งโดยไม่ต้องใช้การเปลี่ยนเส้นทางไปที่ เสด, อึดอัด, เกรป หรืออื่นๆ เหล่านี้ â มีน้ำหนักค่อนข้างมาก â คำสั่งและไม่มีขั้นตอนการจัดเก็บบัฟเฟอร์เพิ่มเติม? เช่น.:

mybuffer ท้องถิ่น = "${XDG_CURRENT_DESKTOP##*:}"
เสียงสะท้อน "${mybuffer,,}"

ฉันต้องการหลีกเลี่ยง "sub-script" หรือโครงสร้างการเรียกใช้ฟังก์ชันเพื่อให้บรรลุเป้าหมายนี้ และฉันได้ลองใช้ทั้งสองอย่างรวมกันแล้ว แต่ดูเหมือนว่าจะไร้ประโยชน์
มีวิธีอื่น ๆ ?
หรือฉันต้องอัพเกรด bash? (ใช้: GNU ทุบตี 4.3.11)
หรือเปลือกอื่นสามารถทำได้?

hr flag
`zsh` ทำได้โดยใช้แฟล็กขยายพารามิเตอร์ `L` เช่น `${(L)XDG_CURRENT_DESKTOP##*:}`
Jens avatar
tr flag
@steeldriver: โอ้ เยี่ยม! _THAT_ คือสิ่งที่ฉันกำลังมองหา! เวลาสำหรับ `zsh` ขอบคุณมาก ๆ! :))
terdon avatar
cn flag
@steeldriver อาจโพสต์ว่าเป็นคำตอบเนื่องจาก OP ยังขอเชลล์อื่นด้วย
Jens avatar
tr flag
@terdon: d'แอคคอร์ด
Score:4
ธง cn

คุณสามารถทำได้ใน ทุบตี ถ้าคุณใช้ อ่าน เพื่ออ่านสองตัวแปร:

$ echo "$XDG_CURRENT_DESKTOP"
อูบุนตู:GNOME
$ IFS=':' อ่าน var1 var2 <<<"${XDG_CURRENT_DESKTOP@L}"
$เสียงสะท้อน "$var2"
คำพังเพย

เดอะ ${variable@L} สร้างส่งคืนค่าของ ตัวแปร $ แปลงเป็นตัวพิมพ์เล็ก แล้ว, IFS=':' อ่าน ตั้งค่าตัวคั่นฟิลด์อินพุตเป็น : สำหรับ อ่าน คำสั่ง ด้วยวิธีนี้ IFS ส่วนกลางจะไม่เปลี่ยนแปลงหลังจากออกคำสั่ง จากนั้น อ่าน var1 var2 จะแยกอินพุตบน : และบันทึกผลลัพธ์ในตัวแปรทั้งสอง var1 และ var2. โปรดทราบว่าหากคุณมีมากกว่าหนึ่ง : ในบรรทัดเดียวกันในอินพุต var1 จะมีครบทุกอย่างเป็นอย่างแรก : และ var2 อย่างอื่น. ในที่สุด, <<< เป็น "here string" วิธีง่ายๆ ในการส่งตัวแปรเป็นอินพุตไปยังคำสั่ง

Jens avatar
tr flag
วิธีแก้ปัญหาที่ดี! แต่น่าเสียดายที่โครงสร้างนี้ใช้เวลานานและน่าจะมีกระบวนการเบื้องหลังมากมาย _(หลักการ KISS)_ BTW ด้วยเวอร์ชันทุบตีนี้ ฉันคิดว่าฉันสามารถใช้ชุดค่าผสมที่คล้ายกับข้อเสนอ zsh จาก @steeldriver ด้านบนได้ อย่างไรก็ตาม 1+ สำหรับแรงบันดาลใจ!
terdon avatar
cn flag
@Jens มันยาวและเทอะทะที่จะเขียนอย่างแน่นอน Zsh มีแนวโน้มที่จะดูสง่างามมากขึ้นด้วยสิ่งนี้ แต่กระบวนการเบื้องหลังมากมาย? ทำไม นี่คือเครื่องมือ bash ในตัวทั้งหมด 100% ฉันไม่คิดว่าจะมีการ forking มากนัก (มี?)
Jens avatar
tr flag
จุดดี! ฉันแค่พยายามใช้บางอย่างเช่น _"uniform directive/constant"_ ซึ่งไม่ควรใช้การประมวลผลเบื้องหลังการเข้ารหัส _and_ มากนักในขณะเดียวกันฉันก็มาถึงจุดที่ `zsh` อาจต่อต้านได้เนื่องจากความจริงที่ว่ามันดูเหมือนจะไม่กระจายอย่างกว้างขวาง ดังนั้นจึงไม่สมเหตุสมผลมากนัก
terdon avatar
cn flag
@Jens zsh กำลังเป็นที่นิยมมากขึ้นเรื่อย ๆ และเป็นเชลล์เริ่มต้นในระบบที่ไม่ใช่ Ubuntu บางระบบ (เท่าที่ฉันรู้ macOS แต่อาจจะอื่น ๆ ) แต่ใช่คุณไม่สามารถสันนิษฐานได้ว่ามันจะพร้อมใช้งาน แต่คุณไม่สามารถสันนิษฐานได้ว่า bash นั้นใช้ได้ :) สำหรับการพกพาที่แท้จริง คุณต้องใช้เชลล์ POSIX พื้นฐาน เช่น `sh` หรือ `dash` คำตอบของฉันขึ้นอยู่กับการทุบตี วิธีแบบพกพาคือการต่อท่อไปยังเครื่องมือภายนอกแบบพกพาเช่น `sed` หรือ `perl` ทั้งหมดนี้อยู่นอกหัวข้อ แต่เราจัดการเฉพาะ Ubuntu เท่านั้น คุณอาจต้องการตรวจสอบ [linux.se] สำหรับคำถามเกี่ยวกับการพกพา
Jens avatar
tr flag
sh, dash, bash, zsh ฯลฯ ⦠ตัวเลือกมากเกินไป ⦠ฉันคิดว่าฉันลืมมุมมองโดยรวมไปพร้อมกับรายละเอียดนี้ oP ฉันต้องยอมรับว่าฉันยังไม่ได้พิจารณาปัญหาเชลล์นี้ บางทีตอนนี้ฉันควรจะอยู่กับ 'bash' จากมุมมองนี้ โค้ดของคุณดูดีขึ้นมาก ยิ่งฉันคิดถึงมันมากเท่าไหร่ xD
Score:0
ธง ng

นี่คือสคริปต์ bash5 (ไม่ใช่ bash4):

ตอนที่ 2 () {
   ท้องถิ่น -n var=$1
   var=${var#*:}
}
แอลซี() {
   ท้องถิ่น -n var=$1
   var=${var,,}
}
เฟรด = "อูบุนตู: คำพังเพย"
ตอนที่ 2 เฟร็ด
lc เฟรด
printf "%s\n" "$เฟรด"

เอาท์พุต:

คำพังเพย

ฟังก์ชั่น ตอนที่ 2 และ แอลซี แก้ไขตัวแปรที่มีการส่งชื่อให้โดยไม่ทำการ Forking สุดท้ายตัวแปรเดิม (เฟร็ด) ได้รับการแก้ไขแล้ว คุณยังต้องการตัวแปรพิเศษอยู่

ทางเลือกอื่นที่ควรใช้กับ bash4 มีดังนี้:

part2() { พิมพ์f "%s" "${1#*:}"; }
lc() { พิมพ์f "%s" "${1,,}" ; }
เฟรด = "อูบุนตู: GNOME"
printf "%s\n" "$(lc "$(ตอนที่ 2 "$เฟรด")")"

ซึ่งไม่ได้แก้ไขตัวแปรใด ๆ (จัดการค่าเท่านั้น) แต่สร้างส้อมพิเศษ

Jens avatar
tr flag
ก่อนอื่น: ขอบคุณสำหรับความพยายามของคุณ ผลลัพธ์ก็โอเค FYI: _all_ ของรหัสของคุณคือ Bash4 ในการกระทำ ;-)ฉันชื่นชมการเขียนโปรแกรมแบบโมดูลาร์จริงๆ แต่ในกรณีนี้ ฉันกำลังมองหาโค้ดคำสั่งเดียวหรืออีกทางเลือกหนึ่งคือซับใน ขออภัย แต่ยังไงก็ขอบคุณมากนะครับ

โพสต์คำตอบ

คนส่วนใหญ่ไม่เข้าใจว่าการถามคำถามมากมายจะปลดล็อกการเรียนรู้และปรับปรุงความสัมพันธ์ระหว่างบุคคล ตัวอย่างเช่น ในการศึกษาของ Alison แม้ว่าผู้คนจะจำได้อย่างแม่นยำว่ามีคำถามกี่ข้อที่ถูกถามในการสนทนา แต่พวกเขาไม่เข้าใจความเชื่อมโยงระหว่างคำถามและความชอบ จากการศึกษาทั้ง 4 เรื่องที่ผู้เข้าร่วมมีส่วนร่วมในการสนทนาด้วยตนเองหรืออ่านบันทึกการสนทนาของผู้อื่น ผู้คนมักไม่ตระหนักว่าการถามคำถามจะมีอิทธิพลหรือมีอิทธิพลต่อระดับมิตรภาพระหว่างผู้สนทนา