อะไรคือความหมายของ [[: space:]] ใน bash?


23

ฉันเพิ่งเจอสคริปต์ทุบตี อะไร[[:space:]]หมายถึงในสคริปต์ทุบตีหรือไม่? ทำไมลำไส้ใหญ่ถึงสองครั้ง?

คำตอบ:


35

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

ตัวอย่างเช่นต่อไปนี้จะจับคู่บรรทัด (เก็บไว้ในบรรทัดตัวแปรเชลล์) หากมีลำดับของอักขระในค่าที่ประกอบด้วยตัวเลขใด ๆ รวมถึงศูนย์ของอักขระเว้นวรรคศูนย์หรือหนึ่งอินสแตนซ์ของ 'a' จากนั้น a 'b':

[[ $line =~ [[:space:]]*?(a)b ]]

... ซึ่งคุณสามารถแยกส่วนที่[[:space:]]ตรงกับ "อักขระช่องว่าง" แต่คุณอาจได้รับการให้อภัยเพราะคิดว่ามันเป็นเพียงอักขระช่องว่างที่แท้จริงและไม่ใช่คลาสทั้งหมดของอักขระซึ่งเป็นสิ่งที่แสดงถึง

หากคุณ (เกิดขึ้นกับ?) ค้นหาสตริง" space"(นั่นคือช่องว่างตามด้วยคำว่า "ช่องว่าง") ในคู่มือทุบตีออนไลน์มี "เฉพาะ" ประมาณ 32 รายการที่ต้องผ่าน เกี่ยวกับหนึ่งในสิบจะอยู่ที่นี่:

ภายใน '[' และ ']' คลาสอักขระสามารถระบุได้โดยใช้ไวยากรณ์ [: class:] โดยที่คลาสเป็นหนึ่งในคลาสต่อไปนี้ที่กำหนดในมาตรฐาน POSIX:

alnum   alpha   ascii   blank   cntrl   digit   graph   lower
print   punct   space   upper   word    xdigit

คลาสอักขระตรงกับอักขระใด ๆ ที่เป็นของคลาสนั้น

ซึ่งจะนำคุณไปสู่มาตรฐาน POSIXซึ่งคุณอาจค้นหาคำว่า "คลาสอักขระ" และค้นหา

wctype, wctype_l - กำหนดคลาสของตัวละครซึ่งจะทำให้คุณได้รับ:

ฟังก์ชั่น wctype () [CX] [ตัวเลือกเริ่ม] และ wctype_l () [ตัวเลือกท้าย] จะกำหนดค่าของ wctype_t ตามกฎของชุดอักขระรหัสที่กำหนดโดยข้อมูลประเภทตัวอักษรในสถานที่ปัจจุบัน [CX] [ตัวเลือกเริ่ม] หรือในโลแคลที่แสดงโดยโลแคล [ตัวเลือกสิ้นสุด] ตามลำดับ (หมวดหมู่ LC_CTYPE)

หากคุณติดตามลิงก์setlocaleในที่สุดคุณจะได้รับคำตอบที่แท้จริงในส่วน Locale :

ช่องว่าง

กำหนดอักขระที่จะจัดประเภทเป็นอักขระช่องว่าง ในสถานที่เกิดเหตุ<space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>จะต้องรวมอย่างแน่นอน

ในไฟล์นิยามโลแคลจะไม่มีการระบุอักขระสำหรับคีย์เวิร์ด upper, lower, alpha, digit, graph หรือ xdigit <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>ของชุดอักขระแบบพกพาและตัวอักษรใด ๆ รวมอยู่ในชั้นว่างเปล่ามีอยู่โดยอัตโนมัติในชั้นนี้


1
ค้นหาการจับคู่ด้วยตนเองได้ง่ายขึ้นLESS=+'/Within \[ and \],' man bashแทนที่จะใช้nคำสั่ง ext 32 คำ :-)
ไอแซค

5
@Issa ฉันคิดว่าประเด็นคือการสอนให้คนรู้วิธีการตกปลา ที่กล่าวว่าฉันไม่ทราบless +"$cmd"ดังนั้นขอขอบคุณสำหรับการที่
JoL

3
แน่นอนฉันตอบด้วยมุมมองของ OP; พวกเขาจะได้รับการอภัยไม่ได้หยิบขึ้นมาที่ด้านนอกเป็นอิสระจากภายใน[] []ฉันพยายาม (!) เพื่อหาวิธีจากคำถามไปยังคำตอบโดยไม่รู้ตัวมากเกินไปเกี่ยวกับสิ่งที่คำตอบคือแม้ว่ามันจะเดาโชคดี :)
เจฟ Schaller

17

มันไม่เพียง แต่สำหรับทุบตีมันเป็นส่วนหนึ่งของสัญกรณ์ POSIX

POSIX คืออะไร

POSIX หรือ "Portable Operating System Interface สำหรับ uniX" เป็นชุดของมาตรฐานที่กำหนดฟังก์ชันการทำงานบางอย่างที่ระบบปฏิบัติการ (UNIX) ควรสนับสนุน หนึ่งในมาตรฐานเหล่านี้กำหนดนิพจน์ปกติสองรสชาติ

นิพจน์ POSIX Bracket

นิพจน์วงเล็บเหลี่ยม POSIX เป็นคลาสอักขระชนิดพิเศษ นิพจน์วงเล็บเหลี่ยม POSIX จับคู่อักขระหนึ่งตัวจากชุดอักขระเช่นเดียวกับคลาสอักขระปกติ

POSIX มาตรฐาน

[[:alnum:]]   Alphanumeric characters
[[:alpha:]]   Alphabetic characters
[[:blank:]]   Space and tab
[[:cntrl:]]   Control characters
[[:digit:]]   Digits
[[:graph:]]   Visible characters (anything except spaces and control characters)
[[:lower:]]   Lowercase letters
[[:print:]]   Visible characters and spaces (anything except control characters)
[[:punct:]]   Punctuation (and symbols).
[[:space:]]   All whitespace characters, including line breaks
[[:upper:]]   Uppercase letters
[[:xdigit:]]  Hexadecimal digits

ไม่มีมาตรฐาน

[[:ascii:]]   ASCII characters
[[:word:]]    Word characters (letters, numbers and underscores)

ไวยากรณ์ดั้งเดิม (ใครบางคนสามารถค้นหาการอ้างอิงถึงสิ่งเหล่านี้ได้หรือไม่)

[[:<:]]       Start of Word 
[[:>:]]       End of Word

คุณสามารถค้นหาข้อมูลเพิ่มเติมได้ที่นี่: วิกิ


1
[[:ascii:]]และ[[:word:]]ไม่ใช่คลาส POSIX (ดูเหมือนว่าจะเป็นbashเฉพาะ) และฉันไม่สามารถค้นหา[[:<:]]หรือ[[:>:]]ไม่ การอ้างอิงที่ดีกว่าอาจเป็นpubs.opengroup.org/onlinepubs/9699919799/basedefs/ …
Kusalananda

1
ใช่[[:ascii:]]และ[[:word:]]ไม่มีคลาส POSIX มาตรฐาน สำหรับ[[:<:]]และ[[:>:]]ผมไม่สามารถหาอ้างอิงใด ๆ \bแต่มันก็เป็นเหมือนกัน en.wikipedia.org/wiki/Regular_expression#Character_classes
Nima


[[:<:]]อยู่ใน FreeBSD ด้วยเช่นเดียวกันกับข้อแม้ของ PostgreSQL มีดังนี้: freebsd.org/cgi/…
ilkkachu

1
และ[[:ascii:]]และ[[:word:]]การทำงานของหลักสูตรในการทุบตีในการจับคู่แบบ แต่ไม่ได้อยู่ในการแสดงออกปกติ (อย่างน้อยในระบบของฉันฉันคิดว่าทุบตีใช้ห้องสมุด regex ระบบ) Bah
ilkkachu

9

ในนิพจน์ทั่วไปและชื่อไฟล์ globs / shell pattern [...]โครงสร้างตรงกับอักขระหนึ่งตัวของรายการที่อยู่ในวงเล็บ ภายในวงเล็บเหล่านั้นสามารถใช้คลาสอักขระอักขระมาตรฐานที่มีชื่อจำนวนหนึ่งได้ หนึ่งในนั้นคือ[:space:]ซึ่งตรงกับตัวละครช่องว่าง (เช่น\sใน Perl regexes) ดูเช่นการจับคู่รูปแบบในคู่มือของ Bash

ดังนั้น[[:space:]]เป็นส่วนหนึ่งของการจับคู่การแสดงออกหรือรูปแบบปกติหนึ่งที่ตรงกับเพียงแค่ช่องว่าง

เช่นการจับคู่รูปแบบ (เชลล์มาตรฐานไม่ใช่ Bash-specific):

case $var in 
    *[[:space:]]*) echo "'$var' contains whitespace";;
esac

หรือ regex (Bash):

if [[ $var =~ [[:space:]] ]]; then
    echo "'$var' contains whitespace"
fi

โปรดทราบว่าแม้ว่านิพจน์วงเล็บเหลี่ยมจะ[...]ทำงานเหมือนกันในนิพจน์ทั่วไปและรูปแบบเชลล์ แต่โดยทั่วไปแล้วจะไม่เหมือนกันมาก ( caseและ[[ string == pattern ]]ใช้รูปแบบที่ตรงกัน[[ string =~ regex ]]ใช้ regexes)

การแสดงออกปกติยังไม่ได้เปลือกเฉพาะที่พวกเขากำลังที่ใช้ในการเช่นawkและsedมากเกินไปและมีการอธิบายไว้ในเช่นหน้าคนลินุกซ์regex(7)

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