ฉันจะลบช่องว่างออกจากตัวแปรเชลล์ได้อย่างไร


15

ฉันทำต่อไปนี้ที่บรรทัดคำสั่ง:

$ text="name with space"
$ echo $text
name with space

ฉันพยายามที่จะใช้tr -d ' 'เพื่อลบช่องว่างและมีผลมาจาก:

namewithspace

ฉันพยายามทำบางสิ่งเช่น:

text=echo $text | tr -d ' '

ไม่มีโชคดีหวังว่าคุณจะสามารถช่วยชาวพื้นบ้านที่ยอดเยี่ยม

คำตอบ:


45

ใน Bash คุณสามารถใช้การจัดการสตริงของ Bash ได้ ในกรณีนี้คุณสามารถทำได้:

> text="some text with spaces"
> echo "${text// /}"
sometextwithspaces

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวดำเนินการจัดการสตริงให้ดูที่http://tldp.org/LDP/abs/html/string-manipulation.html

อย่างไรก็ตามกลยุทธ์ดั้งเดิมของคุณก็ใช้งานได้ซินแทกซ์ของคุณก็ออกมาเล็กน้อย:

> text2=$(echo $text | tr -d ' ')
> echo $text2
sometextwithspaces

ฉันไม่ได้คิดอย่างนั้นอยู่ในอารมณ์ที่ทำงานนี้! คำตอบที่ดีเช่นกัน!
user3347022

11

คุณไม่ต้องการechoคำสั่งเลยเพียงใช้Here Stringแทน:

text=$(tr -d ' ' <<< "$text")

เพียงเพื่อความอยากรู้อยากเห็นฉันตรวจสอบว่าใช้เวลานานเท่าใดในการทำงานที่ไม่สำคัญสำหรับเครื่องมือต่างๆ นี่คือผลลัพธ์ที่เรียงลำดับจากช้าที่สุดไปเร็วที่สุด:

abc="some text with spaces"

$ time (for i in {1..1000}; do def=$(echo $abc | tr -d ' '); done)
0.76s user 1.85s system 52% cpu 4.976 total

$ time (for i in {1..1000}; do def=$(awk 'gsub(" ","")' <<< $abc); done)
1.09s user 2.69s system 88% cpu 4.255 total

$ time (for i in {1..1000}; do def=$(awk '$1=$1' OFS="" <<< $abc); done)
1.02s user 1.75s system 69% cpu 3.968 total

$ time (for i in {1..1000}; do def=$(sed 's/ //g' <<< $abc); done)
0.85s user 1.95s system 76% cpu 3.678 total

$ time (for i in {1..1000}; do def=$(tr -d ' ' <<< $abc); done)
0.73s user 2.04s system 85% cpu 3.244 total

$ time (for i in {1..1000}; do def=${abc// /}; done)
0.03s user 0.00s system 59% cpu 0.046 total

การทำงานของกระสุนบริสุทธิ์นั้นเร็วที่สุดในสิ่งที่ไม่น่าแปลกใจ แต่สิ่งที่น่าประทับใจจริงๆคือมันเร็วกว่า 100 เท่าจากนั้นจึงเป็นคำสั่งที่ช้าที่สุด!


นั่นไม่ใช่stackoverflow.com/q/14967299 ที่
Steven Penny

5

เพียงแก้ไขตัวแปรข้อความของคุณดังนี้

text=$(echo $text | tr -d ' ')

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

text="$(echo "$text" | tr -d ' ')"

จะเป็นรุ่นที่ดีกว่า


ยอดเยี่ยม! ฉันสนิทมาก ในฐานะที่เป็น noob ฉันยินดีที่ได้มุ่งหน้าไปในทิศทางที่ถูกต้อง ขอบคุณสำหรับการตอบสนองที่รวดเร็วเช่นกันทันทีที่ฉันรอ 8 นาทีฉันจะส่งคำตอบนี้!
user3347022

@ user3347022 ยินดีต้อนรับ :)
Ramesh

1
สิ่งนี้จะแตกถ้า$textมีอักขระควบคุมซึ่งเชลล์จะตีความ ควรใส่เครื่องหมายคำพูดคู่ไว้ในนั้น:text="$(echo "$text" | tr -d ' ')"
kasperd

@kasperd ขอบคุณที่พูดถึงมัน ฉันได้รวมข้อเสนอแนะของคุณ
Ramesh


2

กรณีพิเศษเมื่อคุณต้องการตัวแปรที่มีตัวเลข:

ดวลจุดโทษ:

typeset -i A=B #or
typeset -i A="   23232"

kSH:

typeset -n A=B #or
typeset -n A="   23232"
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.