คำสั่งเพื่อหลีกเลี่ยงสตริงใน bash


103

ฉันต้องการคำสั่ง bash ที่จะแปลงสตริงเป็นสิ่งที่หนี นี่คือตัวอย่าง:

echo "hello\world" | escape | someprog

ในกรณีที่คำสั่งการหลบหนีทำให้เข้า"hello\world" "hello\\\world"จากนั้น someprog สามารถใช้งานได้"hello\\world"ตามที่คาดหวัง แน่นอนว่านี่เป็นตัวอย่างที่เรียบง่ายของสิ่งที่ฉันจะทำจริงๆ


5
ลักษณะของการหลบหนีเป็นอย่างไร? กล่าวอีกนัยหนึ่งอักขระใดที่ต้องหลีกหนี? คุณกำลังมองหาการหลีกเลี่ยงสไตล์ C ++ (โดยที่แท็บถูกแทนที่ด้วย \ t, ขึ้นบรรทัดใหม่ด้วย \ n, เครื่องหมายคำพูดด้วย \ "ฯลฯ ) ช่วยได้ยากหากไม่มีปัญหาในการกำหนดไว้อย่างชัดเจน
Michael Aaron Safyan

2
เป็นไปได้ที่จะซ้ำกันของเสียงสะท้อนที่เชลล์หนีอาร์กิวเมนต์
P Shved

คำถามนี้อาจหมายถึงสิ่งต่าง ๆ มากมาย แทนที่จะทำให้เราเดามันจะช่วยได้ถ้าคุณระบุว่าคุณกำลังมองหาการหลบหนีแบบไหน
ดอนฟัก

1
คำถามเฉพาะสำหรับการใช้ \\ สำหรับ \. มีคำตอบที่เป็นที่ยอมรับ
User1

คำตอบ:


159

ใน Bash:

printf "%q" "hello\world" | someprog

ตัวอย่างเช่น:

printf "%q" "hello\world"
hello\\world

สิ่งนี้สามารถใช้ผ่านตัวแปรได้เช่นกัน:

printf -v var "%q\n" "hello\world"
echo "$var"
hello\\world

6
ใจคุณ%qเสียมานานกว่าทศวรรษที่ผ่านมาจนถึงปี 2012 ~มันมีปัญหากับ นอกจากนี้ยังมีแบบพกพา sed one-liners stackoverflow.com/a/20053121/1073695
Jo So

1
sed ดีกว่าแน่นอนเพราะสามารถหลีกเลี่ยงสัญญาณดอลลาร์ได้เช่นกัน
ถึง

2
@untore: a='abc$def":'; printf '%q\n' "$a"ผลลัพธ์ในabc\$def\":(เครื่องหมายดอลลาร์ถูกหลีกเลี่ยง) นี่คือ Bash 4.3 (ฉันได้ผลลัพธ์เดียวกันใน Bash 3.2) คุณใช้เวอร์ชันอะไร
หยุดชั่วคราวจนกว่าจะมีประกาศอีกครั้ง

3
หากต้องการหลีกเลี่ยงเครื่องหมายดอลลาร์ให้ใช้เครื่องหมายคำพูดเดี่ยวแทนเช่นprintf "%q" 'he$l&lo\world'
LeandroCR

bash จะprintf '%q\n' textเสนอราคาข้อความในbashรูปแบบ (และสำหรับโลแคลปัจจุบัน) ดังนั้นจะใช้ได้เฉพาะในกรณีของ OP เท่านั้นหากพวกเขาsomeprogมีไวยากรณ์การอ้างอิงที่เหมือนกันbashซึ่งไม่น่าเป็นไปได้สูง
Stephane Chazelas

9

Pure Bash ใช้การทดแทนพารามิเตอร์:

string="Hello\ world"
echo ${string//\\/\\\\} | someprog

1
วิธีนี้ "สวัสดีชาวโลก" ไม่ได้หนีไปสู่ ​​"สวัสดีโลก" - printf aproach ในคำตอบที่ยอมรับทำเช่นนั้น
vchrizz

1
นอกจากนี้ "% q" ไม่หนี '/' เช่นเดียวกับใน "03/25/2017" ซึ่งฉันต้องหนีไปที่ "03 \ / 25 \ / 2017" (เพื่อให้สามารถใช้ตัวคั่น "/" ปกติได้ นิพจน์).
เขียน

0

คุณสามารถใช้ perl เพื่อแทนที่อักขระต่างๆเช่น:

$ echo "Hello\ world" | perl -pe 's/\\/\\\\/g'
Hello\\ world

ขึ้นอยู่กับลักษณะของการหลบหนีของคุณคุณสามารถเชื่อมโยงหลายสายเพื่อหลบหนีอักขระที่เหมาะสม


1
ทำไมไม่ sed? $ echo "hello \ world" | sed 's / \\ / \\\\ /'
Space

1
@ Octopus นั่นเป็นตัวเลือกที่ถูกต้อง ฉันรู้สึกสบายใจกับ perl มากขึ้น แต่ก็ใช้ได้ผลเช่นกัน
Michael Aaron Safyan
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.