(grep) Regex จับคู่อักขระที่ไม่ใช่ ASCII หรือไม่


169

บน Linux ฉันมีไดเรกทอรีที่มีไฟล์จำนวนมาก บางคนมีอักขระที่ไม่ใช่ ASCII แต่พวกเขาจะถูกต้องทั้งหมดUTF-8 โปรแกรมหนึ่งมีข้อบกพร่องที่ป้องกันไม่ให้ทำงานกับชื่อไฟล์ที่ไม่ใช่ ASCII และฉันต้องค้นหาว่ามีผลกระทบกับจำนวนเท่าใด ฉันจะทำสิ่งนี้ด้วยfindแล้วทำgrepเพื่อพิมพ์อักขระที่ไม่ใช่ ASCII จากนั้นทำ a wc -lเพื่อค้นหาตัวเลข มันไม่จำเป็นต้องเป็น grep ฉันสามารถใช้นิพจน์ทั่วไปของ Unix มาตรฐานเช่นPerl , sed , AWKเป็นต้น

อย่างไรก็ตามมีการแสดงออกปกติสำหรับ 'ตัวละครที่ไม่ใช่ตัวอักษร ASCII' หรือไม่?


1
พอลใช่ฉันสามารถใช้ Perl
Rory

/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]
Tinmarino

คำตอบ:


310

สิ่งนี้จะตรงกับอักขระที่ไม่ใช่ ASCII ตัวเดียว:

[^\x00-\x7F]

นี่เป็นPCRE ที่ถูกต้อง( นิพจน์ปกติที่เข้ากันได้กับ Perl )

คุณยังสามารถใช้POSIXชวเลข:

  • [[:ascii:]] - จับคู่อักขระ ASCII เดียว
  • [^[:ascii:]] - ตรงกับอักขระที่ไม่ใช่ ASCII ตัวเดียว

[^[:print:]] อาจจะพอเพียงสำหรับคุณ **


3
@adrianm: ไม่^ถูกต้องใน PCRE
Alix Axel

10
ถูกต้องแล้ว อย่างไรก็ตามคุณต้องใช้ pcregrep ไม่ใช่ grep มาตรฐาน [^ [: print:]] จะไม่ทำงานหากเทอร์มินัลของคุณตั้งค่าเป็น UTF8
โรรี่

@ รูรี่ทำไม:print:จะไม่ทำงานในเทอร์มินัล UTF8 สิ่งนี้ใช้ได้กับฉันในแงะในเทอร์มินัล UTF8:27.chr =~ /[^[:print:]]/
akostadinov

นี่เป็นสิ่งที่ดีสำหรับการแก้ไขชื่อไฟล์ที่ไม่ดี - rename 's/[^\x00-\x7F]//g' *(คุณสามารถใช้-nเพื่อตรวจสอบการเปลี่ยนชื่อได้ก่อน)
naught101

ฉันจะจับคู่อักขระใด ๆ ที่ไม่ใช่ UTF8 และอักขระอื่น ๆ ได้อย่างไร
CMCDragonkai

37

ไม่[^\x20-\x7E]ไม่ใช่ ASCII

นี่คือ ASCII จริง:

 [^\x00-\x7F]

มิฉะนั้นจะตัดแต่งบรรทัดใหม่และอักขระพิเศษอื่น ๆ ที่เป็นส่วนหนึ่งของตาราง ASCII!



3

[^\x00-\x7F]และ[^[:ascii:]]พลาดไบต์ควบคุมบางส่วนเพื่อให้สตริงเป็นตัวเลือกที่ดีกว่าในบางครั้ง ตัวอย่างเช่นcat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g'จะทำสิ่งที่แปลกไปยังสถานีของคุณที่strings test.torrentจะทำหน้าที่





2

คุณไม่ต้องการ regex

printf "%s\n" *[!\ -~]*

นี่จะแสดงชื่อไฟล์ที่มีอักขระควบคุมในชื่อของพวกเขาเช่นกัน แต่ฉันคิดว่าเป็นคุณลักษณะ

หากคุณไม่มีไฟล์ที่ตรงกันใด ๆ glob จะขยายไปสู่ตัวเองยกเว้นว่าคุณได้nullglobตั้งค่าไว้ (นิพจน์ไม่ตรงกับตัวเองดังนั้นในทางเทคนิคแล้วเอาต์พุตนี้ไม่คลุมเครือ)


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

1

สิ่งนี้กลายเป็นความยืดหยุ่นและขยายได้มาก $ field = ~ s / [^ \ x00- \ x7F] // g; # ดังนั้นจึงสามารถล้างข้อมูลทั้งหมดที่ไม่ใช่ ASCII หรือรายการที่เป็นปัญหาได้ ดีมากในการเลือกหรือการประมวลผลล่วงหน้าของรายการที่จะกลายเป็นกุญแจแฮช

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