Tôi gặp khó khăn khi hiểu một hành vi kỳ lạ: vi dường như thêm một dòng mới (ASCII: LF, vì nó là hệ thống Unix ( AIX )) ở cuối tệp, khi tôi KHÔNG gõ cụ thể.
Tôi chỉnh sửa tệp như vậy trong vi (chú ý không nhập dòng mới ở cuối):
# vi foo ## Which I will finish on the char "9" and not input a last newline, then `:wq`
123456789
123456789
123456789
123456789
~
~
## When I save, the cursor is just above the last "9", and no newline was added.
Tôi hy vọng vi sẽ lưu nó "như hiện tại", vì vậy để có 39 byte: 10 ký tự ASCII trên mỗi ba dòng đầu tiên (số 1 đến 9, theo sau là một dòng mới (LF trên hệ thống của tôi)) và chỉ có 9 dòng cuối cùng dòng (ký tự 1 đến 9, không kết thúc dòng mới / LF).
Nhưng nó xuất hiện khi tôi lưu nó là 40 byte (thay vì 39) và od hiển thị một kết thúc LF :
# wc foo
4 4 40 foo ## I expected 39 here! as I didn't add the last newline
# od -a toto
0000000 1 2 3 4 5 6 7 8 9 lf 1 2 3 4 5 6
0000020 7 8 9 lf 1 2 3 4 5 6 7 8 9 lf 1 2
0000040 3 4 5 6 7 8 9 lf
0000050
## An "lf" terminates the file?? Did vi add it silently?
Nếu tôi tạo tệp với printf thực hiện chính xác những gì tôi đã làm bên trong vi, nó sẽ hoạt động như mong đợi:
# ## I create a file with NO newline at the end:
# printf "123456789\n123456789\n123456789\n123456789" > foo2
# wc foo2 ## This one is as expected: 39 bytes, exactly as I was trying to do above with vi.
3 4 39 foo ## As expected, as I didn't add the last newline
## Note that for wc, there are only three lines!
## (So wc -l doesn't count lines; it counts the [newline] chars... Which is rather odd.)
# root@SPU0WMY1:~ ## od -a foo2
0000000 1 2 3 4 5 6 7 8 9 lf 1 2 3 4 5 6
0000020 7 8 9 lf 1 2 3 4 5 6 7 8 9 lf 1 2
0000040 3 4 5 6 7 8 9
0000047 ## As expected, no added LF.
Cả hai tệp (foo (40 ký tự) và foo2 (39 ký tự) xuất hiện giống hệt nhau nếu tôi mở lại chúng bằng vi ...
Và nếu tôi mở foo2 (39 ký tự, không kết thúc dòng mới) trong vi và chỉ cần làm :wq
mà không chỉnh sửa bất cứ điều gì , nó nói rằng nó viết 40 ký tự, và dòng cấp dữ liệu xuất hiện!
Tôi không thể truy cập vào một vi gần đây hơn (tôi làm điều này trên AIX, vi (không phải Vim ) phiên bản 3.10 Tôi nghĩ sao? (Không "đảo ngược" hoặc các phương tiện khác để biết về nó)).
# strings /usr/bin/vi | grep -i 'version.*[0-9]'
@(#) Version 3.10
Có phải bình thường đối với vi (và có lẽ không phải trong phiên bản gần đây hơn? Hoặc Vim?) Để âm thầm thêm một dòng mới ở cuối tệp? (Tôi nghĩ rằng ~ chỉ ra rằng dòng trước đó KHÔNG kết thúc bằng một dòng mới.)
-
Chỉnh sửa: một số cập nhật bổ sung và một chút tóm tắt, rất cảm ơn các câu trả lời dưới đây:
vi âm thầm thêm một dòng mới ở thời điểm nó ghi một tệp thiếu nó (trừ khi tệp trống).
nó chỉ làm như vậy tại thời điểm viết! (tức là cho đến khi bạn: w, bạn có thể sử dụng: e để xác minh rằng tệp vẫn còn khi bạn mở nó ... (nghĩa là: nó vẫn hiển thị "tên tệp" [Dòng cuối chưa hoàn thành] N dòng, ký tự M). Khi bạn lưu, một dòng mới được âm thầm thêm vào, không có cảnh báo cụ thể (nó cho biết nó tiết kiệm được bao nhiêu byte, nhưng trong hầu hết các trường hợp không đủ để biết một dòng mới đã được thêm vào) (cảm ơn @jiliagre đã nói chuyện với tôi về mở tin nhắn vi, nó giúp tôi tìm cách biết khi nào sự thay đổi thực sự xảy ra)
Đây (chỉnh sửa im lặng) là hành vi POSIX ! (xem câu trả lời @ Barefoot-io để tham khảo)
vi
phiên bản hoặc ít nhất là một đầu mối về nguồn gốc của nó bằng cách chạy :ve
lệnh.
ex
trang thủ công nơi :ver
lệnh thường được ghi lại.