`. []. foo []` ทำอะไรด้วยการทุบตี? ทำไมมันตรงกับ `.. '


16

ดูที่ต่อไปนี้:

$ echo .[].aliases[]
..
$ echo .[].foo[]
..
$ echo .[].[]
..
$ echo .[].xyz[]
..
$ echo .xyz[].xyz[]
.xyz[].xyz[]
$ echo .xyz[].[]
.xyz[].[]

เห็นได้ชัดว่านี่ดูเหมือนจะมีบางสิ่งบางอย่าง แต่ฉันไม่เข้าใจว่าผลลัพธ์มารวมกันได้อย่างไร จากความเข้าใจของฉัน[]เป็นคลาสตัวละครที่ว่างเปล่า มันจะง่ายถ้า

  • มันจับคู่เฉพาะสตริงว่าง ในกรณีนี้ฉันคาดหวังว่า bash จะทำซ้ำทั้งหมดเนื่องจากไม่มีสิ่งใดตรงกับในไดเรกทอรีนี้ แต่ยังจับคู่สิ่งต่าง ๆ เช่น..aliases(ในตัวอย่างแรก)
  • หรือไม่มีอะไรเลย ในกรณีนี้ฉันคาดหวังว่า bash จะทำซ้ำสตริงทั้งหมด

นี่คือกับ GNU bash, รุ่น 4.4.23 (1) - ปล่อย

คำตอบ:


25

ชุด[เริ่มต้น ]ชุดถูกยกเลิกโดย แต่มีวิธีที่จะมี]เป็นส่วนหนึ่งของชุดและนั่นคือการระบุว่า]เป็นตัวอักษรตัวแรก ในขณะที่ชุดที่ว่างเปล่าไม่มีเหตุผลใด ๆ นี่จึงไม่คลุมเครือ

ตัวอย่างของคุณก็คือจุดทั้งหมดตามด้วยชุดที่มีจุดดังนั้นมันจึงตรงกับสองจุด

ตัวอย่างในภายหลังไม่พบไฟล์ใด ๆ ดังนั้นจึงส่งคืนคำต่อคำ


4

เฉพาะสตริงที่ยกมาไม่ได้อยู่ที่ globbing:

$ echo ".[].aliases[]"
.[].aliases[]

แต่สตริงที่ไม่ยกมาอาจมีการโค้ง สตริง unquoted ว่ามี*หรือ?หรือ (ที่ถูกต้อง) [](แสดงออกวงเล็บ) จะได้รับการแก้ไขโดยรายชื่อของไฟล์ที่ตรงกับมัน ในทำนองเดียวกับ a *จะแปลงเป็นไฟล์ทั้งหมดในไดเรกทอรีที่ตรงกันและ a ?จะจับคู่ไฟล์ที่มีอักขระเพียงตัวเดียว a (ที่ถูกต้อง) []จะจับคู่ไฟล์กับอักขระที่อยู่ภายในวงเล็บ จุดเป็นอักขระที่ถูกต้อง:

$ echo a[.]b
a[.]b

$ touch "a.b"
$ echo a[.]b
a.b

เพื่อให้สามารถตรงกับ]มันควรเป็นตัวอักษรตัวแรกในวงเล็บ:

$ touch "a]b"
$ ls a[]]b
a]b

การแสดงออกวงเล็บว่างเปล่าทำให้รู้สึกไม่ (และไม่ได้ขยาย):

$ touch ab
$ ls a[]b
ls: cannot access 'a[]b': No such file or directory

นั่นคือเหตุผลที่ทำงานนี้:

$ touch a]c abc afc azc a:c a?c aoc 
$ ls a[]bfz:?]c
abc  a:c  a?c  a]c  afc  azc

สำหรับ[ความคิดที่คล้ายกัน:

$ touch a[c
$ ls a[[]c
a[c

แต่มันอาจจะอยู่ที่ตำแหน่งใด ๆ ในการแสดงออกวงเล็บ:

$ ls a[]bf[z:?]c
abc  a:c  a?c  a[c  a]c  afc  azc

$ ls a[]bfz:?[]c
abc  a:c  a?c  a[c  a]c  afc  azc

สตริงที่คุณโพสต์.[].foo[]จะตรงกับจุดตามมาด้วยทั้ง]ที่.เป็นfเป็นหรือo [มันคล้ายกับ:

$ echo a[].foo[]c
a[c a]c afc aoc

และจะจับคู่ดังนี้:

$ touch .] .f .o .[ .a .b .z

$ echo .[].foo[]
.. .[ .] .f .o

โปรดทราบว่า..ไม่จำเป็นต้องสร้างรายการไดเรกทอรีเนื่องจากมีอยู่ในทุก ๆ ไดเรกทอรีโดยค่าเริ่มต้น แต่จุดที่เรียบง่าย.จะไม่ถูกจับคู่โดย glob เนื่องจากจะต้องจับคู่อย่างชัดเจน (โดยใช้จุด)

แต่นั่นจะไม่ตรงกัน..aliasesเนื่องจากนิพจน์วงเล็บเหลี่ยมจะจับคู่อักขระเพียงตัวเดียวเท่านั้น ในการจับคู่อักขระหลายตัวคุณต้องใช้*(อะไรก็ได้):

$ touch ..a ..l ..i ..aliases ..alias ..ali
$ echo .[].aliases[]
.. .[ .] .a

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