Làm cách nào để xóa một số dòng nhất định (sử dụng số dòng) trong một tệp?


27

Có những dòng cụ thể mà tôi muốn xóa khỏi một tập tin. Giả sử đó là dòng 20-37 và sau đó là dòng 45. Làm thế nào để tôi làm điều đó mà không chỉ định nội dung của những dòng đó?


Làm thế nào lớn là tập tin của bạn? Nó có thể được tải vào bộ nhớ?
Faheem Mitha

Một vài kilobyte.
tshepang

Câu trả lời:


29

Với sed, như vậy:

sed '20,37d; 45d' < input.txt > output.txt

Nếu bạn muốn làm điều này tại chỗ:

sed --in-place '20,37d; 45d' file.txt

Có cách nào để làm điều đó tại chỗ?
tshepang

Tôi đề nghị tập tin sed -i
enzotib

1
@Tshepang: Sử dụng ed, hoặc GNU sed -i, hoặc sponge, hoặc một phương thức tệp lớn .
Gilles 'SO- ngừng trở nên xấu xa'

3
Tôi thường tự hỏi về thuật ngữ có thể gây hiểu lầm tại chỗ , khi đề cập đến 'sed', vì vậy tôi đã tra cứu nó trong 'man sed': --in-Place [= SUFFIX] This option specifies that files are to be edited in-place. GNU sed 'thực hiện điều này bằng cách tạo một tệp tạm thời và gửi đầu ra đến tệp này chứ không phải đầu ra tiêu chuẩn. '... Tôi không biết về bất kỳ' sed 'nào khác nhưng hậu cần cập nhật "tại chỗ" với trình chỉnh sửa luồng không "tính toán" :)
Peter.O

2
Theo kinh nghiệm của tôi, hầu hết các phương pháp "tại chỗ" đều sử dụng một tệp tạm thời.
Faheem Mitha

5

Nếu tập tin vừa vặn trong bộ nhớ, bạn cũng có thể sử dụng ed.
Các lệnh này khá giống với lệnh sedở trên với một điểm khác biệt đáng chú ý : bạn phải vượt qua danh sách các số / phạm vi dòng sẽ bị xóa theo thứ tự giảm dần (từ dòng cao nhất / phạm vi xuống mức thấp nhất). Lý do là khi bạn xóa / chèn / tách / nối các dòng với ed, bộ đệm văn bản được cập nhật sau mỗi tiểu ban, vì vậy nếu bạn xóa một số dòng, phần còn lại của các dòng sau sẽ không còn ở cùng vị trí trong bộ đệm khi tiểu ban tiếp theo được thực thi. Vì vậy, bạn phải bắt đầu ngược 1 . Chỉnh sửa tại
chỗ :

ed -s in_file <<IN
45d
20,37d
w
q
IN

hoặc là

ed -s in_file <<< $'45d\n20,37d\nw\nq\n'

hoặc là

printf '%s\n' 45d 20,37d w q | ed -s in_file

Thay thế wnghi thức bằng ,print nếu bạn muốn in kết quả đầu ra thay vì ghi vào tệp. Nếu bạn muốn giữ nguyên tệp gốc và ghi vào tệp khác, bạn có thể chuyển tên tệp mới cho tiểu ban wnghi thức:

ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN

1 Trừ khi bạn sẵn sàng tính các số dòng mới sau mỗi lần chạy d, điều này khá tầm thường đối với trường hợp cụ thể này (sau khi xóa các dòng 20-37, tức là 18 dòng, dòng 45 trở thành dòng 27) để bạn có thể chạy:

ed -s in_file <<IN
20,37d
27d
w
q
IN

Tuy nhiên, nếu bạn phải xóa nhiều số dòng / phạm vi, làm việc ngược lại là không có trí tuệ.


qlệnh hữu ích ở cuối? Tôi đoán nó thoát ra một trong hai cách.
Tom Fenech

@TomFenech - không phải tất cả các triển khai đều thoát ra (mặc dù hầu hết đều làm ... Tôi không còn có thể tìm thấy chủ đề mà điều này đã được thảo luận ...)
don_crissti

1

Chỉ cần đọc nó vào bộ nhớ, thay đổi nó, sau đó viết lại. Bạn có thể làm một cái gì đó như

filename = "foo"
f = open(filename, 'r+')                                                                                                                                 
linenums = [1, 3]                                                                                                                                            
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]                                                                                                                                          
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()

Đã thử nghiệm với một tập tin 5 dòng. Tín dụng cho http://pleac.sourceforge.net/pleac_python/fileaccess.html , xem phần "Sửa đổi tệp tại chỗ mà không cần tệp tạm thời". Xem thêm https://stackoverflow.com/questions/125703/how-do-i-modify-a-text-file-in-python

Một số lưu ý:

  1. Đầu tiên người ta có thể cắt ngắn tập tin, sau đó viết vào nó, thay vì viết, sau đó cắt ngắn, như trên. Tuy nhiên, tôi không biết về một cờ Python cho phép một người đọc và sau đó viết một đoạn rút ngắn. Nhưng có lẽ tôi đang thiếu một cái gì đó, vì tài liệu không rõ ràng lắm. Điều này đưa tôi đến

  2. Đôi khi các tài liệu Python thực sự hút. Xem http://docs.python.org/l Library / fiances.html # open

    Các chế độ 'r +', 'w +' và 'a +' mở tệp để cập nhật (lưu ý rằng 'w +' cắt ngắn tệp).

    Điều này có ý nghĩa gì với bạn không? Cái quái gì là "mở để cập nhật"?

  3. Tôi không biết nếu làm điều này trong python trái ngược với một cái gì đó không trộn lẫn như trình chỉnh sửa luồng thì tốt hơn. Nó có thể di động hơn, nhưng tôi không biết sed di động là như thế nào. Tôi chỉ viết như vậy bởi vì tôi thấy thoải mái hơn với lập trình cấp thấp hơn là sử dụng các công cụ unix cổ điển, sẽ tốt nếu họ làm chính xác những gì bạn muốn, nhưng (tôi nghĩ) nói chung là kém linh hoạt hơn.

  4. Cách tiếp cận này (thao tác với tệp trong bộ nhớ) trao đổi bộ nhớ cho không gian đĩa. Nó sẽ hoạt động tốt trên các máy có bộ nhớ vài Gb cho các tệp lên tới vài trăm Mb. Python không xử lý chuỗi rất hiệu quả, do đó, chuyển sang C / C ++ chẳng hạn sẽ tăng hiệu suất một chút và giảm đáng kể việc sử dụng bộ nhớ.


0

Bạn có thể sử dụng Vim trong chế độ Ex:

ex -sc '20,37d|45d|x' file
  1. d xóa bỏ

  2. x lưu và đóng

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.