ฉันจะป้อนไฟล์หรือไดเรกทอรีที่มีอักขระพิเศษในชื่อได้อย่างไร


44

ฉันต้องการที่จะเข้าสู่โฟลเดอร์ต่อไปนี้ใน terminal:

Milano, Torino (Jan)-Compressed

ฉันจะเขียนคำสั่งcdเพื่อเข้าสู่ไดเรกทอรีนี้ได้อย่างไร

ช่องว่างและหลายอักขระพิเศษอื่น ๆ ชอบ\, *, ), (และ?ทำให้เกิดปัญหาเมื่อฉันพยายามที่จะใช้พวกเขาในบรรทัดคำสั่งหรือสคริปต์เช่น:

$ cd space dir
bash: cd: space: No such file or directory

$ cat space file
cat: space: No such file or directory
cat: file: No such file or directory

$ cat (
bash: syntax error near unexpected token `newline'

$ echo content >\
> ^C

$ ls ?
(  )  *  ?  \

ฉันจะป้อนชื่อไฟล์หรือไดเรกทอรีที่มีอักขระพิเศษในเทอร์มินัลโดยทั่วไปได้อย่างไร


ที่เกี่ยวข้อง: มาตรา 3.1.2 Quotingของคู่มืออ้างอิงทุบตี
Eliah Kagan

คำตอบ:


43

คำสั่งนั้นคลุมเครือเนื่องจากช่องว่างมักใช้เพื่อแยกอาร์กิวเมนต์ cd ไม่ทราบว่าคุณต้องการทำอะไร แต่คุณมีสองวิธีในการแก้ไข:

ไม่ว่าคุณจะ " ปิดบัง " ช่องว่าง (และอักขระพิเศษอื่น ๆ ทั้งหมด) เพื่อให้เทอร์มินัลรู้ว่าคุณหมายถึงช่องว่างเป็นอักขระและไม่เป็นตัวคั่น:

cd Milano\,\ Torino\ \(Jan\)-Compressed

หรือคุณใส่ชื่อโฟลเดอร์หรือเส้นทางของคุณลงในเครื่องหมายคำพูด :

cd "Milano, Torino (Jan)-Compressed"

26

เคล็ดลับเล็กน้อย: การทำให้แท็บเสร็จ ;-)

  1. เพียงแค่พิมพ์เช่นตัวอักษรตัวแรกcd Mi(หรือตัวอักษรเพิ่มเติมถ้าจำเป็น) Tabและกด เทอร์มินัลจะช่วยคุณโดยเติมคำศัพท์ที่เหลือ

อีกวิธีหนึ่ง: ลากแล้วปล่อย

  1. หากคุณสามารถดูไดเรกทอรีและถ้าคุณต้องการที่จะเข้าถึงได้โดยใช้ขั้วเพียงพิมพ์: ลากก่อนแล้วและวางไดเรกทอรีบนสถานีและตี cdenter

24

เขียนเป็น:

cd 'Milano, Torino (Jan)-Compressed'

มิฉะนั้นจะถือว่าMilano,เป็นชื่อโฟลเดอร์ สิ่งนี้เกิดขึ้นเนื่องจากช่องว่างในชื่อของโฟลเดอร์ หรือหลีกเลี่ยงอักขระพิเศษบางตัว:

cd Milano\,\ Torino\ \(Jan\)-Compressed/

22

TL; DR : เพื่อพูดอักขระพิเศษอย่างใดอย่างหนึ่งหลบหนีด้วยเครื่องหมาย\หรือใส่ในคู่คำพูดเดียวหรือ" " การดำเนินการให้เสร็จสมบูรณ์จะดูแลเรื่องการอ้างอิงอย่างเหมาะสม' 'Tab ↹


สิ่งที่คุณขอเรียกว่าการอ้างถึง :

การอ้างอิงใช้เพื่อลบความหมายพิเศษของอักขระหรือคำบางคำในเชลล์ ( ... ) มีสามกลไก quoting คือ: ตัวหนี , ราคาเดียวและราคาคู่ [การอ้างอิงที่นำมาจากman bash]

การอ้างอิงด้วยอักขระการหลบหนี \

เครื่องหมายแบ็กสแลชที่ไม่ใช่เครื่องหมายอัญประกาศ ( \) เป็นอักขระยกเว้น <newline>จะรักษามูลค่าที่แท้จริงของตัวอักษรถัดไปที่ตามมาด้วยข้อยกเว้นของ

ดังนั้นหากต้องการป้อนไดเรกทอรีหรือไฟล์ที่มีอักขระพิเศษให้หลีกเลี่ยงหลังด้วย\เช่น:

cd space\ dir      # change into directory called “space dir”
cat space\ file    # print the content of file “space file”
echo content > \\  # print “content” into file “\”
cat \(             # print the content of file “(”
ls -l \?           # list file “?”

bash's ตั้งโปรแกรมเสร็จ (aka Tab ↹เสร็จ) \โดยอัตโนมัติหนีตัวอักษรพิเศษกับตัวหนี

การอ้างอิงด้วยเครื่องหมายคำพูดคู่ " "

ล้อมรอบตัวอักษรในคำพูดสองรักษามูลค่าที่แท้จริงของตัวละครทุกตัวที่อยู่ในคำพูดที่มีข้อยกเว้นของ$, `, และเมื่อการขยายตัวประวัติถูกเปิดใช้งาน\!

ดังนั้นหากต้องการใส่ไดเรกทอรีหรือไฟล์ที่มีตัวอักษรพิเศษให้เว้นอย่างน้อยส่วนหลังหรือส่วนใหญ่ของชื่อไฟล์หรือพา ธ ของคุณด้วยเครื่องหมายคำพูดคู่เช่น:

cd space" "dir     # change into directory called “space dir”
cd spac"e di"r     # equally
cd "space dir"     # equally
cat "space file"   # print the content of file “space file”
cat "("            # print the content of file “(”
ls -l "?"          # list file “?”

ในฐานะที่เป็น$, `และ!ให้ความหมายพิเศษของพวกเขาภายในราคาคู่พารามิเตอร์การขยายตัว , คำสั่งชดเชย , การขยายตัวทางคณิตศาสตร์และการขยายตัวประวัติศาสตร์จะดำเนินการในสายยกมาสองครั้ง

การอ้างอิงด้วยเครื่องหมายคำพูดเดี่ยว ' '

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

ดังนั้นหากต้องการใส่ไดเรกทอรีหรือไฟล์ที่มีตัวอักษรพิเศษให้เว้นอย่างน้อยส่วนหลังหรือส่วนใหญ่ของชื่อไฟล์หรือพา ธ ของคุณด้วยเครื่องหมายคำพูดคู่เช่น:

cd space' 'dir     # change into directory called “space dir”
cd spac'e di'r     # equal
cd 'space dir'     # equal
cat 'space file'   # print the content of file “space file”
cat '('            # print the content of file “(”
ls -l '?'          # list file “?”
echo content > '\' # print “content” into file “\”

คุณสามารถค้นหาข้อมูลเพิ่มเติมเกี่ยวกับ Quoting ในman bash/ ข้อความบนwiki.bash-hackers.orgและtldp.org


10

สตริง C-like และ $ 'string'

เหนือสิ่งอื่นใดเราสามารถใช้$'...'ประเภทของการอ้างอิงเพื่อใช้ประโยชน์จากอักขระแบ็กสแลช ANSI-C เช่น\nและ\tรวมถึงสิ่งที่คุณพูดถึง จาก bash 4.3 manual:

คำของฟอร์ม 'string' ได้รับการปฏิบัติเป็นพิเศษ คำนี้ขยายออกเป็นสตริงด้วยอักขระเครื่องหมายทับขวาทับกลับแทนที่ตามที่ระบุโดยมาตรฐาน ANSI C

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

ตัวอย่างเช่นการสร้างและรายชื่อไฟล์ดังกล่าว:

$ touch a$'*'b  c$'\n'd                                                     
$ ls  a$'*'b  c$'\n'd                                                       
a*b  c?d

คุณสามารถใช้ประโยชน์จากค่าฐานสิบหกตัวอักษรเช่น:

$ touch 'file(name'
$ ls file$'\x28'name
file(name

printf

แนวคิดเดิม - ใช้ประโยชน์จากอักขระเลี่ยง:

$ ls "$(printf "file\x28name")"                                             
file(name
$ echo "Hello World"  >  c$'\n'd                                            
$ cat "$(printf "c\nd")"                                                    
Hello World

ใช้ inodes:

ทุกไฟล์หรือไดเรกทอรีมีโครงสร้างข้อมูลพิเศษที่เกี่ยวข้องกับมันเรียกว่า inode ซึ่งอ้างอิงโดยตัวเลขทศนิยมเฉพาะ ดังนั้นคุณสามารถใช้เพื่อค้นหาไฟล์โดยใช้ไอโหนดโดยเฉพาะผ่านทางfindคำสั่งและทำบางสิ่งกับมัน:

$ echo "This is a test" > file$'('name1
$ ls -i
5898996 file(name1  5898997 file?name2
$ find -type f -inum "5898996" -exec cat {} \;
This is a test

หลีกเลี่ยงการจัดการกับไฟล์แต่ละไฟล์เมื่อคุณสามารถใช้ glob

เมื่อคุณไม่ต้องจัดการกับไฟล์แต่ละไฟล์ให้ใช้ประโยชน์จาก*ตัวละครแบบกลมในเชลล์และเครื่องหมายคำพูดเมื่อส่งไปยังคำสั่งอื่น มันทำให้การจัดการกับชื่อไฟล์ที่ยากขึ้นง่ายขึ้น:

$ for f in ./*; do echo "$f" ; done
file    name2
file(name1

จดบันทึกการใช้./- การป้องกันชื่อไฟล์ซึ่งอาจมีการนำ-หน้าด้วย


6

เพื่อเปิดโฟลเดอร์ที่มีพื้นที่ล้อมรอบมันในเครื่องหมายคำพูดเช่นหรือหลบหนีพื้นที่ที่มีเครื่องหมายเช่น:cd "Some Directory"cd /home/kudic/Radna\ površina


3
หรือหลบหนีจากอวกาศด้วยแบ็กสแลชเช่น:cd /home/kudic/Radna\ površina
Timo

จุดที่ดี! ฉันลืมที่จะพูดถึงว่า ปกติฉันจะใช้อัญประกาศที่ไม่ติดนิสัย แต่แบ็กสแลชดีกว่าที่จะใช้ในระยะยาว
Corey Whitaker

1
หรือใช้เครื่องหมายคำพูดเดี่ยว ( 'Radna površina') หากคุณไม่ต้องการให้ตัวแปรสภาพแวดล้อม ( $VARNAME) ถูกขยายและคำสั่งที่อยู่ใน backticks หรือ$()เรียกใช้ (หรือหากมีเครื่องหมายคำพูดคู่อยู่ในชื่อไฟล์)
Eliah Kagan

3

หากไดเรกทอรีนี้อยู่ในโฟลเดอร์บ้านของคุณให้พิมพ์:

cd "Milano, Torino (Jan)-Compressed"

อื่นให้เส้นทางที่แน่นอน:

cd "/…/…/Milano, Torino (Jan)-Compressed"

หากมีการพูดสองครั้งในชื่อไฟล์แล้วหนีด้วย \"


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

@isaaclw นั่นคือเหตุผลที่เขายื่นแบบเป็นเส้นทางที่แน่นอน: P

1
อ่านั่นคือจุดสามจุดที่แสดงโฟลเดอร์ "ตัวแปร" ฉันคิดว่ามันเป็นสองจุดที่ระบุว่า "โฟลเดอร์หลัก" ขอโทษ.
isaaclw

3

ตัวเลือกอื่นแม้ว่าจะไม่ดีที่สุดในกรณีนี้คือการใช้สัญลักษณ์แทน คุณสามารถลอง:

cd *Torino*

เป็นการดีที่สุดที่จะใช้วิธีนี้เมื่อมีคำหรือวลีที่แตกต่างกันในชื่อของไดเรกทอรีที่ไม่ได้แชร์โดยผู้อื่น ตัวอย่างเช่นฉันมีจุดเชื่อมต่อ / สื่อ / DataSSD และ / สื่อ / DataHDD การเติมข้อความอัตโนมัติไม่ทำงานจนกว่าฉันจะพิมพ์ชื่อเกือบครึ่งหนึ่งเพื่อไปที่พาร์ติชัน HDD ของฉันที่ฉันเพิ่งพิมพ์

cd /media/*HD*

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