Làm thế nào để tìm ra kết thúc dòng trong một tệp văn bản?


304

Tôi đang cố gắng sử dụng một cái gì đó trong bash để hiển thị cho tôi các kết thúc dòng trong một tệp được in chứ không phải là giải thích. Tệp là một kết xuất từ ​​SSIS / SQL Server đang được máy Linux đọc để xử lý.

  • Có bất kỳ công tắc bên trong vi, less, more, vv?

  • Ngoài việc xem các kết thúc dòng, tôi cần biết loại kết thúc dòng đó là gì ( CRLFhoặc LF). Làm thế nào để tôi tìm ra điều đó?


1
Mẹo chung: Nếu bạn có ý tưởng về lệnh * nix / cygwin nào bạn có thể sử dụng, bạn luôn có thể xem trang chủ của nó để tìm kiếm các công tắc có thể cung cấp cho bạn chức năng bạn cần. Ví dụ man less.
David Rivers

Câu trả lời:


421

Bạn có thể sử dụng filetiện ích để cung cấp cho bạn một chỉ dẫn về loại kết thúc dòng.

Unix:

$ file testfile1.txt
testfile.txt: ASCII text

"DOS":

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

Để chuyển đổi từ "DOS" sang Unix:

$ dos2unix testfile2.txt

Để chuyển đổi từ Unix sang "DOS":

$ unix2dos testfile1.txt

Chuyển đổi một tệp đã được chuyển đổi không có tác dụng nên an toàn để chạy một cách mù quáng (tức là không kiểm tra định dạng trước) mặc dù luôn luôn áp dụng các khuyến cáo thông thường.


9
Hiện tại đôi khi chúng được đặt tên là "fromdos" và "todos" (như trường hợp trong Ubuntu 10.4+)
Jess Chadwick

3
@JessChadwick: Có, nhưng chỉ khi bạn cài đặt tofrodosgói rõ ràng với sudo apt-get install tofrodos- giống như bạn phải chạy sudo apt-get install dos2unixđể lấy dos2unixunix2dos.
mkuity0

Actully dos2unix không thể làm tất cả công việc, tôi nghĩ stackoverflow.com/questions/23828554/dos2unix-doesnt-convert-m đưa ra câu trả lời hay nhất
nathan

@nathan: Thất dos2unixbại ở cái gì? OP tại câu hỏi đó chỉ mô tả mơ hồ vấn đề.
Tạm dừng cho đến khi có thông báo mới.

Lệnh tập tin @DennisWilliamson trước và sau lệnh dos2unix có cùng một đầu ra: xxx.c C nguồn, văn bản ASCII, với các đầu cuối dòng CR, LF. Tôi tìm thấy tập tin c này có ^ M ở giữa dòng thích xxxxxxx ^ M xxxxxxx
nathan

127

Trong vi...

:set list để xem kết thúc dòng.

:set nolist để trở lại bình thường.

Mặc dù tôi không nghĩ rằng bạn có thể nhìn thấy \nhoặc \r\nvào vi, nhưng bạn có thể xem loại tệp nào (UNIX, DOS, v.v.) để suy ra kết thúc dòng nào có ...

:set ff

Ngoài ra, từ bashbạn có thể sử dụng od -t c <filename>hoặc chỉ od -c <filename>để hiển thị lợi nhuận.


26
Thật không may, tôi không nghĩ vi có thể hiển thị các ký tự cụ thể. Bạn có thể thử od -c <tên tệp> mà tôi tin rằng sẽ hiển thị \ n hoặc \ r \ n.
Ryan Berger

3
Trong danh mục "vì giá trị của nó", bạn có thể grep cho CRLF kiểu Dos bằng cách phát hành grep --regex = "^ M" trong đó ^ M là CTRL + V CTRL + M. Bạn có thể loại bỏ chúng bằng cách thay thế chúng bằng lệnh sed. Điều này về cơ bản giống như dos2unix
cowboydan

11
Trong vim: :set fileformatsẽ báo cáo phần nào unixhoặc dosvim nghĩ rằng kết thúc dòng của tệp. Bạn có thể thay đổi nó bằng :set fileformat=unix.
Victor Zamanian

5
Sử dụng cờ -b khi bắt đầu vi / vim và sau đó sử dụng: set list để xem các kết thúc CR (^ M) và LF ($).
Samuel

1
@RyanBerger - Có vẻ như bạn đang thiếu một -t. Nó nên od -t c file/path, nhưng cảm ơn cho chương trình mới. Làm việc tuyệt vời!
Eric Fossum

113

Ubuntu 14.04:

cat -e <filename>công việc đơn giản chỉ cần tốt

Điều này sẽ hiển thị các kết thúc dòng Unix ( \nhoặc LF) như $và các kết thúc dòng Windows ( \r\nhoặc CRLF) là ^M$.


7
Cũng hoạt động trên OSX. Giải pháp tốt. Đơn giản và làm việc cho tôi trong khi câu trả lời được chấp nhận thì không. (Lưu ý: không phải là một .txttệp)
dlsso

4
màn hình của M $ một Easteregg / windows bashing?
Tom M

Không hoạt động với Solaris, nhưng con người nói rằng nó nên hoạt động
Zeus

101

Trong vỏ bash, hãy thử cat -v <filename>. Điều này sẽ hiển thị lợi nhuận vận chuyển cho các tập tin windows.

(Điều này làm việc cho tôi trong rxvt thông qua Cygwin trên Windows XP).

Lưu ý của biên tập viên: cat -vtrực quan hóa \rký tự (CR). như ^M. Do đó, các \r\nchuỗi kết thúc dòng sẽ hiển thị ^Mở cuối mỗi dòng đầu ra. cat -ecũng sẽ hình dung \n, cụ thể là $. ( cat -etcũng sẽ trực quan hóa các ký tự tab. as ^I.)


3
@ChrisK: Hãy thử echo -e 'abc\ndef\r\n' | cat -vvà bạn sẽ thấy ^Msau "def".
Tạm dừng cho đến khi có thông báo mới.

Tôi muốn xem liệu tệp có ^ M (Windows / DOS EOL) không và chỉ có con mèo -v chỉ cho tôi điều đó. +1 cho điều đó
Ali

1
^ M = phong cách DOS / Windows
Sao Thủy

chỉnh sửa: Do đó, các chuỗi \ r \ n kết thúc dòng sẽ hiển thị dưới dạng ^ M $
Shaya

19

Để hiển thị CR như ^Msử dụng ít hơn less -uhoặc gõ -umột lần ít hơn được mở.

man less nói:

-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
Hãy làm rõ câu trả lời của bạn.
adao7000

12

Hãy thử filesau file -kđódos2unix -ih

filethường sẽ là đủ Nhưng đối với trường hợp khó khăn hãy thử file -khoặc dosunix -ih.

Chi tiết bên dưới.


Thử file -k

Phiên bản ngắn: file -k somefile.txt sẽ cho bạn biết.

  • Nó sẽ xuất ra with CRLF line endingscho kết thúc dòng DOS / Windows.
  • Nó sẽ xuất ra with LF line endingscho kết thúc dòng MAC.
  • Và đối với dòng Linux / Unix "CR", nó sẽ chỉ xuất ra text. (Vì vậy, nếu nó không đề cập rõ ràng bất kỳ loại nào line endingsthì điều này có nghĩa là: "kết thúc dòng CR" .)

Phiên bản dài xem bên dưới.


Ví dụ thế giới thực: Mã hóa chứng chỉ

Đôi khi tôi phải kiểm tra điều này cho các tệp chứng chỉ PEM.

Vấn đề thường gặp filelà: Đôi khi, nó cố tỏ ra quá thông minh / quá cụ thể.

Hãy thử làm một bài kiểm tra nhỏ: Tôi đã có một số tệp. Và một trong những tập tin này có kết thúc dòng khác nhau. Cái nào?

(Nhân tiện: đây là một trong những thư mục "công việc chứng chỉ" điển hình của tôi trông như thế nào.)

Hãy thử thường xuyên 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. Nó không cho tôi biết kết thúc dòng. Và tôi đã biết rằng đó là những tập tin cert. Tôi không cần "tập tin" để nói với tôi điều đó.

Bạn có thể thử cái gì khác?

Bạn có thể thử dos2unixvới công --infotắc như thế này:

$ 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

Vì vậy, điều đó cho bạn biết rằng: yup, "0.example.end.cer" phải là người đàn ông kỳ quặc. Nhưng những loại kết thúc dòng là gì? Bạn biết định dạng đầu ra dos2unix theo trái tim? (Tôi không.)

Nhưng may mắn thay, có tùy chọn --keep-going(hoặc -kviết tắt) trong 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

Thông minh! Bây giờ chúng tôi biết rằng tệp lẻ của chúng tôi có CRLFkết thúc dòng DOS ( ). (Và các tệp khác có LFkết thúc dòng Unix ( ). Điều này không rõ ràng trong đầu ra này. Nó ẩn. Đó chỉ là cách filemong đợi một tệp văn bản "thông thường".)

(Nếu bạn muốn chia sẻ bản ghi nhớ của tôi: "L" là dành cho "Linux" và cho "LF".)

Bây giờ hãy chuyển đổi thủ phạm và thử lại:

$ 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  

Tốt Bây giờ tất cả các certs có kết thúc dòng Unix.

Thử dos2unix -ih

Tôi không biết điều này khi tôi viết ví dụ trên nhưng:

Trên thực tế, hóa ra dos2unix sẽ cung cấp cho bạn một dòng tiêu đề nếu bạn sử dụng -ih(viết tắt --info=h) như vậy:

$ 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

Và một khoảnh khắc "thực sự" khác: Định dạng tiêu đề thực sự dễ nhớ: Đây là hai câu thần chú:

  1. Đó là DUMB (trái sang phải: d cho Dos, u cho Unix, m cho Mac, b cho BOM).
  2. Và cũng: "DUM" chỉ là thứ tự chữ cái của D, U và M.

đọc thêm


1
Nó tạo ra kết quả như: Accounts.java: Java source, ASCII text\012-trên Windows trong MinTTY
độc lập

@standopol: thú vị. Tôi đã đọc những điều kỳ lạ về một tùy chọn gọi là "igncr" - và những gì bạn đang nói nghe có vẻ như vậy. Nhưng không thể tái tạo những gì bạn mô tả. (Tôi đã thử bên trong Bash bên trong mintty đi kèm với Git-for-Windows, "git phiên bản 2.24.0.windows.1".)
StackzOfZtuff

Hừm, tôi cũng đã thử file -k Accounts.javabên trong mintty đi kèm với git-for-windows, nhưng phiên bản của tôi làgit version 2.21.0.windows.1
độc lập

Giải pháp làm việc cho tôi làcat -e file_to_test
độc lập

9

Bạn có thể sử dụng xxdđể hiển thị kết xuất hex của tệp và tìm kiếm các ký tự "0d0a" hoặc "0a".

Bạn có thể sử dụng cat -v <filename>như @warriorpostman gợi ý.


1
Nó hoạt động với tôi với mèo v 8.23. Kết thúc dòng Unix sẽ không in bất kỳ thông tin bổ sung nào, nhưng kết thúc dòng DOS sẽ in "^ M".
Giàu

Đó phải là những gì tôi đang chạy với 8.21, với thực tế là tôi đang sử dụng các kết thúc dòng unix.
Neanderslob

5

Bạn có thể sử dụng lệnh todos filenameđể chuyển đổi sang các kết thúc DOS và fromdos filenameđể chuyển đổi sang các kết thúc dòng UNIX. Để cài đặt gói trên Ubuntu, gõ sudo apt-get install tofrodos.


5

Bạn có thể sử dụng vim -b filenameđể chỉnh sửa một tệp ở chế độ nhị phân, nó sẽ hiển thị ^ M ký tự cho việc trả lại vận chuyển và một dòng mới là dấu hiệu cho thấy hiện diện của LF, cho biết kết thúc dòng CRLF của Windows. Ý tôi là của tôi \nvà ý của CR \r. Lưu ý rằng khi bạn sử dụng tùy chọn -b, tệp sẽ luôn được chỉnh sửa ở chế độ UNIX theo mặc định như được chỉ định [unix]trong dòng trạng thái, nghĩa là nếu bạn thêm dòng mới, chúng sẽ kết thúc bằng LF, không phải CRLF. Nếu bạn sử dụng vim bình thường không có -b trên một tệp có kết thúc dòng CRLF, bạn sẽ thấy [dos]hiển thị trong dòng trạng thái và các dòng được chèn sẽ có CRLF ở cuối dòng. Các tài liệu vim để fileformatsthiết lập giải thích sự phức tạp.

Ngoài ra, tôi không có đủ điểm để nhận xét về câu trả lời của Notepad ++, nhưng nếu bạn sử dụng Notepad ++ trên Windows, hãy sử dụng menu Xem / Hiển thị biểu tượng / Hiển thị kết thúc dòng để hiển thị CR và LF. Trong trường hợp này, LF được hiển thị trong khi đối với vim, LF được chỉ định bởi một dòng mới.


0

Tôi đổ đầu ra của tôi vào một tập tin văn bản. Sau đó tôi mở nó trong notepad ++, sau đó nhấp vào nút hiển thị tất cả các ký tự. Không thanh lịch nhưng nó hoạt động.


3
Câu hỏi này được gắn thẻ là Linux và tôi không nghĩ notepad ++ là dành cho linux. Điều này sẽ làm việc cho các cửa sổ mặc dù.
Rick Smith

0

Vim - luôn hiển thị các dòng mới của Windows dưới dạng ^M

Nếu bạn luôn muốn xem các dòng mới của Windows trong vim render như ^M, bạn có thể thêm dòng này vào .vimrc:

set ffs=unix

Điều này sẽ làm cho vim diễn giải mọi tệp bạn mở dưới dạng tệp unix. Vì các tệp unix có \nký tự dòng mới, một tệp windows có ký tự dòng mới \r\nvẫn sẽ hiển thị đúng (nhờ \n) nhưng sẽ có ^Mở cuối tệp (đó là cách vim biểu hiện \rký tự).


Vim - đôi khi hiển thị các dòng mới của Windows

Nếu bạn chỉ muốn đặt nó trên cơ sở mỗi tệp, bạn có thể sử dụng :e ++ff=unixkhi chỉnh sửa một tệp đã cho.


Vim - luôn hiển thị filetype ( unixvs dos)

Nếu bạn muốn dòng dưới cùng của vim để luôn luôn hiển thị những gì filetype bạn chỉnh sửa đang (và bạn không lực lượng thiết lập filetype để unix), bạn có thể thêm vào của bạn statuslinevới
set statusline+=\ %{&fileencoding?&fileencoding:&encoding}.

Trạng thái đầy đủ của tôi được cung cấp dưới đây. Chỉ cần thêm nó vào của bạn .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+=\ 

Nó sẽ hiển thị như

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

ở dưới cùng của tập tin của bạn


Vim - đôi khi hiển thị filetype ( unixvs dos)

Nếu bạn chỉ muốn xem loại tệp nào bạn có, bạn có thể sử dụng :set fileformat(điều này sẽ không hoạt động nếu bạn buộc thiết lập kiểu tệp). Nó sẽ trả về unixcho các tập tin unix và doscho Windows.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.