Chỉnh sửa tại chỗ với sed trên OS X


142

Tôi muốn chỉnh sửa một tệp với sed trên OS X. Tôi đang sử dụng lệnh sau:

sed 's/oldword/newword/' file.txt

Đầu ra được gửi đến thiết bị đầu cuối. file.txt không được sửa đổi. Các thay đổi được lưu vào file2.txt bằng lệnh này:

sed 's/oldword/newword/' file1.txt > file2.txt

Tuy nhiên tôi không muốn tập tin khác. Tôi chỉ muốn chỉnh sửa file1.txt . Tôi có thể làm cái này như thế nào?

Tôi đã thử cờ -i. Điều này dẫn đến lỗi sau:

sed: 1: "file1.txt": invalid command code f

2
Lệnh chính xác bạn đang sử dụng khi bạn thử -icờ là gì?
eldarerathis

Câu trả lời:


281

Bạn có thể sử dụng -icờ chính xác bằng cách cung cấp cho nó một hậu tố để thêm vào tệp sao lưu. Mở rộng ví dụ của bạn:

sed -i.bu 's/oldword/newword/' file1.txt

Sẽ cung cấp cho bạn hai tệp: một tệp có tên file1.txtthay thế và một tệp có tên file1.txt.bucó nội dung gốc.

Nguy hiểm nhẹ

Nếu bạn muốn ghi đè lên tập tin gốc, hãy sử dụng một cái gì đó như:

sed -i '' 's/oldword/newword/' file1.txt
      ^ note the space

Do cách dòng được phân tích cú pháp, nên cần một khoảng trắng giữa cờ tùy chọn và đối số của nó vì đối số có độ dài bằng không.

Khác với khả năng làm hỏng bản gốc của bạn, tôi không nhận thấy bất kỳ nguy hiểm nào nữa khi lừa sed theo cách này. Tuy nhiên, cần lưu ý rằng nếu lệnh này sedlà một phần của tập lệnh, Unix Way ™ sẽ (IMHO) sẽ sử dụng sedkhông phá hủy, kiểm tra xem nó đã thoát ra một cách sạch sẽ và chỉ sau đó xóa tệp không liên quan.


Bạn nói đúng, tôi đã bỏ qua phần mở rộng sau cờ -i. Có -i''nguy hiểm vì bất kỳ lý do nào khác ngoài khả năng làm hỏng tập tin gốc (và không có bản sao lưu) không?
Chủ nhật

Theo sedtrang man nếu bạn hết dung lượng đĩa trên thiết bị, bạn có thể làm hỏng tệp giữa bước và có kết quả đầu ra xấu. Nếu bạn đang làm việc dưới sự kiểm soát nguồn cục bộ sed -i ""mà không có bản sao lưu thì hầu hết thời gian sẽ ổn (hoặc ngay git init && git add -A . && git commit -m 'backup'trước khi chạy sed ở -ichế độ).
cfeduke

2
Tôi tìm thấy một chút nguy hiểm nhẹ đặc biệt hữu ích. +1
Andre

5
BSD sed yêu cầu không có khoảng trống sau cờ -i. Vì vậy, -i''là hợp lệ, nhưng -i ''là không.
Todd A. Jacobs

3
Argh! Thay vào đó, BSD sed bỏ qua ký tự '\ n' và in 'n'! Tôi sẽ thay thế BSD sed bằng GNU sed trên máy mac của tôi!
vào

20

Tôi gặp vấn đề tương tự với MacOS

sed -i '' 's/oldword/newword/' file1.txt

không hoạt động, nhưng

sed -i"any_symbol" 's/oldword/newword/' file1.txt

hoạt động tốt


Bây giờ là cách khác. sed -i '' <file>hoạt động nhưng sed -i'' <file>không còn hoạt động
Zohaib Amanzai


4

Bạn có thể sử dụng -i''( --in-place) cho sednhư đã đề xuất. Xem: Đối số -itại chỗ , tuy nhiên lưu ý rằng -itùy chọn là các tiện ích mở rộng FreeBSD không chuẩn và có thể không khả dụng trên các hệ điều hành khác. Thứ hai sedlà một S tream ED itor, không phải là một trình soạn thảo tập tin .


Cách khác là sử dụng thay thế tích hợp trong chế độ Vim Ex, như:

$ ex +%s/foo/bar/g -scwq file.txt

và cho nhiều tệp:

$ ex +'bufdo!%s/foo/bar/g' -scxa *.*

Để chỉnh sửa tất cả các tệp đệ quy, bạn có thể sử dụng **/*.*nếu shell hỗ trợ (cho phép bằng shopt -s globstar).


Một cách khác là sử dụng gawkphần mở rộng "tại chỗ" mới của nó, chẳng hạn như:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1

4

Điều này tạo ra các tập tin sao lưu. Ví dụ, sed -i -e 's/hello/hello world/' testfileđối với tôi, tạo một tệp sao lưu, testfile-e, trong cùng một thư mục.


Tương tự ở đây với Mac OS Catalina. Việc chuyển cả hai -i và -e riêng biệt (KHÔNG -ie với nhau!) Tạo ra một tệp sao lưu có thêm '-e'.
Daniel Kesner

1

Bạn có thể dùng:

sed -i -e 's/<string-to-find>/<string-to-replace>/' <your-file-path>

Thí dụ:

sed -i -e 's/Hello/Bye/' file.txt

Điều này hoạt động hoàn hảo trong Mac .


2
Điều này tạo ra một tệp sao lưu cho tôi trong Mac OS Catalina có thêm '-e'.
Daniel Kesner

Điều này là sai đối với macOS. Xin hãy xem trang "man sed" ở đó. -iyêu cầu một đối số cho macOS. Vì bạn không chỉ định một tệp, nó sử dụng -e, dẫn đến việc có tệp thứ hai được -enối thêm. -ekhông tồn tại trong macOS -E. Vì vậy, lệnh chính xác cho macOS làsed -i '' -E 's/Hello/Bye/' file.txt
Marc J. Schmidt
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.