2008-09-15 42 views
87

Khi tôi chạy tập lệnh SQL cụ thể trong môi trường Unix, tôi thấy ký tự '^ M' ở cuối mỗi dòng của tập lệnh SQL khi nó được lặp lại với dòng lệnh. Tôi không biết trên đó hệ điều hành kịch bản SQL ban đầu được tạo ra.Ký tự '^ M' ở cuối dòng

Điều gì gây ra điều này và làm cách nào để khắc phục sự cố?

Trả lời

68

Đó là do các ký tự dòng kết thúc DOS/Windows. Giống như Andy Whitfield nói, lệnh dos2unix của Unix sẽ giúp khắc phục vấn đề. Nếu bạn muốn biết thêm thông tin, bạn có thể đọc các trang hướng dẫn sử dụng cho lệnh đó.

+3

Trên một số hệ thống (ví dụ: Ubuntu) tên của lệnh này là "fromdos" – bobwienholt

+6

Bạn có thể lấy công cụ trên OSX rất dễ dàng với 'brew install dos2unix' khi bạn đã cài homebrew – philipp

13

Hãy thử sử dụng dos2unix để loại bỏ^M.

7

^M thường được gây ra bởi các toán tử Windows mới, và được dịch lên Unix trông giống như^M. Các dos2unix lệnh nên gỡ bỏ chúng độc đáo

dos2unix [options] [-c convmode] [file -o ...] [-n infile outfile ...]

8

Các kịch bản SQL ban đầu được tạo ra trên Windows Hệ điều hành. Ký tự '^ M' là kết quả của Windows và Unix có những ý tưởng khác nhau về những gì cần sử dụng cho một ký tự cuối dòng. Bạn có thể sử dụng perl tại dòng lệnh để sửa lỗi này.

perl -pie 's/\r//g' filename.txt 
+0

Chắc chắn, bạn CÓ THỂ sử dụng perl, nhưng bạn có gợi ý perl trên dos2unix không? –

+2

Tôi chỉ cung cấp một giải pháp thay thế, vì bốn người đã từng sử dụng dos2unix. –

+2

Có, tôi thấy điều này hữu ích vì tôi đang ở một trạm làm việc lạc hậu làm việc trong một văn phòng với một bộ phận CNTT thời tiền sử. Trừ trường hợp tôi đã sử dụng biến thể: tập tin perl -pi -e "s/\ x0D/\ n/g" .csv – Rimian

9

Trong vi, làm một :%s/^M//g

Để có được ^M giữ CTRL chìa khóa, nhấn V sau đó M (Cả trong khi giữ phím điều khiển) và ^M sẽ xuất hiện. Điều này sẽ tìm thấy tất cả các lần xuất hiện và thay thế chúng bằng không có gì.

+2

Để thay thế^M bằng ngắt dòng thân thiện với nhau: ':% s/^ M/\ r/g' –

39

Nguyên nhân là sự khác biệt giữa cách hệ điều hành dựa trên Windows và hệ điều hành dựa trên Unix lưu trữ các điểm đánh dấu cuối dòng.

Hệ điều hành dựa trên Windows, nhờ di sản DOS của chúng, lưu trữ dòng cuối cùng là một cặp ký tự - 0x0D0A (chuyển dòng + dòng nguồn cấp dữ liệu). Các hệ điều hành dựa trên Unix chỉ sử dụng 0x0A (một line feed). ^M mà bạn đang thấy là hình ảnh trực quan của 0x0D (một carriage return).

dos2unix sẽ trợ giúp việc này. Bạn cũng có thể cần điều chỉnh nguồn của các tập lệnh thành 'thân thiện với Unix'.

+0

Tôi sẽ không nói các phiên bản Windows hiện tại có bất kỳ loại di sản DOS * nào *. Tuy nhiên, họ vẫn có những hạn chế về khả năng tương thích. – Joey

+0

Đây là cách dễ dàng, bạn có thực hiện công cụ chuyển đổi tự động không. Cảm ơn của – peter

+0

Nhưng tại sao '^ M'? Tại sao '^'? Tại sao 'M'? – uprego

24

Cách dễ nhất là sử dụng vi. Tôi biết rằng âm thanh khủng khiếp nhưng đơn giản và đã được cài đặt trên hầu hết các môi trường UNIX.^M là một dòng mới từ môi trường Windows/DOS.

từ dấu nhắc lệnh: $ vi filename

Sau đó nhấn ":" để có được chỉ huy chế độ.

Tìm kiếm và Thay thế tất cả các phạm vi toàn cầu là :%s/^M//g "Bấm và giữ kiểm soát sau đó nhấn V sau đó M" sẽ thay thế^M với không có gì.

Sau đó, để viết và thoát, hãy nhập ":wq" Xong!

+0

Làm thế nào để thay thế nó trong emacs? – herbertD

+0

Cảm ơn! VI (M) thật tuyệt vời! –

+2

Cảm ơn bạn đã mở rộng cách nhập ký tự^M! Thay vào đó, tôi sẽ thay thế nó bằng \ r. Vì vậy, tôi đã làm:% s/^ M/\ r/g – aharris88

-1

Một lệnh vi khác sẽ thực hiện: :%s/.$// Điều này sẽ xóa ký tự cuối cùng của mỗi dòng trong tệp. Nhược điểm của lệnh tìm kiếm và thay thế này là nó không quan tâm đến ký tự cuối cùng là gì, vì vậy hãy cẩn thận không gọi nó hai lần.

+0

Tại sao đề cập đến nó nếu bạn biết nó không đáng tin cậy? – minexew

5
C:\tmp\text>dos2unix hello.txt helloUNIX.txt 

Sed thậm chí còn rộng rãi hơn và có thể làm điều này loại điều còn nếu dos2unix không được cài đặt

C:\tmp\text>sed s/\r// hello.txt > helloUNIX.txt 

Bạn cũng có thể thử tr:

cat hello.txt | tr -d \r > helloUNIX2.txt 

Dưới đây là kết quả :

C:\tmp\text>dumphex hello.txt 
00000000h: 48 61 68 61 0D 0A 68 61 68 61 0D 0A 68 61 68 61 Haha..haha..haha 
00000010h: 0D 0A 0D 0A 68 61 68 61 0D 0A     ....haha.. 

C:\tmp\text>dumphex helloUNIX.txt 
00000000h: 48 61 68 61 0A 68 61 68 61 0A 68 61 68 61 0A 0A Haha.haha.haha.. 
00000010h: 68 61 68 61 0A         haha. 

C:\tmp\text>dumphex helloUNIX2.txt 
00000000h: 48 61 68 61 0A 68 61 68 61 0A 68 61 68 61 0A 0A Haha.haha.haha.. 
00000010h: 68 61 68 61 0A         haha. 
0

od -a $file là hữu ích để khám phá những loại câu hỏi trên Linux (tương tự như dumphex ở trên).

68

kết thúc dòng Fix trong vi bằng cách chạy như sau:

:set fileformat=unix

:w

+2

Đây là một câu trả lời tuyệt vời. Cảm ơn nhiều. (đã lưu cài đặt dos2unix, một công cụ tôi có thể chỉ sử dụng một lần) – Jamsi

+1

+1. Nó thật sạch sẽ. –

+0

Hoạt động hoàn hảo. –

0

Trong Perl, nếu bạn không muốn thiết lập $/biến và sử dụng chomp(), bạn có thể cũng làm:

$var =~ /\r\n//g; 

tôi hai xu

4

Để thay thế^M nhân vật trong sử dụng trình soạn thảo vi dưới đây

mở file văn bản nói t1.txt

vi t1.txt 

Vào chế độ lệnh bằng cách nhấn shift + :

sau đó nhấn phím như đã đề cập %s/^M/\r/g

in above ^M is not (shift + 6)M instead it is (ctrl + V)(ctrl + M) 
+0

Dòng cuối cùng của bạn là những gì tôi đã mất tích từ tất cả các câu trả lời trước đó. Tôi liên tục nhận được 'không có kết quả nào được tìm thấy bc tôi đã làm shift + 6, vì vậy tôi đã làm những gì mọi hacker sẽ và phá vỡ sự hiểu lầm của tôi bằng giải pháp của riêng tôi: ghi lại macro để thực hiện $ để đi đến cuối mỗi dòng và sau đó nhấn x, chỉ cần lặp lại macro cho num của dòng trong tập tin. – darethas

3

Một giải pháp thay thế cho lệnh dos2unix sẽ sử dụng các tiện ích chuẩn e sed.

Ví dụ, dos để unix:

sed 's/\r$//' dos.txt > unix.txt 

unix để dos:

sed 's/$/\r/' unix.txt > dos.txt 
0

Bạn có thể loại bỏ^M từ các tập tin trực tiếp thông qua lệnh sed, ví dụ:

sed -i'.bak' s/\r//g *.* 

Nếu bạn hài lòng với các thay đổi, hãy xóa.file bak:

rm -v *.bak 
Các vấn đề liên quan