การจับคู่สตริงที่มีจำนวนอักขระคงที่โดยใช้ grep


9

ฉันพยายามค้นหา6คำศัพท์ที่ใช้grepทั้งหมด ฉันมีสิ่งนี้:

grep "^.\{6\}$" myfile.txt 

étuisแต่ฉันพบว่านอกจากนี้ผมยังได้รับผลเช่น étude,

ฉันสงสัยว่ามันมีบางอย่างเกี่ยวกับสัญลักษณ์ด้านบนeในคำด้านบน

มีสิ่งที่ฉันสามารถทำได้เพื่อให้แน่ใจว่าสิ่งนี้จะไม่เกิดขึ้น?

ขอบคุณสำหรับความช่วยเหลือของคุณ!

คำตอบ:


4

grepความคิดของตัวละครขึ้นอยู่กับสถานที่ หากคุณอยู่ในโลแคลที่ไม่ใช่ Unicode และคุณ grep จากไฟล์ที่มีอักขระ Unicode อยู่การนับจำนวนอักขระจะไม่ตรงกัน หากคุณecho $LANGคุณจะเห็นสถานที่ที่คุณอยู่

หากคุณตั้งค่าตัวแปรสภาพแวดล้อมLC_CTYPEและ / หรือLANGสภาพแวดล้อมเป็นค่าที่ลงท้ายด้วย ".UTF-8" คุณจะได้รับพฤติกรรมที่เหมาะสม:

$ cat data
étuis
letter
éééééé
$ LANG=C grep -E '^.{6}$' data
étuis
letter
$ LANG=en_US.UTF_8 grep -E '^.{6}$' data
letter
éééééé
$

คุณสามารถเปลี่ยนสถานที่ของคุณเพียงคำสั่งเดียวโดยการกำหนดตัวแปรในบรรทัดเดียวกับคำสั่ง

ด้วยการกำหนดค่านี้อักขระหลายไบต์ถือว่าเป็นอักขระเดียว หากคุณต้องการยกเว้นอักขระที่ไม่ใช่ ASCII ทั้งหมดคำตอบอื่น ๆ มีคำตอบสำหรับคุณ


โปรดทราบว่ายังมีความเป็นไปได้ที่สิ่งต่าง ๆ จะแตกหักหรืออย่างน้อยก็ไม่ได้ทำตามที่คุณคาดหวังเมื่อมีตัวละครที่รวมเข้าด้วยกัน คุณgrepอาจปฏิบัติต่อ LATIN เล็ก LETTER E + รวมตัวอักษร ACUTE ข้างต้นแตกต่างจาก LATIN เล็ก LETTER E ด้วย ACUTE


ถ้าคุณใช้.สิ่งที่ต้องการwăsd'sจะตรงกับ
cuonglm

'เป็นอักขระที่สามารถเป็นส่วนหนึ่งของ "สตริงที่มีจำนวนอักขระคงที่"
Michael Homer

อาจจะ. และคุณควรตั้งค่าทั้งสองอย่างLC_CTYPEและLANGบางสิ่งบางอย่างLC_CTYPE=en_US.UTF-8 LANG=en_USจะล้มเหลว ใช้LC_ALLเพื่อความปลอดภัย
cuonglm

2

ลองสิ่งนี้:

LC_ALL=C.UTF-8 grep -x '[_[:alnum:]]\{6\}' file

-xใช้เพื่อจับคู่ทั้งบรรทัดและกำหนดโดย POSIX (ดูgrep )

ดูที่นี่สำหรับคำอธิบายที่ดีเกี่ยวกับสิ่งที่LC_ALLทำ คุณสามารถตั้งค่าLANGหรือLC_CTYPEใช้ utf-8 เพื่อให้มีพฤติกรรมเหมือนกัน สละเพื่อส่งผลกระทบต่อเป็นLC_ALL=> =>LANGLC_CTYPE


2

ด้วย GNU grepเมื่อสร้างด้วยการรองรับ PCRE คุณสามารถทำได้:

grep -Px '\X{6}'

ในขณะที่.ตรงกับตัวละคร\Xตรงกับ ideogram / กราฟ

ในโลแคล UTF-8:

$ locale charmap
UTF-8
$ printf '\u00e9tuis\n\u00e9tudes\n' | grep -Px '\X{6}'
études
$ printf 'e\u0301tuis\ne\u0301tudes\n' | grep -Px '\X{6}'
études

ในหลังétudesนั้นมี 7 ตัวอักษร 8 ไบต์และ 6 กราฟ


ดูเหมือนว่าจะไม่ทำงาน: echo épée | grep -Px '\X{6}'ouputépée
cuonglm

@Gnouc คุณต้องเรียกใช้ใน UTF-8 locale (หากสิ่งที่กล่าวมาéข้างต้นถูกเข้ารหัสเป็น UTF-8)
Stéphane Chazelas

โอ้ความผิดพลาดของฉัน มันทำงานร่วมกับ UTF-8
cuonglm

0

คุณสามารถลองสิ่งที่ชอบ:

grep "^[A-Za-z]\{6\}$" myfile.txt

หรือถ้าคำนั้นอาจมีตัวเลขด้วยเช่นกัน:

grep "^[A-Za-z0-9]\{6\}$" myfile.txt

เพียงเพิ่มอักขระใด ๆ ลงในวงเล็บเหลี่ยมที่คุณต้องการเพิ่มเติม


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