ลบอักขระบางตัวออกจากตัวแปรโดยใช้ bash


122

ฉันต้องการแยกตัวแปร (ในกรณีของฉันเป็นรุ่นชุดพัฒนา) เพื่อให้ dot ( .) ฟรี หากการส่งออกที่ต้องการคือversion='2.3.3'233

ฉันพยายามที่ดังต่อไปนี้ แต่ต้องถูกแทนที่ด้วยตัวอักษรอีกให้ฉัน. 2_3_3คงจะดีกว่านี้ถ้าใช้tr . ''งานได้

  1 VERSION='2.3.3' 
  2 echo "2.3.3" | tr . _

10
ไม่ไม่ต้องการ: echo "2.3.3" | tr -d ..
จัดการ

1
@ ทำงานที่ยอดเยี่ยมที่ได้ผล คุณสามารถโพสต์มันเป็นคำตอบ ขอบคุณ
prayagupd

1
คำตอบที่ดีมากมาย แต่ถ้าฉันคาดเดาวัตถุประสงค์ได้สองครั้งควรได้รับการเตือนเกี่ยวกับ 2.11.3 และ 2.1.13 ... ;-) ลองเพิ่มการเติมศูนย์เป็นตัวเลข
Rmano

1
@Rmano คุณหมายความว่าVERSION='2.30.3100'อย่างไร ไม่ว่า.คำตอบทั้งหมดจะถูกลบออกไปเพียงใด
prayagupd

2
@PrayagUpd --- ฉันแค่ตั้งใจว่าถ้าคุณจะใช้จำนวนหลังจากการแปลงสำหรับการเปรียบเทียบ (ที่จะบอกว่า "เป็นรุ่นที่ใหม่กว่าหรือเหมือนกัน") คุณควรดูแลกรณีเช่น 2.11.3 และ 2.1.13 - - ดูเหมือนว่าจะเหมือนเดิมหลังจากการลบจุด แต่ชัดเจนว่า 2.11.3 นั้นใหม่กว่า นอกจากนี้ 2.11.3 ใหม่กว่า 2.1.14 แต่การเปรียบเทียบ 2113 และ 2114 จะนำไปสู่คำตอบที่ผิด ผมจำได้ว่าข้อผิดพลาดบางแห่งนี้ ...
Rmano

คำตอบ:


135

ไม่จำเป็นต้องเรียกใช้โปรแกรมภายนอก bashการจัดการสตริงของสามารถจัดการได้ (ยังมีอยู่ในksh(มันมาจากไหน) และzsh):

$ VERSION='2.3.3'
$ echo "${VERSION//.}"
233

(ในคู่มือของ shells คุณสามารถค้นหาได้ในส่วนการขยายพารามิเตอร์)


19
สำหรับรายละเอียดเพิ่มเติมไวยากรณ์ของคำตอบดังกล่าวข้างต้นเป็น${string//substring/replacement}ที่เห็นได้ชัดว่าการขาดสุดท้ายทับและเปลี่ยนสตริงจะถูกตีความเป็นลบ ดูที่นี่
sherrellbc

5
ขวาman bashพูดอย่างชัดเจนในส่วนการขยายพารามิเตอร์ของเชลล์ :“ ${parameter/pattern/string}(…) หากสตริงเป็นโมฆะการจับคู่รูปแบบจะถูกลบและรูปแบบ/ต่อไปนี้อาจถูกตัดออกไป”
จัดการ

1
ปัญหาของฉันคือหมายเลขเวอร์ชันมาเป็นแบบนี้ "1.0.0"และฉันต้องการเพียงแค่จำนวนดังนั้นทำตามสิ่งที่ @atatwork แนะนำให้ฉันเปลี่ยน: "${VERSIONNUM//'"'}"แต่ฉันใส่แม้' ' เพราะมิเช่นนั้นจะไม่รู้จัก""สตริงตัวที่จะถอด
Alexiscanny

1
@Alexiscanny คุณหมายถึงตัวอักษรที่"มีอยู่ในค่าหรือไม่ ฉันเกรงว่านี่จะนับเป็นคำถามใหม่ แต่พยายามที่จะหลบหนี Doublequote: "${VERSIONNUM//\"}" pastebin.com/3ECDtkwH
จัดการ

1
สุดยอด !! ทำงาน-ashเช่นกัน!
Fr0zenFyr

87

ตามลำดับ:

TR / sed

echo "$VERSION" | tr -d .
echo "$VERSION" | sed 's/\.//g'

csh / tcsh

echo $VERSION:as/.//

เปลือกหอย POSIX:

set -f
IFS=.
set -- $VERSION
IFS=
echo "$*"

ksh / zsh / bash / yash (และ busybox ashเมื่อสร้างด้วยASH_BASH_COMPAT)

echo "${VERSION//.}"

zsh

echo $VERSION:gs/./

1
tr -d ลบถ่านแม้แต่ตัวเดียวออกจากชุด สำหรับอดีตฉันต้องการลบ DCC_ จาก "DCC_VersionD" มันจะลบ DCC และ D เอาต์พุตที่คาดหวัง: VersionD เอาต์พุตจริง: เวอร์ชัน sed ทำงานเหมือนมีเสน่ห์ :) ขอบคุณสำหรับการโพสต์
kayle

20

นอกเหนือจากคำตอบที่ประสบความสำเร็จแล้ว สิ่งเดียวกันสามารถทำได้ด้วยtrด้วย--deleteตัวเลือก

echo "2.3.3" | tr --delete .

ซึ่งจะส่งออก: 233


6
ใน macos --deleteไม่รู้จักการตั้งค่าสถานะ แต่คุณสามารถใช้-dแทน
Anentropic


4
echo "$VERSION" | tr -cd [:digit:]

นั่นจะส่งกลับเฉพาะตัวเลขไม่ว่าจะมีอักขระอื่น ๆ อยู่ด้วยก็ตาม


4

Perl

$ VERSION='2.3.3'                                     
$ perl -pe 's/\.//g' <<< "$VERSION"           
233

หลาม

$ VERSION='2.3.3'                                     
$ python -c 'import sys;print sys.argv[1].replace(".","")' "$VERSION"
233

หาก$VERSIONมีตัวเลขและจุดเท่านั้นเราสามารถทำสิ่งที่สั้นกว่า:

$ python -c 'print "'$VERSION'".replace(".","")'
233

(ระวังว่ามันเป็นช่องโหว่ในการฉีดรหัสแม้ว่า$VERSIONจะมีตัวอักษรใด ๆ ก็ตาม)

AWK

$ VERSION='2.3.3'
$ awk 'BEGIN{gsub(/\./,"",ARGV[1]);print ARGV[1]}' "$VERSION"
233

หรือสิ่งนี้:

$ awk '{gsub(/\./,"")}1' <<< "$VERSION"
233
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.