Jak znaleźć zakończenia linii w pliku tekstowym?

304

Próbuję użyć czegoś w bash, aby pokazać mi zakończenia linii w pliku drukowanym, a nie interpretowanym. Plik jest zrzutem z SSIS / SQL Server wczytywanego przez maszynę z systemem Linux do przetwarzania.

  • Czy są jakieś przełączniki odległości vi, less, moreitp?

  • Oprócz zobaczenia końca linii, muszę wiedzieć, jaki to typ końca linii ( CRLFlub LF). Jak się tego dowiem?

Marco Ceppi
źródło
1
Porada ogólna: jeśli masz pomysł, którego polecenia * nix / cygwin możesz użyć, zawsze możesz wyświetlić jego stronę podręczną, aby wyszukać przełączniki, które mogą zapewnić ci potrzebną funkcjonalność. Np man less.
David Rivers,

Odpowiedzi:

421

Możesz użyć tego filenarzędzia, aby wskazać rodzaj zakończeń linii.

Unix:

$ file testfile1.txt
testfile.txt: ASCII text

„DOS”:

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

Aby przekonwertować z „DOS” na Unix:

$ dos2unix testfile2.txt

Aby przekonwertować z Uniksa na „DOS”:

$ unix2dos testfile1.txt

Konwersja już przekonwertowanego pliku nie ma wpływu, więc można bezpiecznie uruchamiać na ślepo (tj. Bez uprzedniego przetestowania formatu), jak zwykle jednak obowiązują zwykłe zastrzeżenia.

Wstrzymano do odwołania.
źródło
9
Są one teraz czasami nazywane odpowiednio „fromdos” i „todos” (jak ma to miejsce w Ubuntu 10.4+)
Jess Chadwick,
3
@JessChadwick: Tak, ale tylko w przypadku jawnej instalacji tofrodospakietu za pomocą sudo apt-get install tofrodos- tak jak trzeba by uruchomić i sudo apt-get install dos2unixuzyskać . dos2unixunix2dos
mklement0
Actully dos2unix nie jest w stanie wykonać całej pracy, myślę, że stackoverflow.com/questions/23828554/dos2unix-doesnt-convert-m daje najlepszą odpowiedź
nathan
@nathan: W czym dos2unixzawodzi? OP na to pytanie tylko niejasno opisuje ten problem.
Wstrzymano do odwołania.
Komenda @DennisWilliamson przed i po komendzie dos2unix otrzymała to samo wyjście: xxx.c Źródło C, tekst ASCII, z terminatorami linii CR, LF. Znalazłem ten plik c ma ^ M pośrodku linii, która lubi xxxxxxx ^ M xxxxxxx
nathan
127

W vi...

:set list aby zobaczyć zakończenia linii.

:set nolist wrócić do normalności.

Chociaż nie sądzę, można zobaczyć, \nczy \r\nw vimożna zobaczyć, jaki typ pliku jest (UNIX, DOS, itd.), Aby wnioskować, która linia ma zakończenia ...

:set ff

Alternatywnie, ze bashmożna użyć od -t c <filename>albo tylko od -c <filename>do wyświetlania powraca.

Ryan Berger
źródło
26
Niestety nie sądzę, że vi może pokazywać te konkretne postacie. Możesz spróbować od -c <nazwa_pliku>, który moim zdaniem wyświetli \ n lub \ r \ n.
Ryan Berger,
3
W kategorii „za co warto” możesz grep dla CRLF w stylu Dos, wydając grep --regex = „^ M”, gdzie ^ M to CTRL + V CTRL + M. Możesz je usunąć, zastępując je poleceniem sed. Robi to w zasadzie to samo, co dos2unix
cowboydan
11
W vim: :set fileformatpoinformuje, który z nich unixlub dosvim uważa, że ​​kończą się wiersze pliku. Możesz to zmienić :set fileformat=unix.
Victor Zamanian
5
Użyj flagi -b podczas uruchamiania vi / vim, a następnie użyj: ustaw listę, aby zobaczyć zakończenia CR (^ M) i LF ($).
Samuel
1
@RyanBerger - Wygląda na to, że brakuje Ci -t. Tak powinno być od -t c file/path, ale dzięki za nowy program. Działa świetnie!
Eric Fossum,
113

Ubuntu 14.04:

proste cat -e <filename>działa dobrze.

Wyświetla zakończenia linii Unix ( \nlub LF) jako $i zakończenia linii Windows ( \r\nlub CRLF) jako ^M$.

Alexander Shelemin
źródło
7
Działa również na OSX. Dobre rozwiązanie. Proste i działało dla mnie, podczas gdy zaakceptowana odpowiedź nie. (Uwaga: nie był .txtplikiem)
dlsso
4
czy wyświetlanie M $ jest wschodnie / Windows bashing?
Tom M
Nie działa z Solaris, ale człowiek mówi, że powinien był działać
Zeus
101

W powłoce bash spróbuj cat -v <filename>. To powinno wyświetlać znaki powrotu karetki dla plików Windows.

(To działało dla mnie w rxvt przez Cygwin na Windows XP).

Nota edytora: cat -vwizualizuje \rznaki (CR). jak ^M. Zatem \r\nsekwencje kończące linię będą wyświetlane jak ^Mna końcu każdej linii wyjściowej. cat -edodatkowo wizualizuje \n, a mianowicie jako $. ( cat -etdodatkowo zwizualizuje tabulatory. as ^I.)

warriorpostman
źródło
3
@ChrisK: Spróbuj echo -e 'abc\ndef\r\n' | cat -vi powinieneś zobaczyć napis ^Mpo „def”.
Wstrzymano do odwołania.
Chciałem sprawdzić, czy plik ma ^ M (Windows / DOS EOL) i pokazał mi to tylko cat -v. +1 za to
Ali
1
^ M = styl DOS / Windows
Mercury
korekta: Tak więc sekwencje kończące \ r \ n będą wyświetlane jako ^ M $
Shayan
19

Aby pokazać CR jako ^Mmniej używany less -ulub wpisz -uraz, gdy mniej jest otwarte.

man less mówi:

-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.
P. Kucerak
źródło
1
Proszę wyjaśnić swoją odpowiedź.
adao7000,
12

Spróbuj filewtedy file -knastępniedos2unix -ih

filezwykle wystarczy. Ale w trudnych przypadkach spróbuj file -klub dosunix -ih.

Szczegóły poniżej.


Próbować file -k

Krótka wersja: file -k somefile.txt powie ci.

  • Będzie wyświetlać with CRLF line endingsdla zakończeń linii DOS / Windows.
  • Będzie wyświetlać with LF line endingsdla zakończeń linii MAC.
  • A dla linii CR / Linux / Unix zostanie po prostu wyprowadzony text. (Jeśli więc nie wspomina o żadnym rodzaju, line endingsoznacza to domyślnie: „Zakończenia linii CR” .)

Wersja długa patrz poniżej.


Przykład ze świata rzeczywistego: kodowanie certyfikatów

Czasami muszę to sprawdzić w przypadku plików certyfikatów PEM.

Problem ze zwykłym filejest taki: Czasami stara się być zbyt mądry / zbyt konkretny.

Spróbujmy małego quizu: Mam trochę plików. Jeden z tych plików ma różne zakończenia linii. Który?

(Przy okazji: tak wygląda jeden z moich typowych katalogów „praca z certyfikatami”).

Spróbujmy regularnie 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

Huh To nie mówi mi o zakończeniu linii. I już wiedziałem, że to były pliki cert. Nie potrzebowałem „pliku”, żeby mi to powiedzieć.

Co jeszcze możesz spróbować?

Możesz spróbować dos2unixz takim --infoprzełącznikiem:

$ 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

To mówi ci, że: tak, „0.example.end.cer” musi być dziwnym mężczyzną. Ale jakie są zakończenia linii? Czy ty wiesz, format wyjściowy dos2unix na pamięć? (Ja nie.)

Ale na szczęście jest opcja --keep-going(lub -kw skrócie) w 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

Świetny! Teraz wiemy, że nasz nieparzysty plik ma CRLFzakończenia linii DOS ( ). (A inne pliki mają LFkońcówki wiersza Unix ( ). Nie jest to jednoznaczne na tym wyjściu. Jest niejawne. Po prostu fileoczekuje się, że będzie to „zwykły” plik tekstowy.)

(Jeśli chcesz podzielić się moim mnemonikiem: „L” oznacza „Linux” i „LF”.)

Teraz przekonwertujmy winowajcę i spróbuj ponownie:

$ 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  

Dobrze. Teraz wszystkie certyfikaty mają zakończenia linii Uniksa.

Próbować dos2unix -ih

Nie wiedziałem tego, pisząc powyższy przykład, ale:

Okazuje się, że dos2unix da ci nagłówek, jeśli użyjesz -ih(skrót od --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

I jeszcze jeden „faktyczny” moment: format nagłówka jest naprawdę łatwy do zapamiętania: oto dwie mnemoniki:

  1. To DUMB (od lewej do prawej: d dla Dos, u dla Unix, m dla Mac, b dla BOM).
  2. A także: „DUM” to kolejność alfabetyczna liter D, U i M.

Dalsza lektura

StackzOfZtuff
źródło
1
Generuje dane wyjściowe takie jak: Accounts.java: Java source, ASCII text\012-w systemie Windows w MinTTY
samodzielny
@standalone: ​​ciekawe. Czytałem dziwne rzeczy na temat opcji o nazwie „igncr” - i to, co mówisz, brzmi tak. Ale nie może odtworzyć tego, co opisujesz. (Próbowałem w Bash wewnątrz mięty, która jest dostarczana z Git-for-Windows, „git wersja 2.24.0.windows.1”.)
StackzOfZtuff
Hm, próbowałem też file -k Accounts.javaw mennicy, która pochodzi z git-for-windows, ale moja wersja jestgit version 2.21.0.windows.1
samodzielna
Rozwiązaniem dla mnie jestcat -e file_to_test
samodzielny
9

Możesz użyć xxddo wyświetlenia zrzutu heksadecymalnego pliku i przeszukiwać znaki „0d0a” lub „0a”.

Możesz użyć, cat -v <filename>jak sugeruje @warriorpostman.

Bogaty
źródło
1
Działa dla mnie z cat v 8.23. Zakończenia linii uniksowej nie wydrukują żadnych dodatkowych informacji, ale zakończenia linii DOS wydrukują „^ M”.
Bogaty
To musi być to, na co wpadam w wersji 8.21, biorąc pod uwagę fakt, że używam zakończeń linii unix.
neanderslob
5

Możesz użyć tego polecenia, todos filenameaby przekonwertować na zakończenia DOS i fromdos filenameprzekonwertować na zakończenia linii UNIX. Aby zainstalować pakiet na Ubuntu, wpisz sudo apt-get install tofrodos.

Zorayr
źródło
5

Możesz użyć vim -b filenamedo edycji pliku w trybie binarnym, który pokaże ^ M znaków do powrotu karetki, a nowy wiersz wskazuje na obecność LF, wskazując zakończenia linii Windows CRLF. Mam na myśli LF, \na CR mam na myśli \r. Zauważ, że kiedy użyjesz opcji -b, plik zawsze będzie domyślnie edytowany w trybie UNIX, jak wskazuje [unix]linia stanu, co oznacza, że ​​jeśli dodasz nowe linie, kończą się na LF, a nie CRLF. Jeśli używasz normalnego vima bez -b na pliku z zakończeniami linii CRLF, powinieneś zobaczyć [dos]pokazany w linii statusu, a wstawione linie będą miały CRLF jako koniec linii. Dokumentacja vima dotycząca fileformatsustawiania wyjaśnia złożoność.

Ponadto nie mam wystarczającej liczby punktów, aby skomentować odpowiedź Notepad ++, ale jeśli używasz Notepad ++ w systemie Windows, użyj menu Widok / Pokaż symbol / Pokaż koniec linii, aby wyświetlić CR i LF. W tym przypadku pokazane jest LF, natomiast dla vim LF jest oznaczone nową linią.

Smalers
źródło
0

Zrzucam moje wyjście do pliku tekstowego. Następnie otwieram go w notatniku ++, a następnie kliknij przycisk pokaż wszystkie znaki. Niezbyt elegancki, ale działa.

Diego
źródło
3
To pytanie jest oznaczone jako Linux i nie sądzę, że notepad ++ jest przeznaczony dla systemu Linux. Powinno to jednak działać w systemie Windows.
Rick Smith
0

Vim - zawsze pokazuj nowe linie Windows jako ^M

Jeśli wolisz zawsze widzieć nowe wiersze systemu Windows w renderowaniu vim jako ^M, możesz dodać ten wiersz do .vimrc:

set ffs=unix

Spowoduje to, że vim będzie interpretował każdy otwierany plik jako plik unix. Ponieważ pliki unix mają \nznak nowej linii, plik systemu Windows o znaku nowej linii \r\nbędzie nadal renderowany poprawnie (dzięki \n), ale będzie miał ^Mna końcu pliku (tak jak vim renderuje \rznak).


Vim - czasami pokazuje nowe linie Windows

Jeśli wolisz ustawić go tylko dla poszczególnych plików, możesz użyć go :e ++ff=unixpodczas edycji danego pliku.


Vim - zawsze pokazuj typ pliku ( unixvs dos)

Jeśli chcesz dolną linię vim, aby zawsze wyświetlać co filetype jesteś edycji (i nie zmuszał ustawić typ pliku na Unix) można dodać do statuslinez
set statusline+=\ %{&fileencoding?&fileencoding:&encoding}.

Moja pełna linia statusu znajduje się poniżej. Po prostu dodaj go do swojego .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+=\ 

Renderuje się jak

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

na dole pliku


Vim - czasami pokaż typ pliku ( unixvs dos)

Jeśli chcesz tylko zobaczyć, jaki typ pliku masz, możesz użyć :set fileformat(to nie zadziała, jeśli wymusisz ustawienie typu pliku). Będzie to powrót unixdo plików UNIX i dosWindows.

jeremysprofile
źródło