Як дізнатися закінчення рядків у текстовому файлі?


304

Я намагаюся використовувати щось у баші, щоб показати мені закінчення рядків у файлі, надрукованому, а не інтерпретованому. Цей файл - це дамп із SSIS / SQL Server, який читається на машині Linux для обробки.

  • Чи існують які - або перемикачі в межах vi, less, moreі т.д.?

  • Окрім того, щоб побачити закінчення рядків, мені потрібно знати, який тип кінця рядка це ( CRLFабо LF). Як я це дізнаюся?


1
Загальна порада: Якщо ви маєте уявлення про те, яку команду * nix / cygwin ви можете використовувати, ви завжди можете переглянути її сторінку пошуку для пошуку перемикачів, які можуть надати вам потрібну функціональність. Наприклад, man less.
Девід Ріверс

Відповіді:


421

Ви можете скористатися fileутилітою, щоб вказати тип закінчень рядків.

Unix:

$ file testfile1.txt
testfile.txt: ASCII text

"DOS":

$ file testfile2.txt
testfile2.txt: ASCII text, with CRLF line terminators

Для перетворення з "DOS" в Unix:

$ dos2unix testfile2.txt

Для перетворення з Unix в "DOS":

$ unix2dos testfile1.txt

Перетворення вже перетвореного файлу не має ефекту, тому безпечно запускати сліпо (тобто, попередньо не перевіряючи формат), хоча звичайні відмови від відповідальності застосовуються, як завжди.


9
Зараз їх іноді називають відповідно "fromdos" і "todos" (як це відбувається в Ubuntu 10.4+)
Джесс Чадвік,

3
@JessChadwick: Так, але лише у тому випадку, якщо ви явно встановите tofrodosпакунок із sudo apt-get install tofrodos- точно так, як вам доведеться запустити, sudo apt-get install dos2unixщоб отримати dos2unixі unix2dos.
mklement0

Насправді dos2unix не може виконати всю роботу, я думаю, stackoverflow.com/questions/23828554/dos2unix-doesnt-convert-m дає найкращу відповідь
Nathan

@nathan: Що не dos2unixвдається? ОП у цьому питанні лише невиразно описує це питання.
Призупинено до подальшого повідомлення.

Команда файлу @DennisWilliamson до і після команди dos2unix отримала однаковий вихід: xxx.c C джерело, текст ASCII, з термінаторами рядків CR, LF. Я знайшов, що цей файл c має ^ M посередині рядка, який подобається xxxxxxx ^ M xxxxxxx
Натан

127

В vi...

:set list щоб побачити закінчення рядків

:set nolist щоб повернутися до нормального.

Хоча я не думаю, що ви можете бачити \nабо \r\nвходити vi, ви можете бачити, який тип файлу це (UNIX, DOS тощо), щоб зробити висновок про закінчення рядків у ньому ...

:set ff

Як варіант, bashви можете використовувати od -t c <filename>або просто od -c <filename>відображати прибутки.


26
На жаль, я не думаю, що vi може показати цих конкретних персонажів. Ви можете спробувати od -c <ім'я файлу>, який, на мою думку, відобразить \ n або \ r \ n.
Райан Бергер,

3
У категорії "для чого це варто", ви можете привітатись до стилю CRLF Dos, видавши grep --regex = "^ M", де ^ M CTRL + V CTRL + M Ви можете видалити їх, замінивши їх командою sed. Це по суті те саме, що і dos2unix
ковбойдан

11
In vim: :set fileformatповідомить про те, для якого unixабо dosvim вважається закінчення файлу. Ви можете змінити його на :set fileformat=unix.
Віктор Заманян

5
Використовуйте прапор -b під час запуску vi / vim, а потім використовуйте: встановити список, щоб побачити закінчення CR (^ M) та LF ($).
Самуїл

1
@RyanBerger - Схоже, ти пропускаєш -t. Це має бути od -t c file/path, але дякую за нову програму. Працювали чудово!
Ерік Фоссум

113

Ubuntu 14.04:

прості cat -e <filename>роботи просто чудово.

Це відображає закінчення рядків Unix ( \nабо LF) як, $а закінчення рядків Windows ( \r\nабо CRLF) як ^M$.


7
Також працює на OSX. Гарне рішення. Простий і працював для мене, поки прийнятої відповіді не став. (Примітка: не було .txtфайлу)
dlsso

4
чи відображення M $ у всьому заході / вікні?
Том М

Не працює з Соларісом, але людина каже, що це мало б працювати
Зевс

101

У шкаралупі bash спробуйте cat -v <filename>. Це повинно відображати повернення каретки для файлів Windows.

(Це працювало для мене в rxvt через Cygwin на Windows XP).

Примітка редактора: cat -vвізуалізує \r(CR) символи. як ^M. Таким чином, \r\nпослідовності, що закінчуються рядком , відображатимуться як ^Mнаприкінці кожного рядка виводу. cat -eдодатково візуалізує \n, а саме як $. ( cat -etдодатково візуалізує символи вкладок ^I.)


3
@ChrisK: Спробуйте, echo -e 'abc\ndef\r\n' | cat -vі ви повинні побачити ^Mпісля "def".
Призупинено до подальшого повідомлення.

Я хотів дізнатися, чи є у файлі ^ M (Windows / DOS EOL), і лише cat -v мені це показав. +1 для цього
Алі

1
^ M = Стиль DOS / Windows
Меркурій

виправлення: Таким чином, послідовності \ r \ n, що закінчуються рядками, відображатимуться як ^ M $
Шаян

19

Показати CR як ^Mу меншому використанні less -uабо вводити -uодин раз менше, відкрито.

man less каже:

-u or --underline-special

      Causes backspaces and carriage returns to be treated  as  print-
      able  characters;  that  is,  they are sent to the terminal when
      they appear in the input.

1
Будь ласка, уточніть свою відповідь.
adao7000

12

Спробуйте fileпотім file -kпотімdos2unix -ih

fileзазвичай буде достатньо Але для важких випадків спробуйте file -kабо dosunix -ih.

Деталі нижче.


Спробуйте file -k

Коротка версія: file -k somefile.txt скажу.

  • Він виведе with CRLF line endingsдля закінчень рядків DOS / Windows.
  • Він виведе with LF line endingsдля закінчень рядків MAC.
  • А для Linux / Unix рядка "CR" це буде просто вихід text. (Тож якщо в ньому прямо не згадується жоден вид, line endingsто це неявно означає: "Кінцеві рядки закінчення" .)

Довгу версію дивіться нижче.


Приклад реального світу: кодування сертифікатів

Мені іноді доводиться перевіряти це на наявність файлів сертифікатів PEM.

Проблема з регулярними fileполягає в наступному: іноді вони намагаються бути занадто розумними / занадто конкретними.

Спробуємо невелику вікторину: у мене є кілька файлів. І один з цих файлів має різні закінчення рядків. Який?

(До речі: саме так виглядає один із моїх типових каталогів "робота з сертифікатами".)

Спробуємо регулярно file:

$ file -- *
0.example.end.cer:         PEM certificate
0.example.end.key:         PEM RSA private key
1.example.int.cer:         PEM certificate
2.example.root.cer:        PEM certificate
example.opensslconfig.ini: ASCII text
example.req:               PEM certificate request

Ага. Це не говорить мені закінчення рядка. І я вже знав, що це файли cert. Мені не потрібно було "файлу", щоб мені це сказати.

Що ще можна спробувати?

Ви можете спробувати dos2unixз таким --infoперемикачем:

$ dos2unix --info -- *
  37       0       0  no_bom    text    0.example.end.cer
   0      27       0  no_bom    text    0.example.end.key
   0      28       0  no_bom    text    1.example.int.cer
   0      25       0  no_bom    text    2.example.root.cer
   0      35       0  no_bom    text    example.opensslconfig.ini
   0      19       0  no_bom    text    example.req

Отже, це говорить вам про те, що: yup, "0.example.end.cer" повинен бути дивним чоловіком. Але які закінчення рядків існують? Чи знаєте ви напам’ять вихідний формат dos2unix? (Я не.)

Але на щастя, є --keep-going(або -kна короткий час) варіант у file:

$ file --keep-going -- *
0.example.end.cer:         PEM certificate\012- , ASCII text, with CRLF line terminators\012- data
0.example.end.key:         PEM RSA private key\012- , ASCII text\012- data
1.example.int.cer:         PEM certificate\012- , ASCII text\012- data
2.example.root.cer:        PEM certificate\012- , ASCII text\012- data
example.opensslconfig.ini: ASCII text\012- data
example.req:               PEM certificate request\012- , ASCII text\012- data

Відмінно! Тепер ми знаємо, що наш непарний файл має CRLFзакінчення рядка DOS ( ). (І інші файли мають LFзакінчення рядків Unix ( ). Це не явно в цьому висновку. Це неявно. Це просто спосіб fileочікування "звичайного" текстового файлу.)

(Якщо ви хочете поділитися моєю мнемонічністю: "L" - це "Linux" і "LF".)

Тепер давайте перетворимо винуватця і повторимо спробу:

$ dos2unix -- 0.example.end.cer

$ file --keep-going -- *
0.example.end.cer:         PEM certificate\012- , ASCII text\012- data
0.example.end.key:         PEM RSA private key\012- , ASCII text\012- data
1.example.int.cer:         PEM certificate\012- , ASCII text\012- data
2.example.root.cer:        PEM certificate\012- , ASCII text\012- data
example.opensslconfig.ini: ASCII text\012- data
example.req:               PEM certificate request\012- , ASCII text\012- data  

Добре. Тепер усі серти мають закінчення Unix.

Спробуйте dos2unix -ih

Я не знав цього, коли писав приклад вище, але:

Насправді виявляється, що dos2unix дасть вам заголовок, якщо ви використовуєте -ih(короткий для --info=h) такий:

$ dos2unix -ih -- *
 DOS    UNIX     MAC  BOM       TXTBIN  FILE
   0      37       0  no_bom    text    0.example.end.cer
   0      27       0  no_bom    text    0.example.end.key
   0      28       0  no_bom    text    1.example.int.cer
   0      25       0  no_bom    text    2.example.root.cer
   0      35       0  no_bom    text    example.opensslconfig.ini
   0      19       0  no_bom    text    example.req

І ще один "фактично" момент: Формат заголовка запам'ятовується дуже просто: Ось дві мнемоніки:

  1. Це DUMB (зліва направо: d для Dos, u для Unix, m для Mac, b для BOM).
  2. А також: "DUM" - це лише алфавітне впорядкування D, U та M.

Подальше читання


1
Це генерує вихід на зразок: Accounts.java: Java source, ASCII text\012-у Windows в MinTTY
окремо

@standalone: ​​цікаво. Я читав дивні речі про параметр під назвою "igncr" - і те, що ви говорите, звучить так. Але не можу відтворити те, що ви описуєте. (Я спробував усередині Bash inside mintty, що постачається з Git-for-Windows, "git версія 2.24.0.Windows.1".)
StackzOfZtuff

Гм, я спробував file -k Accounts.javaусередині монетного двору, який постачається з git-for-windows, але моя версіяgit version 2.21.0.windows.1
окремо

Робочим рішенням для мене єcat -e file_to_test
самостійно

9

Ви можете використовувати xxdдля показу шістнадцятковий дамп файлу та переходити до символів "0d0a" або "0a".

Ви можете використовувати так, cat -v <filename>як пропонує @warriorpostman.


1
Це працює для мене з cat v 8.23. Кінцеві рядки Unix не надрукують додаткової інформації, але закінчення рядків DOS надрукують "^ M".
Багатий

Це, мабуть, я зіткнувся з 8.21, враховуючи той факт, що я використовую закінчення ліній Unix.
неандерслоб

5

Ви можете використовувати команду todos filenameдля перетворення в закінчення DOS та fromdos filenameдля конвертації в закінчення рядків UNIX. Щоб встановити пакет на Ubuntu, введіть sudo apt-get install tofrodos.


5

Ви можете vim -b filenameредагувати файл у двійковому режимі, де відображатимуться ^ М символів для повернення каретки, а новий рядок вказує на наявність LF, що вказує закінчення рядка Windows CRLF. Під LF я маю на увазі, \nа під CR я маю на увазі \r. Зауважте, що при використанні параметра -b файл завжди буде редагуватися в режимі UNIX за замовчуванням, як зазначено [unix]у рядку стану, тобто, якщо ви додасте нові рядки, вони закінчуються LF, а не CRLF. Якщо ви використовуєте звичайний vim без -b у файлі із закінченнями рядка CRLF, ви повинні побачити, що [dos]показано у рядку стану, а вставлені рядки матимуть CRLF як кінець рядка. Документація VIM для fileformatsналаштування пояснює складності.

Крім того, у мене недостатньо балів, щоб коментувати відповідь Notepad ++, але якщо ви використовуєте Notepad ++ у Windows, використовуйте меню View / Show Symbol / Show End of Line, щоб відобразити CR та LF. У цьому випадку LF показано, тоді як для vim LF позначається новим рядком.


0

Я скидаю свій висновок у текстовий файл. Потім я відкриваю його в блокноті ++ і натискаю кнопку Показати всі символи. Не дуже елегантно, але це працює.


3
Це питання позначено як Linux, і я не думаю, що блокнот ++ призначений для Linux. Це має працювати для Windows.
Рік Сміт

0

Vim - завжди показувати нові рядки для Windows як ^M

Якщо ви хочете завжди бачити нові рядки Windows , в ВІМ візуалізації , як ^Mви можете додати цей рядок в .vimrc:

set ffs=unix

Це дозволить vim інтерпретувати кожен файл, який ви відкриваєте, як файл Unix. Оскільки файли unix мають \nяк символ нового рядка, файл Windows з новим рядком символу \r\nволі все одно буде відображатися належним чином (завдяки \n), але матиме його ^Mв кінці файлу (саме так vim надає \rсимвол).


Vim - інколи показують нові рядки для Windows

Якщо ви хочете просто встановити його на основі файлу, ви можете використовувати його :e ++ff=unixпід час редагування заданого файлу.


Vim - завжди показувати тип файлу ( unixvs dos)

Якщо ви хочете в нижньому рядку Vim завжди відображати те , що FILETYPE ви редагуєте (і ви не примусово встановити тип файлу в UNIX) , ви можете додати в ваш statuslineз
set statusline+=\ %{&fileencoding?&fileencoding:&encoding}.

Нижче наведено мій повний статус. Просто додайте його до свого .vimrc.

" Make statusline stay, otherwise alerts will hide it
set laststatus=2
set statusline=
set statusline+=%#PmenuSel#
set statusline+=%#LineNr#
" This says 'show filename and parent dir'
set statusline+=%{expand('%:p:h:t')}/%t
" This says 'show filename as would be read from the cwd'
" set statusline+=\ %f
set statusline+=%m\
set statusline+=%=
set statusline+=%#CursorColumn#
set statusline+=\ %y
set statusline+=\ %{&fileencoding?&fileencoding:&encoding}
set statusline+=\[%{&fileformat}\]
set statusline+=\ %p%%
set statusline+=\ %l:%c
set statusline+=\ 

Це буде робити, як

.vim/vimrc\                                    [vim] utf-8[unix] 77% 315:6

внизу файлу


Vim - інколи показувати тип файлу ( unixvs dos)

Якщо ви просто хочете побачити, який тип файлу у вас є, ви можете скористатися :set fileformat(це не спрацює, якщо ви змусили встановити тип файлу). Він повернеться unixдля файлів unix та dosдля Windows.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.