Znak „^ M” na końcu linii

99

Kiedy uruchamiam określony skrypt SQL w środowiskach Unix, widzę znak „^ M” na końcu każdego wiersza skryptu SQL, który jest powtarzany w wierszu poleceń. Nie wiem, w którym systemie operacyjnym skrypt SQL został pierwotnie utworzony.

Co jest tego przyczyną i jak to naprawić?

Paul Reiners
źródło

Odpowiedzi:

79

Jest to spowodowane znakami końca linii DOS / Windows. Jak powiedział Andy Whitfield, uniksowe polecenie dos2unix pomoże rozwiązać problem. Jeśli chcesz uzyskać więcej informacji, możesz przeczytać strony podręcznika man dla tego polecenia.

Thomas Owens
źródło
3
W niektórych systemach (np. Ubuntu) nazwa tego polecenia to „fromdos”
bobwienholt
6
Możesz bardzo łatwo uzyskać narzędzie na OSX, brew install dos2unixgdy masz zainstalowany homebrew
philipp
73

Napraw zakończenia linii, viwykonując następujące czynności:

:set fileformat=unix

:w

Tim Abell
źródło
2
To świetna odpowiedź. Wielkie dzięki. (zapisano instalację dos2unix, narzędzia, którego prawdopodobnie użyłem tylko raz)
Jamsi,
3
to nie usuwa ^Ms z jakiegoś powodu. Plik referencyjny: /etc/timidity/fluidr3_gm.cfg.
phil294
39

Przyczyną jest różnica między sposobem przechowywania znaczników końca linii przez system operacyjny oparty na systemie Windows i system operacyjny oparty na systemie Unix.

Systemy operacyjne oparte na systemie Windows, dzięki swojemu dziedzictwu w systemie DOS, przechowują koniec wiersza jako parę znaków - 0x0D0A(powrót karetki + nowy wiersz). Systemy operacyjne oparte na Uniksie po prostu używają 0x0A( wysuw wiersza ). To, ^Mco widzisz, jest wizualną reprezentacją 0x0D( powrotu karetki ).

dos2unix pomoże w tym. Prawdopodobnie będziesz musiał także dostosować źródła skryptów, aby były „przyjazne dla Uniksa”.

ColinYounger
źródło
Nie powiedziałbym, że obecne wersje Windows mają jakiekolwiek dziedzictwo DOS . Jednak nadal mają ograniczenia dotyczące kompatybilności.
Joey
Jest to łatwy sposób, jeśli używasz narzędzia do automatycznej konwersji. Dziękuję
Pjl
Ale dlaczego ^M? Dlaczego „^”? Dlaczego „M”?
1737973
Ponieważ jest to „znak kontrolny”. „^” to wizualna reprezentacja kliknięcia klawisza sterującego. Pod jego tylko określonymi bajtami, ^ oznacza ich reprezentację w edytorze.
Hejazzman
24

Najłatwiej jest użyć vi. Wiem, że to brzmi okropnie, ale jest proste i już zainstalowane w większości środowisk UNIX. ^ M to nowa linia ze środowiska Windows / DOS.

z wiersza poleceń: $ vi filename

Następnie naciśnij „ :”, aby przejść do trybu poleceń.

Wyszukaj i zamień wszystko Globalnie to :%s/^M//gNaciśnij i przytrzymaj klawisz Control, a następnie naciśnij V, a następnie M ”, co zastąpi ^ M niczym.

Następnie, aby napisać i wyjść, wpisz „ :wq” Gotowe!

Bernie Perez
źródło
Jak to zamienić w emacsie?
herbertD
Dzięki! VI (M) jest świetny!
Ionică Bizău
3
Dzięki za wyjaśnienie, jak wpisać znak ^ M! Zamiast tego zamieniłbym go na \ r. Tak więc zrobiłem:% s / ^ M / \ r / g
aharris88
13

Spróbuj użyć dos2unix do usunięcia ^ M.

Andy Whitfield
źródło
10

W vi wykonaj a :%s/^M//g

Aby uzyskać ^Mprzytrzymanie CTRLklawisza, naciśnij, Va następnie M(oba trzymając klawisz sterujący), a ^Mpojawi się. Spowoduje to znalezienie wszystkich wystąpień i zastąpienie ich niczym.

dogbane
źródło
2
Aby zamienić ^ M na przyjazny dla unixa podział linii::%s/^M/\r/g
Gary Oak
8

Skrypt SQL został pierwotnie utworzony w systemie operacyjnym Windows. Znaki „^ M” są wynikiem tego, że Windows i Unix mają różne pomysły na temat tego, czego użyć jako znaku końca linii. Możesz użyć perla w wierszu poleceń, aby to naprawić.

perl -pie 's/\r//g' filename.txt
Bill the Lizard
źródło
Jasne, MOŻESZ używać perla, ale czy sugerowałbyś perl zamiast dos2unix?
Thomas Owens,
2
Podaję tylko alternatywę, ponieważ cztery osoby już powiedziały, że używają dos2unix.
Bill the Lizard
2
Tak, uznałem to za przydatne, ponieważ pracuję na zacofanej stacji roboczej w biurze z prehistorycznym działem IT. Z wyjątkiem tego, że użyłem odmiany: perl -pi -e "s / \ x0D / \ n / g" file.csv
Rimian
7

^ M jest zwykle powodowane przez znak nowej linii w systemie Windows i tłumaczone na Uniksa wygląda jak ^ M. Polecenie dos2unix powinno ładnie je usunąć

dos2unix [opcje] [-c convmode] [-o plik ...] [-n plik wyjściowy plik ...]

jW.
źródło
5
C:\tmp\text>dos2unix hello.txt helloUNIX.txt

Sed jest jeszcze szerzej dostępny i może robić tego typu rzeczy także wtedy, gdy dos2unix nie jest zainstalowany

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

Możesz także spróbować tr:

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

Oto wyniki:

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.  
Alex Bolotov
źródło
4

Aby zamienić znaki ^ M w edytorze vi użyj poniżej

otwórz plik tekstowy, powiedz t1.txt

vi t1.txt

Wejdź w tryb poleceń, naciskając shift + :

następnie naciśnij klawisze, jak wspomniano %s/^M/\r/g

in above ^M is not (shift + 6)M instead it is (ctrl + V)(ctrl + M)
leela
źródło
Twoja ostatnia linia jest tym, czego brakowało mi we wszystkich poprzednich odpowiedziach. Ciągle otrzymywałem `` nie znaleziono dopasowań, bc robiłem shift + 6, więc zrobiłem to, co zrobiłby każdy haker i obejrzałem moje nieporozumienie z moim własnym rozwiązaniem: nagraj makro, aby zrobić $, aby przejść do końca każdej linii, a następnie naciśnij x, po prostu powtórz makro dla liczby wierszy w pliku.
darethas
3

Alternatywą dla dos2unixpolecenia byłoby użycie standardowych narzędzi, takich jak sed.

Na przykład dos do unixa:

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

unix do zrobienia:

sed 's/$/\r/' unix.txt > dos.txt
g 4
źródło
1

Możesz usunąć ^ M z plików bezpośrednio poleceniem sed, np .:

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

Jeśli jesteś zadowolony ze zmian, usuń pliki .bak:

rm -v *.bak
kenorb
źródło
0

od -a $file przydaje się do eksplorowania tego typu pytań w Linuksie (podobnie jak dumphex w powyższym).

Allan Wind
źródło
0

W Perlu, jeśli nie chcesz ustawiać zmiennej $ / i używać chomp (), możesz również zrobić:

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

Moje dwa centy

Ariel Monaco
źródło
-1

Kolejne polecenie vi, które zrobi: :%s/.$// usuwa ostatni znak z każdego wiersza w pliku. Wadą tego polecenia wyszukiwania i zamiany jest to, że nie obchodzi go, jaki jest ostatni znak, więc uważaj, aby nie wywołać go dwukrotnie.

Scottie T
źródło
Po co o tym wspominać, jeśli wiesz, że nie jest to wiarygodne?
minexew