Символ '^ M' в конце строк

99

Когда я запускаю конкретный сценарий SQL в средах Unix, я вижу символ «^ M» в конце каждой строки сценария SQL, поскольку он отображается в командной строке. Я не знаю, на какой ОС изначально был создан сценарий SQL.

Что вызывает это и как это исправить?

Пауль Райнерс
источник

Ответы:

79

Это вызвано символами конца строки DOS / Windows. Как сказал Энди Уитфилд, команда dos2unix в Unix поможет решить эту проблему. Если вам нужна дополнительная информация, вы можете прочитать страницы руководства по этой команде.

Томас Оуэнс
источник
3
В некоторых системах (например, Ubuntu) эта команда называется fromdos
bobwienholt
6
Вы можете очень легко получить этот инструмент на OSX, brew install dos2unixкогда у вас установлен homebrew
Филипп
73

Исправьте окончание строки vi, выполнив следующее:

:set fileformat=unix

:w

Тим Абелл
источник
2
Это блестящий ответ. Большое спасибо. (сохранена установка dos2unix, инструмента, который я, вероятно, использовал бы только один раз)
Jamsi
3
^Mпо какой-то причине это не удаляет s. ссылка на файл: /etc/timidity/fluidr3_gm.cfg.
phil294 06
39

Причина в разнице между тем, как ОС на базе Windows и ОС на базе Unix хранят маркеры конца строки.

Операционные системы на базе Windows, благодаря наследию DOS, сохраняют конец строки как пару символов - 0x0D0A(возврат каретки + перевод строки). Операционные системы на основе Unix просто используют 0x0A( перевод строки ). ^MВы видите визуальное представление 0x0Dвозврат каретки ).

dos2unix поможет в этом. Возможно, вам также потребуется настроить источник сценариев, чтобы он был «дружественным к Unix».

ColinYounger
источник
Я бы не сказал, что текущие версии Windows имеют какое-либо наследие DOS . Однако у них все еще есть ограничения совместимости.
Joey
Это простой способ, если вы сделаете инструмент автоматического преобразования. Спасибо
Pjl
Но почему ^M? Почему "^"? Почему «М»?
1737973
Потому что это «управляющий персонаж». «^» - это визуальное представление нажатия клавиши управления. Под его просто конкретными байтами ^ - это то, как редактор представляет их.
Hejazzman 05
24

Самый простой способ - использовать vi. Я знаю, что это звучит ужасно, но это просто и уже установлено в большинстве сред UNIX. ^ M - это новая строка из среды Windows / DOS.

из командной строки: $ vi filename

Затем нажмите « :», чтобы перейти в командный режим.

Искать и заменить все глобально - это :%s/^M//g« Нажмите и удерживайте элемент управления, затем нажмите V, затем M », который заменит ^ M ничем.

Затем, чтобы написать и выйти, введите " :wq" Готово!

Берни Перес
источник
Как заменить его в emacs?
herbertD 01
Спасибо! ВИ (М) отлично!
Ionică Bizău
3
Спасибо за подробное описание того, как вводить символ ^ M! Вместо этого я бы заменил его на \ r. Так я и сделал:% s / ^ M / \ r / g
aharris88
13

Попробуйте использовать dos2unix для удаления ^ M.

Энди Уитфилд
источник
10

В vi выполните :%s/^M//g

Чтобы ^Mудерживать CTRLклавишу, нажмите Vзатем M(оба, удерживая клавишу Control), и ^Mпоявится значок. Это найдет все вхождения и ничего не заменит.

кендырь
источник
2
Чтобы заменить ^ M на разрыв строки, дружественный к unix::%s/^M/\r/g
Gary Oak
8

Скрипт SQL изначально был создан в ОС Windows. Символы '^ M' являются результатом того, что Windows и Unix имели разные представления о том, что использовать для символа конца строки. Вы можете использовать perl в командной строке, чтобы исправить это.

perl -pie 's/\r//g' filename.txt
Билл Ящерица
источник
Конечно, вы МОЖЕТЕ использовать perl, но не могли бы вы предложить perl вместо dos2unix?
Томас Оуэнс,
2
Я просто предлагаю альтернативу, поскольку четыре человека уже сказали использовать dos2unix.
Bill the Lizard
2
Да, я нашел это полезным, потому что я работаю на отсталой рабочей станции в офисе с доисторическим ИТ-отделом. За исключением того, что я использовал вариант: perl -pi -e "s / \ x0D / \ n / g" file.csv
Rimian
7

^ M обычно вызывается оператором новой строки Windows и переводится в Unix выглядит как ^ M. Команда dos2unix должна удалить их красиво

dos2unix [параметры] [-c convmode] [-o файл ...] [-n infile outfile ...]

jW.
источник
5
C:\tmp\text>dos2unix hello.txt helloUNIX.txt

Sed еще более широко доступен и может делать подобные вещи, даже если dos2unix не установлен.

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

Вы также можете попробовать tr:

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

Вот результаты:

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.  
Алексей Болотов
источник
4

Чтобы заменить символы ^ M в редакторе vi, используйте ниже

откройте текстовый файл, скажем t1.txt

vi t1.txt

Войдите в командный режим, нажав shift + :

затем нажмите клавиши, как указано %s/^M/\r/g

in above ^M is not (shift + 6)M instead it is (ctrl + V)(ctrl + M)
Лила
источник
Ваша последняя строка - это то, чего мне не хватало во всех предыдущих ответах. Я продолжал получать 'совпадений не найдено, потому что я делал shift + 6, поэтому я сделал то, что сделал бы каждый хакер, и обошел свое недоразумение своим собственным решением: записал макрос, чтобы сделать $, чтобы перейти в конец каждой строки, а затем нажмите x, просто повторить макрос для количества строк в файле.
darethas
3

Альтернативой dos2unixкоманде может быть использование стандартных утилит, например sed.

Например, dos to unix:

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

unix для dos:

sed 's/$/\r/' unix.txt > dos.txt
g4th
источник
1

Вы можете удалить ^ M из файлов напрямую с помощью команды sed, например:

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

Если вас устраивают изменения, удалите файлы .bak:

rm -v *.bak
Kenorb
источник
0

od -a $file полезен для изучения этих типов вопросов в Linux (аналогично dumphex выше).

Аллан Винд
источник
0

В Perl, если вы не хотите устанавливать переменную $ / и использовать chomp (), вы также можете:

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

Мои два цента

Ариэль Монако
источник
-1

Другая команда vi, которая подойдет: :%s/.$// удаляет последний символ каждой строки в файле. Недостатком этой команды поиска и замены является то, что ей все равно, какой будет последний символ, поэтому будьте осторожны, чтобы не вызывать его дважды.

Скотти Т
источник
Зачем упоминать об этом, если вы знаете, что это ненадежно?
minexew