Bạn có thể làm một cái gì đó thô thiển với một tập lệnh Perl nhỏ được hướng dẫn để thực hiện thay thế từng dòng ( -l -pe
) tại chỗ trên các tệp được truyền dưới dạng đối số ( -i
):
perl -i -l -pe '
if (/from/) { # is the source text present on this line?
printf STDERR ("%s: %s [y/N]? ", $ARGV, $_); # display a prompt
$r=<STDIN>; # read user response
if ($r =~ /^[Yy]/) { # if user entered Y:
s/from/to/g; # replace all occurences on this line
}' /path/to/files
Những cải tiến có thể sẽ là tô màu các phần của dấu nhắc và hỗ trợ những thứ như Thay thế tất cả các lần xuất hiện trong tệp hiện tại. Việc nhắc riêng cho mỗi lần xuất hiện trên một dòng sẽ khó hơn.
Phần thứ hai, phù hợp với các tập tin. nếu không có quá nhiều tệp liên quan và bạn đang chạy zsh, bạn có thể khớp tất cả các tệp trong thư mục hiện tại và các thư mục con của nó theo cách đệ quy:
perl -i -l -pe '…' **/*(.)
Nếu shell của bạn là bash 4, bạn có thể chạy perl … **/*
, nhưng điều đó sẽ tạo ra các thông báo lỗi giả vì sed sẽ thử (và không thành công) để chạy trên các thư mục. Nếu bạn chỉ muốn thực hiện thay thế trong một tập hợp các tệp như tệp C, bạn có thể hạn chế các kết quả khớp (hoạt động trong bash ≥4 hoặc zsh):
perl -i -l -pe '…' **/*.[hc]
Nếu bạn cần kiểm soát tốt hơn những tập tin nào bạn sẽ thay thế hoặc trình bao của bạn không có cấu trúc khớp thư mục đệ quy **
hoặc nếu bạn có quá nhiều tập tin và nhận được một dòng lệnh quá dài lỗi, hãy sử dụng find
. Ví dụ: để thực hiện thay thế trong tất cả các tệp có tên *.h
hoặc *.c
trong thư mục hiện tại và thư mục con của nó (trên các hệ thống cũ hơn, bạn có thể cần sử dụng \;
thay vì +
ở cuối dòng ( +
biểu mẫu nhanh hơn nhưng không khả dụng ở mọi nơi).
find . -type f -name '*.[hc]' -exec perl -i -l -pe '…' {} +
Điều đó đang được nói, tôi sẽ gắn bó với một trình soạn thảo tương tác nếu bạn cần tương tác. Gert đã chỉ ra một cách để làm điều này trong Vim , mặc dù nó yêu cầu mở tất cả các tệp mà bạn muốn tìm kiếm, đây có thể là một vấn đề nếu có rất nhiều.
Trong Emacs, đây là cách bạn có thể làm điều này:
- Tập hợp các tên tệp bằng
M-x find-name-dired
(chỉ định thư mục toplevel) hoặc M-x find-dired
(chỉ định một find
dòng lệnh tùy ý ).
- Trong bộ đệm dired kết quả , nhấn
t
để đánh dấu tất cả các tệp, sau đó Q
( dired-do-query-replace-regexp
) để thực hiện thay thế bằng lời nhắc trên các tệp được đánh dấu.
s/from/to/g
một trục trặc định dạng sau nó, thay vìs/from/to/gc
nhấn mạnh vàoc
như bạn đã cố gắng viết (bạn không thể làm điều đó với Markdown, bạn có thể làm điều đó với Markdown<code>
và<strong>
thẻ HTML).