grep เพื่อค้นหาไฟล์ที่มี ^ M (Windows carriage return)


72

ฉันใช้ Linux มี pesky ^ M (Windows cariage return) อยู่ที่ไหนสักแห่งที่ซ่อนอยู่ในไฟล์การกำหนดค่าหลายพันไฟล์และฉันต้องหามันเพราะมันทำให้เซิร์ฟเวอร์ล้มเหลว

ฉันจะค้นหา ^ M ในลำดับชั้นไดเรกทอรีที่เต็มไปด้วยไฟล์การกำหนดค่าได้อย่างไร

ฉันคิดว่าฉันไม่สามารถป้อน ^ M บนบรรทัดคำสั่ง bash แต่ฉันมีมันในไฟล์ข้อความที่เรียกว่า m.txt


ที่เกี่ยวข้อง: นำกลับรถในระบบปฏิบัติการยูนิกซ์
40XUserNotFound

windows จะเป็น ^ M ^ J
barlop

3
"ฉันไม่สามารถป้อน ^ M บนบรรทัดคำสั่ง bash" ใช่คุณสามารถ. ลองใช้ control-V Control-M
Hennes

คำตอบ:


91
grep -r $'\r' *

ใช้-rสำหรับการค้นหาแบบเรียกซ้ำและ$''หลบหนีแบบ c ใน Bash

ยิ่งกว่านั้นถ้าคุณแน่ใจว่าเป็นไฟล์ข้อความคุณควรเรียกใช้ไฟล์นั้นอย่างปลอดภัย

tr -d $'\r' < filename

เพื่อลบทั้งหมด\rในไฟล์

หากใช้ GNU sed, -iสามารถดำเนินการแก้ไขในสถานที่ดังนั้นคุณจะไม่จำเป็นต้องเขียนกลับ:

sed $'s/\r//' -i filename

10
@Nicolas: คุณสามารถป้อน ^ M ที่บรรทัดคำสั่งโดยการกด ^ V ^ M $'\r'แต่มันจะดีกว่าที่จะใช้
Dennis Williamson

เยี่ยมมากมันใช้งานได้! ขอบคุณสำหรับเคล็ดลับ ^ V ^ M เช่นกัน :-)
Nicolas Raoul

5
ภายใต้ Cygwin คุณต้องใช้ -U เพื่อทำงานนี้ และ -n จะบอกหมายเลขบรรทัด: grep -r -U -n -e $ '\ r'
Rainer Blome

4
เพิ่ม -l ไปที่คำสั่ง grep เพื่อดูชื่อไฟล์ มิฉะนั้นคุณอาจถูกโจมตีด้วยเส้นที่ตรงกัน
Brendan Byrd

1
@uprego ไม่แน่ใจว่าคุณเข้าใจพวกเขาตอนนี้หรือไม่ แต่ fyi และอื่น ๆ ของการค้นหา$'อ่านตีครั้งแรกใน manpage bash(1)โดยทั่วไปคุณสามารถดูได้ราวกับว่าคุณกำลังเขียนสตริงตัวอักษร C สำหรับcommand < filenameการใช้<หรือ>ที่เรียกว่าการเปลี่ยนเส้นทางนี้เป็นครั้งแรกที่ผมได้เห็นทุกคนเรียกมันว่าการแสดงออกมากขึ้น ค้นหาในREDIRECTION bash(1)
livibetter

12

เมื่อฉันลองฉันสามารถบอกได้ว่ามันทำงานได้ดี แต่เส้นนั้นว่างเปล่า เพิ่มในตัวเลือก:

--color=never

หากคุณได้รับปัญหานี้ฉันคิดว่ามันเป็นตัวละครในการหลบหลีกสำหรับการเน้นสีที่รบกวน\rตัวละคร


2

หากเซิร์ฟเวอร์ของคุณไม่ได้มีเปลือกทุบตีอีกทางเลือกหนึ่งคือการใช้-fตัวเลือกในการรวมกันกับไฟล์ที่เตรียมไว้มีgrep\r

วิธีสร้างไฟล์:

$ echo -ne '\r' > /tmp/cr                    --or--                   $ printf '\r' > /tmp/cr

$ od -c /tmp/cr
0000000  \r
0000001

เพื่อทำการค้นหาอย่างแท้จริง

$ grep -f /tmp/cr *.html *.php *.asp *.whatever

หรือคุณอาจขี้เกียจนิดหน่อยแล้วก็พิมพ์ *

$ grep -f /tmp/cr *

ตัวเลือกถูกใช้เพื่อระบุไฟล์ที่มีรูปแบบให้ตรงกับอย่างใดอย่างหนึ่งต่อบรรทัด ในกรณีนี้มีเพียงรูปแบบเดียว-f filenamegrep


2

หากฉันเข้าใจคำถามของคุณอย่างถูกต้องสิ่งที่คุณต้องการจริงๆคือทำให้มาตรฐานของบรรทัดทั้งหมดเป็นมาตรฐาน Unix LF ( \x0a) ไม่เหมือนกับการลบ CRs ( \x0d) แบบสุ่มสี่สุ่มห้า

หากคุณมีไฟล์ Mac อยู่รอบ ๆ ซึ่งใช้เพียง CR สำหรับการขึ้นบรรทัดใหม่คุณจะทำลายไฟล์เหล่านั้น (ใช่ Mac ควรจะใช้ LF มาเกือบ 20 ปีแล้ว แต่ยังมี (ในปี 2019) แอพ Mac จำนวนมากที่ใช้แค่ CR)

คุณสามารถใช้ Perl ของ\R การหลบหนี LINEBREAKเพื่อแทนที่การเรียงลำดับของการขึ้นบรรทัดใหม่ใด ๆ \nกับ

perl -i.bak -pe 's/\R/\n/g' $your_file

นี้จะเข้ามาแทนที่ในสถานที่จัดเรียงของ LINEBREAK กับใด ๆ\nในการรักษาการสำรองข้อมูลของไฟล์ต้นฉบับใน$your_file${your_file}.bak


1

ในการใช้ grep กับตัวอักษรท้ายบรรทัดฉันคิดว่าคุณต้องบอก grep ว่าไฟล์นั้นเป็นเลขฐานสอง

-l (ตัวอักษร L) ใช้สำหรับพิมพ์เฉพาะชื่อไฟล์

-P สำหรับ perl regexp (ดังนั้น \ x0d จะเปลี่ยนเป็น \ r หรือ ^ M)

grep -l --binary -P '\x0d' *

0

หากคุณใช้ Mac และใช้homebrewคุณสามารถทำได้:

brew install tofrodos
fromdos file.txt

เพื่อลบการรับคืนของ Windows ทั้งหมดออกจากfile.txt

หากต้องการเปลี่ยนกลับเป็น Windows carriage return

todos file.txt

เพื่อค้นหาในโฟลเดอร์และล้างไฟล์ทั้งหมดที่มาจาก dos ให้รันคำสั่งนี้: find -type f -name "* .java" | xargs fromdos
Taiko

0

ในรูปแบบการแสดงออกปกติขึ้นบรรทัดใหม่ต่าง ๆ :

Windows (CR LF)
\r\n

Unix (LF)
\n

เนื่องจาก\r\nลำดับนั้นไม่เหมือนใครฉันคิดว่าคุณน่าจะสามารถค้นหามันได้

เพื่อทำให้สิ่งต่าง ๆ แย่ลง Macs เคยมีเพียง '\ r' แทนที่ newline ฉันไม่สามารถยืนยันสิ่งนี้ได้ แต่ฉันไม่คิดว่ารุ่น MacOSX จะทำสิ่งนั้นได้อีก

Macs รุ่นเก่า (CR)
\r


ในไดเรกทอรีที่มี m.txt grep "\r\n" *จะไม่มีผลลัพธ์ ไม่มีผลอย่างใดอย่างหนึ่งegrep -e "\r\n" *หรือgrep -E "\r\n" *
นิโคลัสราอูล

@ นิโคลัสอาเข้าใจผิด .. คุณหมายถึงซีอาร์เท่านั้นที่\rไม่ดี หน้าต่างขึ้นบรรทัดใหม่เต็มรูปแบบเป็นที่แน่นอน\r\nหรือ CRLF
เจฟฟ์แอด

0

การติดตามคำตอบก่อนหน้านี้วิธีการ 'tr' นั้นดี:

533 $ ถ้า [[-n " tr -cd "\r" <~/.bashrc"]]; จากนั้นเสียงก้อง "DOS"; อื่นสะท้อน "UNIX"; Fi

ยูนิกซ์

534 $ ถ้า [[-n " tr -cd "\r" <dosfile.txt"]]; จากนั้นเสียงก้อง "DOS"; อื่นสะท้อน "UNIX"; Fi

DOS

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