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 đó?
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 đó?
Câu trả lời:
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
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" :)
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ế w
nghi thức bằng ,p
rint 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 w
nghi 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ệ.
q
lệnh hữu ích ở cuối? Tôi đoán nó thoát ra một trong hai cách.
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 ý:
Đầ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
Đô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"?
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.
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ớ.
Bạn có thể sử dụng Vim trong chế độ Ex:
ex -sc '20,37d|45d|x' file
d
xóa bỏ
x
lưu và đóng