ฉันจะสะท้อนอักขระแท็บอย่างน้อยหนึ่งตัวโดยใช้สคริปต์ทุบตีได้อย่างไร เมื่อฉันเรียกใช้รหัสนี้
res=' 'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]
ฉันได้รับสิ่งนี้
res=[ x] # that is [<space>x]
ฉันจะสะท้อนอักขระแท็บอย่างน้อยหนึ่งตัวโดยใช้สคริปต์ทุบตีได้อย่างไร เมื่อฉันเรียกใช้รหัสนี้
res=' 'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]
ฉันได้รับสิ่งนี้
res=[ x] # that is [<space>x]
คำตอบ:
echo -e ' \t '
จะ echo 'ช่องว่างช่องว่างขึ้นบรรทัดใหม่' ( -eหมายถึง 'เปิดใช้งานการตีความเครื่องหมายทับขวา'):
$ echo -e ' \t ' | hexdump -C
00000000 20 09 20 0a | . .|
echo -eไม่ว่าทำไมไม่ทำงานจาก Makefiles
echo -eไม่ใช่ POSIX และการmakeโทร/bin/shซึ่งปกติแล้วไม่ใช่โปรแกรมที่ใช้จะใช้แบบโต้ตอบและโดยปกติจะไม่ได้-eใช้งาน สำหรับการพกพาให้ใช้printf '\t'แทน
manหน้าสำหรับคำสั่งไม่ได้พูดถึงตัวเลือกecho -eอย่างไรก็ตามตัวเลือกนี้ได้รับการยอมรับ
ใช้ไม่ได้printfecho
echoคำสั่งมีหลายเวอร์ชัน มี/bin/echo(ซึ่งอาจเป็นหรือไม่เป็นรุ่น GNU Coreutils ขึ้นอยู่กับระบบ) และechoคำสั่งนั้นถูกสร้างไว้ในเชลล์ส่วนใหญ่ เวอร์ชันที่ต่างกันมีวิธีที่แตกต่างกัน (หรือไม่มีวิธี) ในการระบุหรือปิดใช้งาน Escape สำหรับอักขระควบคุม
printfในทางกลับกันมีการเปลี่ยนแปลงน้อยกว่ามาก มันสามารถอยู่เป็นคำสั่งโดยทั่วไป/bin/printfและก็สร้างขึ้นในเปลือกหอยบางคน (ทุบตีและ zsh มีมัน tcsh และ ksh ทำไม่ได้) แต่รุ่นต่างๆมีมากขึ้นคล้าย ๆ กันกว่ารุ่นที่แตกต่างกันechoอยู่ และคุณไม่จำเป็นต้องจำตัวเลือกบรรทัดคำสั่ง (มีข้อยกเว้นเล็กน้อย GNU Coreutils printf ยอมรับ--versionและ--helpและ bash printf ในตัวยอมรับ-v varการจัดเก็บเอาต์พุตในตัวแปร)
สำหรับตัวอย่างของคุณ:
res=' 'x # res = "\t\tx"
printf '%s\n' "[$res]"
และตอนนี้ก็ถึงเวลาที่ฉันต้องยอมรับว่ามันechoจะได้ผลเช่นเดียวกับตัวอย่างที่คุณถาม คุณเพียงแค่ใส่เครื่องหมายคำพูดคู่รอบอาร์กิวเมนต์:
echo "[$res]"
ตามที่ kmkaplan เขียน (สองปีครึ่งที่ผ่านมาฉันเพิ่งสังเกตเห็น!) ปัญหาเกี่ยวกับคำสั่งดั้งเดิมของคุณ:
res=' 'x # res = "\t\tx"
echo '['$res']' # expect [\t\tx]
ไม่ได้อยู่กับecho; มันคือเปลือกแทนที่แท็บด้วยช่องว่างก่อนที่จะechoเคยเห็นมัน
echoไม่เป็นไรสำหรับเอาต์พุตแบบง่ายเช่นecho hello worldแต่คุณควรใช้printfเมื่อใดก็ตามที่คุณต้องการทำอะไรที่ซับซ้อนกว่านี้ คุณสามารถได้รับechoในการทำงาน แต่รหัสส่งผลให้มีแนวโน้มที่จะล้มเหลวเมื่อคุณเรียกมันด้วยแตกต่างกันechoการดำเนินการหรือเปลือกที่แตกต่างกัน
คุณสามารถลอง:
echo Hello$'\t'world.
คุณต้องใช้แฟล็ก -e สำหรับ echo จากนั้นคุณสามารถ
echo -e "\t\t x"
จากหน้าคนทุบตี:
คำของฟอร์ม 'string' ได้รับการปฏิบัติเป็นพิเศษ คำขยายออกเป็นสตริงด้วยอักขระเครื่องหมายทับขวาทับกลับแทนที่ตามที่ระบุโดยมาตรฐาน ANSI C
ดังนั้นคุณสามารถทำสิ่งนี้:
echo $'hello\tworld'
ใช้คำต่อคำการกดแป้นพิมพ์^V( CTRL+V, C-v, สิ่งที่ )
เมื่อคุณพิมพ์^Vลงในเทอร์มินัล (หรือในตัวแก้ไข Unix ส่วนใหญ่) อักขระต่อไปนี้จะถูกนำไปใช้คำต่อคำคำต่อคำคุณสามารถใช้สิ่งนี้เพื่อพิมพ์ตัวอักษรแท็บตัวอักษรภายในสตริงที่คุณกำลังสะท้อน
สิ่งที่ชอบทำงานต่อไปนี้:
echo "^V<tab>" # CTRL+V, TAB
Bash docs ( qv , "quote-insert")
ใบเสนอราคาแทรก (Cq, Cv) เพิ่มอักขระถัดไปที่คุณพิมพ์ลงในบรรทัดคำต่อคำ นี่คือวิธีการแทรกลำดับคีย์เช่น Cq
หมายเหตุด้านข้าง: ตามนี้ ALT+TAB ควรทำสิ่งเดียวกัน แต่เราทุกคนเชื่อมโยงลำดับนั้นกับการสลับหน้าต่างเพื่อให้เราไม่สามารถใช้งานได้
tab-insert (M-TAB) แทรกอักขระแท็บ
-
หมายเหตุ: คุณสามารถใช้กลยุทธ์นี้กับตัวละครที่ผิดปกติทุกประเภท เหมือนการคืนรถ:
echo "^V^M" # CTRL+V, CTRL+M
นี่เป็นเพราะ carriage return คือ ASCII 13 และMเป็นตัวอักษรที่ 13 ของตัวอักษรดังนั้นเมื่อคุณพิมพ์^Mคุณจะได้รับอักขระ ASCII ที่ 13 คุณสามารถดูได้โดยใช้ls^Mพรอมต์ที่ว่างเปล่าซึ่งจะแทรกการขึ้นบรรทัดใหม่กลับทำให้พรอมต์ทำหน้าที่เหมือนกับที่คุณกดปุ่มย้อนกลับ เมื่อตัวละครเหล่านี้ถูกตีความตามปกติคำต่อคำจะทำให้คุณได้รับตัวอักษรที่แท้จริง
grepเพื่อจับเส้นที่มีtabอักขระ
การใช้ echo เพื่อพิมพ์ค่าของตัวแปรเป็นข้อผิดพลาด Bash ทั่วไป ลิงค์อ้างอิง:
หากคุณต้องการใช้echo "a\tb"ในสคริปต์คุณเรียกใช้สคริปต์เป็น:
# sh -e myscript.sh
อีกทางเลือกหนึ่งคือคุณสามารถมอบสิทธิ์การใช้งาน myscript.sh ให้กับคุณเพื่อรันสคริปต์
# chmod +x myscript.sh
# ./myscript.sh
res="\t\tx"
echo -e "[${res}]"