Kiểm tra tìm kiếm sed đệ quy và thay thế trước khi chạy


13

Có cách nào để chạy thử nghiệm đệ quy thử nghiệm và thay thế bằng cách sử dụng sedtrước khi thực sự chạy nó không? Tôi chỉ muốn in ra kết quả trước khi thực sự tìm kiếm và thay thế. Một cái gì đó giống như lặp lại kết quả của,

grep -rl term1 . |xargs sed -i -e 's/term1/term2/'

Tạo một bản sao của dữ liệu, chạy lệnh của bạn, kiểm tra kết quả.
Kusalananda

Câu trả lời:


10

Bạn có thể chạy sedmà không cần -ivà bước qua đầu ra vớiless

grep -rl --null term1 . | xargs -0 sed -e 's/term1/term2/' | less

Sau đó chạy sedvới -i.bakđể tạo bản sao lưu mà bạn có thể tìm khác sau đó

grep -rl --null term1 . | xargs -0 sed -i.bak -e 's/term1/term2/'
diff somefile.bak somefile
# verify changes were correct

Chỉnh sửa: Theo đề xuất trong bình luận, sử dụng grep --null | xargs -0. Điều này khiến tên tệp bị chấm dứt bởi byte rỗng, điều này làm cho nó an toàn cho tên tệp có các ký tự khác thường như dòng mới. Có, \nlà một ký tự hợp lệ trong một tên tệp unix. Các nhân vật bị cấm duy nhất là dấu gạch chéo /và nhân vật nul\0


Thật thú vị, tôi đã cố gắng tìm ý nghĩa của -i nhưng nó không được liệt kê dưới man sed. Giải pháp của bạn đã làm việc. Điều gì sẽ là cách tốt nhất theo ý kiến ​​của bạn để chỉ liệt kê các dòng, không phải toàn bộ tập tin? Thay vì đường ống vào ít hơn tôi đường ống | grep term2, loại này hoạt động nhưng tôi cũng nhận được một số đầu ra với các ký tự lạ.
dùng251482

@ user251482 - "Chỉ liệt kê các dòng", như trong "xem khác biệt giữa tệp cũ và tệp mới"?
grebneke

1
@StephaneChazelas Có, hoặc thậm chí tốt hơn grep -rl --nullvì OP không chỉ định HĐH và -Zcó nghĩa là có gì đó khác trên BSD / OSX (giải nén). --nulllà giống nhau trên cả GNU và BSD
grebneke

1
@grebneke. Điểm hay, nhưng lưu ý rằng OP đang sử dụng cú pháp sed của GNU, vì vậy chúng ta có thể cho rằng anh ta không có trên BSD. Lưu ý rằng grep(một nhánh của) GNU grep trên FreeBSD và NetBSD. Trên NetBSD, -Zvẫn có nghĩa là --null(theo trang nam), nhưng tôi đồng ý - hoàn toàn dễ mang theo hơn. Cũng lưu ý rằng cả - không phải -Z cũng không hoạt động trên OpenBSD
Stéphane Chazelas

1
@grebneke, nó sed -i '' -e s/.../ở BSD sed(không có tùy chọn tùy chọn nào ở đó)
Stéphane Chazelas

5

Sử dụng sedvới findthay vìgrep

Trước hết, tôi sẽ sử dụng findchứ không phải grep, và điều này vì ba lý do tốt:

  1. findcho phép lựa chọn tập tin chính xác hơn. Ví dụ, grep -r string *.txtsẽ chỉ mang lại các tệp trong thư mục hiện tại; không phải trong thư mục con.
  2. findđi kèm với -exectùy chọn mạnh mẽ giúp loại bỏ sự cần thiết cho toàn bộ --null … |xargs 0cấu trúc.
  3. Các tùy chọn -readablevà sẽ ngăn chặn lãng phí thời gian vào các tệp không thể truy cập.-writablefind

Kiểm tra chụp

Điều đó nói rằng, grepchính nó cho vay thử nghiệm đầu tiên để xem những gì sẽ được nắm bắt:

$ find . -exec grep term1 {} \;

hoặc cụ thể hơn:

$ find . -type f -name '*.txt' -readable -writable -exec grep term1 {} \;

Chạy khô

Bây giờ, tiến hành sedchạy khô. Các sedtùy chọn -nlà một từ đồng nghĩa với --quietpvào cuối của sedbiểu sẽ in không gian mô hình hiện tại.

$ find . -exec sed -n 's/term1/term2/gp' {} \;

hoặc cụ thể hơn:

$ find . -type f -name '*.txt' -readable -writable -exec sed -n 's/term1/term2/gp' {} \;

Chấp hành

Nếu mọi thứ đều ổn, hãy đưa ra lệnh dứt khoát bằng cách thay thế sedtùy chọn -nbằng cách -i"tại chỗ" và bằng cách loại bỏ pở cuối.

$ find . -exec sed -i 's/term1/term2/g' {} \;

hoặc cụ thể hơn:

$ find . -type f -name '*.txt' -readable -writable -exec sed -i 's/term1/term2/g' {} \;

Thêm findví dụ

Nhiều findví dụ có thể được tìm thấy ở đây .

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.