วิธีที่สวยงามในการค้นหาไฟล์ UTF-8 ด้วย BOM?


94

สำหรับวัตถุประสงค์ในการดีบักฉันจำเป็นต้องค้นหาไดเร็กทอรีซ้ำสำหรับไฟล์ทั้งหมดที่ขึ้นต้นด้วยเครื่องหมายคำสั่งไบต์ UTF-8 (BOM) โซลูชันปัจจุบันของฉันคือเชลล์สคริปต์แบบธรรมดา:

find -type f |
while read file
do
    if [ "`head -c 3 -- "$file"`" == $'\xef\xbb\xbf' ]
    then
        echo "found BOM in: $file"
    fi
done

หรือหากคุณต้องการหนึ่งบรรทัดสั้น ๆ ที่อ่านไม่ได้:

find -type f|while read file;do [ "`head -c3 -- "$file"`" == $'\xef\xbb\xbf' ] && echo "found BOM in: $file";done

ใช้ไม่ได้กับชื่อไฟล์ที่มีตัวแบ่งบรรทัด แต่ไม่ควรคาดหวังไฟล์ดังกล่าว

มีวิธีแก้ปัญหาที่สั้นกว่าหรือสวยงามกว่านี้ไหม?

มีโปรแกรมแก้ไขข้อความหรือมาโครที่น่าสนใจสำหรับโปรแกรมแก้ไขข้อความหรือไม่?

คำตอบ:


167

แล้วคำสั่งง่ายๆที่ไม่เพียงแค่ค้นหา แต่ยังล้าง BOM ที่น่ารังเกียจ? :)

find . -type f -exec sed '1s/^\xEF\xBB\xBF//' -i {} \;

ฉันชอบ "ค้นหา" :)

คำเตือนข้างต้นจะแก้ไขไฟล์ไบนารีที่มีอักขระสามตัวดังกล่าว

หากคุณต้องการเพียงแค่แสดงไฟล์ BOM ให้ใช้ไฟล์นี้:

grep -rl $'\xEF\xBB\xBF' .

9
ตรวจพบ PDF ที่มีเครื่องหมาย BOM ไม่ถูกต้อง .. นั่นเป็นเพราะมันค้นหาเอกสารทั้งหมดไม่ใช่แค่บรรทัดแรก
Olivier Refalo

1
หรือด้วย ack: "ack '\ xEF \ xBB \ xBF'"
Smar

5
เปลี่ยนคำสั่ง sed เพื่อเพิ่ม 1 ก่อนหน้า 's' ดังนั้นจึงใช้กับบรรทัดแรกเท่านั้น
Ben Combee

27
ใช้grep -rlI $'\xEF\xBB\xBF' .เพื่อละเว้นไฟล์ไบนารี
dbernard

1
ตรวจจับและแก้ไข JPG และไฟล์ไบนารีอื่น ๆ ตามที่กล่าวไปแล้ว
Jehy

41

วิธีที่ดีที่สุดและง่ายที่สุดใน Windows:

Total Commander →ไปที่ root dir ของโปรเจ็กต์→ค้นหาไฟล์ ( Alt+ F7) →ประเภทไฟล์ *. * →ค้นหาข้อความ "EF BB BF" →เลือกช่องทำเครื่องหมาย 'Hex' →ค้นหา

และคุณจะได้รับรายชื่อ :)


4
ดีโดยเฉพาะอย่างยิ่งการใช้ Total Commander ที่ฉันชอบมานาน แต่น่าเสียดายที่ปัญหานี้ประสบปัญหาเดียวกันกับคนอื่น ๆ อีกมากมาย: ค้นหาไบต์ทั้งหมดในหมัดดังนั้นจึงมีการรายงานรูปภาพจำนวนมาก ฯลฯ สิ่งนี้สามารถปรับปรุงได้เล็กน้อยโดยใช้ RegEx แทน Hex และค้นหา "^ \ xEF \ xBB \ xBF" ซึ่งจะกำจัดภาพจำนวนมาก แต่ยังมีไฟล์ที่มี BOM อยู่ครึ่งทางของไฟล์ (แม้ว่าจะมีน้อย) และแน่นอน ไฟล์ไบนารีใด ๆ ที่มี Charcode ascii newline เพียงแค่ BOM เท่านั้น ถึงกระนั้นภาพทั้งหมดก็หายไปในการค้นหาทดสอบของฉัน
Legolas

13
find . -type f -print0 | xargs -0r awk '
    /^\xEF\xBB\xBF/ {print FILENAME}
    {nextfile}'

โซลูชันส่วนใหญ่ที่ให้ไว้ข้างต้นจะทดสอบมากกว่าบรรทัดแรกของไฟล์แม้ว่าจะมีบางส่วน (เช่นโซลูชันของ Marcus) ก็กรองผลลัพธ์ โซลูชันนี้จะทดสอบเฉพาะบรรทัดแรกของแต่ละไฟล์ดังนั้นจึงควรเร็วกว่าเล็กน้อย


1
Got กำลังทำงานกับสิ่งต่อไปนี้บน Linux (RHEL6) -find . -type f -print0 | xargs -0 awk '/^\xEF\xBB\xBF/ {print FILENAME} {nextfile}'
Olivier Refalo

ฉันจะต้องแก้ไขโค้ดของคุณอย่างไรเพื่อแก้ไขไฟล์เหล่านี้หลังจากที่พบ
Black

7

หากคุณยอมรับผลบวกเท็จ (ในกรณีที่มีไฟล์ที่ไม่ใช่ข้อความหรือในกรณีที่ไม่น่าจะมี ZWNBSP อยู่ตรงกลางไฟล์) คุณสามารถใช้ grep:

fgrep -rl `echo -ne '\xef\xbb\xbf'` .

5

ฉันจะใช้สิ่งที่ชอบ:

grep -orHbm1 "^`echo -ne '\xef\xbb\xbf'`" . | sed '/:0:/!d;s/:0:.*//'

ซึ่งจะช่วยให้มั่นใจได้ว่า BOM เกิดขึ้นโดยเริ่มจากไบต์แรกของไฟล์


5

คุณสามารถใช้grepเพื่อค้นหาพวกมันและ Perl เพื่อตัดออกได้ดังนี้:

grep -rl $'\xEF\xBB\xBF' . | xargs perl -i -pe 's{\xEF\xBB\xBF}{}'

อันนี้ใช้ได้ผลสำหรับฉันคำตอบที่ยอมรับไม่ได้ (ฉันใช้ Mac)
mjsarfatti

4

สำหรับผู้ใช้ Windows โปรดดูสิ่งนี้ (สคริปต์ PHP ที่ดีสำหรับการค้นหาBOMในโครงการของคุณ)


เว็บไซต์ที่เชื่อมโยงจะแสดง: "เว็บไซต์ออฟไลน์ไม่มีเวอร์ชันแคช"
vog

สคริปต์เดียวกันนี้ยังมีอยู่ใน github: github.com/emrahgunduz/BomCleaner
emrahgunduz

ขอบคุณเพื่อนคำตอบของคุณบันทึกวันของฉัน
Krunal Panchal

และ BOM Finder: github.com/svn2github/wikia/blob/master/extensions/FCKeditor/… (ในกรณีที่มีคนไม่ชอบการทำความสะอาดแบบ 'อัตโนมัติ' หรือเพียงแค่ต้องการค้นหาไฟล์ด้วย BOM)
meloniq

3

วิธีแก้ปัญหามากเกินไปคือphptags(ไม่ใช่viเครื่องมือที่มีชื่อเดียวกัน) ซึ่งมองหาสคริปต์ PHP โดยเฉพาะ:

phptags --warn ./

จะแสดงผลลัพธ์ดังนี้:

./invalid.php: TRAILING whitespace ("?>\n")
./invalid.php: UTF-8 BOM alone ("\xEF\xBB\xBF")

และ--whitespaceโหมดนี้จะแก้ไขปัญหาดังกล่าวโดยอัตโนมัติ (เรียกซ้ำ แต่ยืนยันว่าจะเขียนสคริปต์. php เท่านั้น)


2
find -type f -print0 | xargs -0 grep -l `printf '^\xef\xbb\xbf'` | sed 's/^/found BOM in: /'
  • find -print0 ใส่ null \ 0 ระหว่างชื่อไฟล์แต่ละชื่อแทนที่จะใช้บรรทัดใหม่
  • xargs -0 คาดหวังอาร์กิวเมนต์ที่คั่นด้วยค่าว่างแทนการแยกบรรทัด
  • grep -l แสดงรายการไฟล์ที่ตรงกับนิพจน์ทั่วไป
  • regex ^\xeff\xbb\xbfไม่ถูกต้องทั้งหมดเนื่องจากจะจับคู่ไฟล์ UTF-8 ที่ไม่ใช่ BOMed หากมีช่องว่างความกว้างเป็นศูนย์ที่จุดเริ่มต้นของบรรทัด

คุณยังต้องมี "หัว 1" ในท่อก่อน grep
MSalters

2

ฉันใช้สิ่งนี้เพื่อแก้ไขไฟล์ JavaScript เท่านั้น:

find . -iname *.js -type f -exec sed 's/^\xEF\xBB\xBF//' -i.bak {} \; -exec rm {}.bak \;

0

หากคุณกำลังมองหาไฟล์ UTF คำสั่ง file จะใช้งานได้ มันจะบอกว่าการเข้ารหัสของไฟล์คืออะไร หากมีอักขระที่ไม่ใช่ ASCII อยู่ในนั้นจะมี UTF

file *.php | grep UTF

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

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