2010-03-04 24 views
8

Làm cách nào để thay thế tất cả các kết thúc dòng trong tệp lớn (> 100MB)? Tôi đã cố gắng để làmLàm thế nào để thay thế kết thúc dòng trong VIM

:%s/\n/, /g

nhưng nó quá chậm.

+0

Tại sao bạn muốn thực hiện việc này trong VIM. Bạn sẽ chỉ kết thúc với một dòng dài mà bạn không thể đọc (với đôi mắt đó là.) Ngoài ra, những gì kết thúc dòng tồn tại: DOS, UNIX, MAC hoặc kết hợp? – Marichyasana

Trả lời

8

Vì vậy, tôi đã đi qua và thử nghiệm/timed một số câu trả lời đã được đưa ra bởi những người khác, cộng với một câu trả lời python của riêng tôi. Đây là những gì tôi nhận:

tr:

> time tr "\n" "," <lines> line 
real 0m1.617s 
user 0m0.100s 
sys  0m1.520s 

python:

> time python -c 'import sys; print sys.stdin.read().replace("\n",", "),' <lines> line 
real 0m1.663s 
user 0m0.060s 
sys  0m1.610s 

awk:

> time awk '{printf("%s, ", $0)}' lines > line         
real 0m1.998s 
user 0m0.390s 
sys  0m1.600s 

perl:

> time perl -e 'while (<>) { chomp; print "$_, " }' lines > line 
real 0m2.100s 
user 0m0.590s 
sys  0m1.510s 

sed:

> time sed 's/$/, /g' lines > line            
real 0m6.673s 
user 0m5.050s 
sys  0m1.630s 

Dưới đây là file tôi đã sử dụng:

> ls -lh lines 
-rw-r--r-- 1 some one 101M 2010-03-04 19:54 lines 
> wc -l < lines 
1300000 
> head -n 3 < lines 
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched. 
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched. 
The pretty pink puma pounced on the unsuspecting aardvark, the scientist watched. 
> head -n 1 < lines | wc -c 
82 

Nguyên timings được chụp trong Cygwin, họ hiện nay đã được thực hiện với cập nhật đầy đủ ubuntu 9.10. Ngoài ra, kích thước tệp văn bản đã được tăng lên 100 megs, với các dòng có chiều rộng 80 ký tự. Như bạn có thể thấy khá nhiều thứ khác ngoài sed là một ý tưởng hay.

+2

tôi rất nghi ngờ về kết quả awk của bạn. thời gian bạn chỉ huy một vài lần, không chỉ một lần. Python không nên nhanh hơn awk, xem xét nó cần có thời gian để nhập khẩu các mô-đun và các công cụ – ghostdog74

+0

Nó đã chạy một vài lần, đó là về trung bình. Chỉ cần chạy nó khoảng 10 lần nữa, 1,7xx mỗi lần. Có lẽ nó sẽ khác nếu tôi không sử dụng awg Cygwin. –

+0

@ ghostdog74 Bạn có quyền nghi ngờ kết quả awk của tôi, tôi chạy lại nó trên một hộp linux thực sự, và nó đã được nhanh hơn nhiều. –

2

Sử dụng tập lệnh Perl này để xem qua tệp của bạn; nó sẽ nhanh hơn việc giữ mọi thứ trong bộ nhớ với VIM. Chỉ cần đầu ra đường ống cho một tập tin mới.

#!/usr/local/bin/perl 

while (<>) { 
    $_ =~ s/\n/,/g; 
    print $_; 
} 
+0

Tôi đoán thông dịch viên perl không đủ thông minh để biết rằng trong trường hợp này '$ _' không thể có một dòng mới ngoại trừ ký tự cuối cùng -' chomp' có lẽ nhanh hơn rất nhiều. – Cascabel

+0

@Jefromi Trong thử nghiệm hoàn toàn không khoa học của tôi, nhanh hơn khoảng 300ms để sử dụng chomp trên một tệp 100 meg. –

0

Bạn có phải thực hiện việc này không?

Có tiện ích Unix tuyệt vời làm bản dịch dựa trên ký tự. Nó được gọi là tr. Một số reference.

Trong trường hợp của bạn nó sẽ là:

 
tr "\n" "," < input_file > output_file 
+0

Điều này gần như chắc chắn nhanh hơn các giải pháp tôi đã đăng, nhưng thật không may, nó thay thế "," thay vì "," theo yêu cầu của OP. Tôi không chắc có cách nào để làm điều đó với 'tr', đúng không? – Cascabel

+0

tr chỉ mất một ký tự – ghostdog74

+0

Không có không có, tôi đã không nhận thấy không gian đó. Để đặt nhiều hơn 1 ký tự, người ta có thể sử dụng sed như một người nào đó được đăng bên dưới. – pajton

3

:%s/$/, / theo sau là một :1,$j có thể nhanh hơn. Nếu không, hãy làm điều đó trong một tiện ích bên ngoài:

perl -e 'while (<>) { chomp; print "$_, " }' input_file > output_file 

awk '{printf("%s, ", $0)}' input_file > output_file 

Không biết đỉnh đầu của tôi sẽ nhanh nhất.

+0

'perl -ne 'chomp; in "$ _," 'tập tin'. '-n'" giả định trong khi vòng lặp " – ghostdog74

+0

Gọi tốt trên' -n'. – Cascabel

+0

@sparrkey, "perl sẽ chạy nhanh hơn" là không hợp lý. – ghostdog74

0
$ more file 
aaaa 
bbbb 
cccc 
dddd 
eeee 

$ awk 'NR>1{printf("%s, ", p)}{p=$0}END{print p}' file 
aaaa, bbbb, cccc, dddd, eeee 

$ sed -e :b -e '$!N;s/\n/, /;tb' file 
+0

Bạn đã kiểm tra lệnh sed của mình chưa? sed 'N; s/\ n /, /' tập tin – sparkkkey

+0

không thực sự. của nó một cắt dán một wiki, nhưng tôi đoán wiki không thể tin tưởng đôi khi. – ghostdog74

0

Công cụ tốt nhất là sed và bạn có thể sử dụng công cụ này với:! lệnh

nên sử dụng :!sed -e 's/\n/,/g' % > %.tmp ; cat %.tmp > % ; rm %.tmp'

Bạn cần tạo một file tmp với sự thay đổi trước khi tích hợp trong tập tin hiện tại của bạn

+0

bạn đã kiểm tra lệnh sed của mình chưa? – ghostdog74

+0

vâng tôi kiểm tra nó trước – shingara

Các vấn đề liên quan