Piping string manipulation


9

ฉันได้อ่านคำถามเกี่ยวกับการจัดการสตริงทุบตี bash อื่น ๆ แต่ดูเหมือนจะเป็นแอปพลิเคชันพิเศษ

เป็นหลักมีวิธีการทำด้านล่างง่ายขึ้น?

แทน

$ string='hello world'; string2="${string// /_}"; echo "${string2^^}"
HELLO_WORLD

สิ่งที่ต้องการ

$ echo 'hello world' | $"{-// /_}" | "${ -^^}"
HELLO_WORLD

แก้ไขฉันสนใจที่จะอยู่ในการควบคุมของ bash หากเป็นไปได้เพื่อรักษาความเร็ว (ตรงข้ามกับ sed / awk ซึ่งมีแนวโน้มที่จะทำให้สคริปต์ของฉันช้าลงอย่างมาก)

แก้ไข 2: @jimmij

ฉันชอบตัวอย่างที่สองและทำให้ฉันทำฟังก์ชั่น

bash_m() { { read x; echo "${x// /_}"; } | { read x; echo "${x^^}"; }; }
echo hello world | bash_m
HELLO_WORLD

1
ทำไมคุณถึงคิดว่า sed / awk จะช้าสำหรับจุดประสงค์นี้ พวกเขาเร็วเท่าที่พวกเขามา
mkc

1
@ Ketan Sed และ awk เป็นกระบวนการที่แยกกันดังนั้นพวกเขาจึงไม่สามารถทำได้อย่างรวดเร็วเหมือนสิ่งที่ทุบตีสามารถทำได้โดยไม่ต้องเปิดกระบวนการแยกต่างหาก โดยทั่วไปความแตกต่างนี้จะสังเกตได้ยาก แต่ประสิทธิภาพของการทำงานในเชลล์สคริปมักจะวนซ้ำหรือการคำนวณซ้ำหลายครั้งมากและการวางไข่ของกระบวนการหลายพันจะช้าลงอย่างเห็นได้ชัดกว่าทำการจัดการสตริงอย่างง่าย ๆ
jw013

2
@ jw013 นี่เป็นความจริงสำหรับสตริงสั้น ๆ ว่า "สวัสดีโลก" จากคำถาม แต่ถ้าสตริงยาวมากให้พูดด้วยtrตนเองจากนั้นตรงข้ามเป็นจริงเพราะเวลาของการวางไข่กระบวนการจะน้อยมากเมื่อเทียบกับเวลาของการจัดการสตริงที่sedและawkทุ่มเท ถ้าสายยาวมากพูดคู่มือทุบตีทั้งหมดแล้วทุบตีก็สามารถปฏิเสธที่จะดำเนินการต่อไปทั้งหมดเพราะข้อ จำกัด ภายในบางอย่าง
jimmij

2
@ jw013 ฉันอ้างว่ารหัสสตริงจัดการทุบตีเป็นเครื่องมือที่มีประสิทธิภาพน้อยลงโดยเฉพาะแล้วsed, awk, trหรือคล้ายกัน ดูคำตอบ gena2x ซึ่งฉันได้แก้ไขเมื่อไม่นานมานี้เพิ่มข้อมูลตรงนี้: unix.stackexchange.com/questions/162221/คุณอาจต้องการเปรียบเทียบกับคำตอบ terdon กับคำถามเดียวกันที่เขาให้เวลากับสตริงสั้น ๆ การวางไข่กระบวนการกรณีใช้เวลามากที่สุด คุณสามารถทดสอบด้วยตัวเองและโพสต์ผลการ
jimmij

1
@ Miati เหตุใดคุณคิดว่าสิ่งนี้พิเศษread x; echo $xกว่าประสิทธิภาพมากกว่า? ไวยากรณ์ไม่ได้ดูสั้นลงหรือสะอาดขึ้น เป็นวิธีที่รัดกุมมากขึ้นเพื่อทำสิ่งเดียวกันเป็นx=${x// /_}; x=${x^^} {read x; echo ${x...@jimmij ได้ชี้ให้เห็นว่าtr/ sedจะเร็วกว่าbashนั้นการนับจำนวนจะเท่ากัน การใช้ไพพ์จะส่งผลให้เกิดกระบวนการพิเศษเสมอดังนั้นอาร์กิวเมนต์ของการบันทึกฟอร์กไม่ได้ใช้อีกต่อไป ดังนั้นหากใช้งานท่อให้ใช้sed/ tretc หากคุณสามารถทำได้โดยใช้ทุบตีให้ทำเช่นนั้นและข้ามread x; echo $xเรื่องไร้สาระนี้
jw013

คำตอบ:


9

jimmij พูดอะไร ตัวอย่างสุดท้ายของเขาคือสิ่งที่ใกล้เคียงที่สุดที่คุณจะได้รับในสิ่งที่คุณพยายามทำในการแสดงออกทางสีหน้า

นี่คือตัวแปรในชุดรูปแบบ:

echo 'hello world'|echo $(read s;s=${s^^};echo ${s// /_})

ฉันอยากจะใช้trเพราะมันค่อนข้างเร็ว

echo 'hello world'|tr ' [:lower:]' '_[:upper:]'

ฉันคิดว่ามันเป็นความอัปยศที่ bash ไม่อนุญาตให้มีการขยายพารามิเตอร์แบบซ้อน OTOH การใช้นิพจน์ที่ซ้อนกันนั้นสามารถนำไปสู่โค้ดที่เจ็บปวดในการอ่านได้อย่างง่ายดาย หากคุณไม่ต้องการให้สิ่งต่าง ๆ ทำงานเร็วเท่าที่จะเป็นไปได้คุณควรเขียนโค้ดที่ง่ายต่อการอ่านทำความเข้าใจและบำรุงรักษาแทนที่จะใช้โค้ดที่ดูฉลาดซึ่งเป็น PITA ที่จะดีบั๊ก และถ้าคุณต้องการทำสิ่งต่าง ๆ ด้วยความเร็วสูงสุดคุณควรใช้รหัสที่คอมไพล์ไม่ใช่สคริปต์


7

คุณไม่สามารถผ่านการขยายพารามิเตอร์ได้ เมื่อคุณอ้างถึงxโดยใช้$สัญลักษณ์เช่นเดียวกับในรูปแบบแล้วก็จะต้องมีชื่อตัวแปรจริงไม่เข้ามาตรฐานอย่างน้อยไม่ได้อยู่ใน"${x}" bashในzshคุณสามารถทำการทดแทนพารามิเตอร์ที่ซ้อนกันด้วยวิธีต่อไปนี้:

$ x=''hello world'
$ echo ${${x// /_}:u}
HELLO_WORLD

(หมายเหตุ: :uสำหรับการzshเช่นเดียวกับ^^สำหรับbash)

การซ้อนใน bash นั้นเป็นไปไม่ได้และฉันคิดว่าสิ่งที่คุณเขียนในคำถามนั้นเป็นวิธีที่ดีที่สุดที่จะได้รับ แต่ถ้าด้วยเหตุผลแปลก ๆ ที่คุณต้องมีส่วนร่วมในการสร้างสมการคุณอาจต้องการลอง:

$ echo 'hello world' | { read x; echo "${x// /_}"; } | { read y; echo "${y^^}"; }
HELLO_WORLD

1
เมื่อพิจารณาจากการสนทนาล่าสุดของเราเกี่ยวกับวิธีการtr/ sedจะเร็วกว่าbashที่ประมวลผลสตริงและพิจารณาว่าคุณกำลังใช้ท่อที่จะผ่านสายผ่านมาตรฐาน I / O ที่ฉันเห็นตัวอักษรศูนย์จุดในการทำการดำเนินงานของผู้ที่อยู่ในทุบตีเมื่อเทียบกับ/tr sedทำไมคนเรา| { read x; echo $x... }ถึง| sedไม่ได้ทำในสิ่งเดียวกัน
jw013

1
@ jw013 พูดตรงไปตรงมาฉันเห็นถัดจากไม่มีจุด มันเป็นเพียงตัวอย่างที่จะมีส่วนร่วมอย่างแข็งขันท่อกับปัญหาเพราะ OP ถามอย่างชัดเจนสำหรับพวกเขาและไม่ต้องการที่จะใช้โปรแกรมภายนอก (ทั้งสองechoและreadมีทุบตีตัว -ins ดังนั้นในหลักการนิด ๆ หน่อย ๆ ได้เร็วขึ้น) ตามที่ฉันได้เขียนไว้แล้วในคำตอบการจัดการพารามิเตอร์แบบโปรเกรสซีฟซึ่ง OP มีในคำถามนั้นเป็นสิ่งที่ดีที่สุดที่จะได้รับในความคิดของฉันสำหรับงานนี้ในการทุบตี อย่างไรก็ตามปัญหาคือนักวิชาการค่อนข้าง
jimmij
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.