2009-02-09 42 views
33

cách tốt nhất để làm điều này là gì? Tôi không có chiến binh dòng lệnh, nhưng tôi đã nghĩ rằng có thể có một cách sử dụng grep và mèo.Cách tốt nhất để thực hiện tìm/thay thế trong một số tệp là gì?

tôi chỉ muốn thay thế chuỗi xuất hiện trong thư mục và thư mục con. cách tốt nhất để làm điều này là gì? Tôi đang chạy ubuntu nếu có vấn đề.

-d

+0

Chỉ cần thoát khỏi liên kết này ngay tại đây: http://stackoverflow.com/questions/102083/whats-the-best-tool-to-find-and-replace-regular-expressions-over-multiple-files –

Trả lời

36
find . -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g' 

Phần đầu tiên trong số đó là một lệnh find để tìm các tập tin bạn muốn thay đổi. Bạn có thể cần sửa đổi điều đó một cách thích hợp. Lệnh "xargs" lấy mọi tập tin tìm thấy và áp dụng lệnh "sed" cho nó. Lệnh "sed" lấy mọi phiên bản "từ" và thay thế bằng "thành". Đó là một biểu thức chính quy chuẩn, vì vậy hãy sửa đổi nó theo ý bạn.

Nếu bạn đang sử dụng phần mềm svn. Thư mục .svn của bạn cũng sẽ được tìm kiếm và thay thế. Bạn cần phải loại trừ những người, ví dụ như thế này:

find . ! -regex ".*[/]\.svn[/]?.*" -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

hoặc

find . -name .svn -prune -o -type f -print0 | xargs -0 -n 1 sed -i -e 's/from/to/g'

+0

nó không có vẻ như lệnh này được đệ quy vào thư mục con. có điều gì tôi đang làm sai? – blackrobot

+0

Điều gì khiến bạn nghĩ rằng nó không đệ quy vào các thư mục? –

+0

các tệp văn bản trong thư mục con không thực hiện thay đổi. những gì tôi muốn nó làm là điều này: thay đổi sự xuất hiện của some.ip.address thành somewebsite.com trong tất cả các subdir. – blackrobot

37

Như Phao-lô nói, bạn muốn đầu tiên tìm thấy các tập tin bạn muốn chỉnh sửa và sau đó chỉnh sửa chúng. Một thay thế cho việc sử dụng find là sử dụng GNU grep (mặc định trên Ubuntu), ví dụ:

grep -r -l from . | xargs -0 -n 1 sed -i -e 's/from/to/g' 

Bạn cũng có thể sử dụng ack-grep (sudo apt-get install ack-grep hoặc truy cập http://petdance.com/ack/) là tốt, nếu bạn biết bạn chỉ muốn một loại tệp nhất định và muốn bỏ qua mọi thứ trong các thư mục kiểm soát phiên bản. ví dụ, nếu bạn chỉ muốn tập tin văn bản,

ack -l --print0 --text from | xargs -0 -n 1 sed -i -e 's/from/to/g' 
# `from` here is an arbitrary commonly occurring keyword 

Một thay thế cho việc sử dụng sed là sử dụng perl mà có thể xử lý nhiều tác phẩm cho mỗi lệnh, ví dụ:

grep -r -l from . | xargs perl -pi.bak -e 's/from/to/g' 

Ở đây, perl được kể để chỉnh sửa trong nơi, tạo một tập tin .bak đầu tiên.

Bạn có thể kết hợp bất kỳ bên trái nào của ống với các cạnh bên phải, tùy thuộc vào tùy chọn của bạn.

+0

Bạn có thể tránh các thư mục kiểm soát phiên bản trong "tìm" bằng lệnh "-prune". Ví dụ: "find. -name RCS -prune -o-type f -print0" –

+0

Đúng, mặc dù nó đòi hỏi ít trí tuệ để có một công cụ như ack xử lý nó cho bạn. –

+0

ack cũng chấp nhận tùy chọn '--print0' để sử dụng null làm dấu phân tách giữa các tên tệp, do đó lệnh ack của bạn sẽ trông giống như sau:' ack -l --print0 --text from | xargs -0 -n 1 sed -i -e 's/from/to/g'' –

3

Một thay thế cho sed đang sử dụng rpl (ví dụ có sẵn từ http://rpl.sourceforge.net/ hoặc phân phối GNU/Linux của bạn), như rpl --recursive --verbose --whole-words 'F' 'A' grades/

14

tôi sẽ ném vào một ví dụ khác cho folks sử dụng Ag, The Silver Searcher làm tìm/thay thế hoạt động trên nhiều file .

Hoàn dụ:

ag -l "search string" | xargs sed -i '' -e 's/from/to/g' 

Nếu chúng ta phá vỡ này xuống, những gì chúng ta nhận được là:

# returns a list of files containing matching string 
ag -l "search string" 

Tiếp theo, chúng ta có:

# consume the list of piped files and prepare to run foregoing command 
# for each file delimited by newline 
xargs 

Cuối cùng, lệnh chuỗi thay thế :

# -i '' means edit files in place and the '' means do not create a backup 
# -e 's/from/to/g' specifies the command to run, in this case, 
# global, search and replace 

sed -i '' -e 's/from/to/g' 
Các vấn đề liên quan