2009-08-07 68 views
8

Tôi có một tệp SQL khổng lồ được thực hiện trên máy chủ. Dump là từ máy tính của tôi và trong nó có một vài cài đặt liên quan đến máy tính của tôi. Vì vậy, về cơ bản, tôi muốn mọi sự xuất hiện của "c://temp" để được thay thế bằng "//home//some//blah"Lệnh Linux để thay thế chuỗi trong tệp LARGE bằng một chuỗi khác

Làm thế nào điều này có thể được thực hiện từ dòng lệnh?

+0

Bạn đang thiếu một% trailing trong lệnh của bạn. Đó là s% foo% bar% không s% foo% bar –

Trả lời

29

sed là lựa chọn tốt cho các tệp lớn.

sed -i.bak -e 's%C://temp%//home//some//blah%' large_file.sql 

Đó là lựa chọn tốt vì không đọc toàn bộ tệp cùng lúc để thay đổi. Trích dẫn hướng dẫn:

Một biên tập dòng được sử dụng để thực hiện biến đổi văn bản cơ bản trên một đầu vào dòng (một tập tin hoặc thông tin từ một đường ống dẫn ). Mặc dù theo một số cách tương tự như đối với trình chỉnh sửa cho phép chỉnh sửa kịch bản (chẳng hạn như ed), sed hoạt động theo số chỉ thực hiện một lần qua đầu vào và do đó hiệu quả hơn . Nhưng khả năng của sed là văn bản lọc trong một đường ống mà đặc biệt phân biệt với các loại trình chỉnh sửa khác.

Phần hướng dẫn có liên quan là here. Một lời giải thích nhỏ sau

-i.bak cho phép trong việc biên tập nơi để lại một bản sao lưu với phần mở rộng bak

s% foo% thanh% sử dụng s, lệnh thay thế, mà sản phẩm thay thế các trận đấu của chuỗi đầu tiên ở giữa dấu%, 'foo', cho chuỗi thứ hai , 'thanh'. Nó thường được viết là s // nhưng vì các chuỗi của bạn có nhiều dấu gạch ngang , nên thuận tiện hơn để thay đổi chúng cho một thứ khác để bạn tránh phải thoát chúng.

Ví dụ

 
[email protected]:~$ sed -i.bak -e 's%C://temp%//home//some//blah%' a.txt 
[email protected]:~$ more a.txt 
//home//some//blah 
D://temp 
//home//some//blah 
D://temp 
[email protected]:~$ more a.txt.bak 
C://temp 
D://temp 
C://temp 
D://temp 
+2

Bạn có thể sử dụng một ký tự khác để tránh phải trích dẫn các dấu gạch chéo, ví dụ sed -e "s% C: // temp%/home // some // blah% ". Ngoài ra, tùy chọn -i cho phép bạn lưu tập tin tại chỗ, khi bạn chắc chắn về các tùy chọn. – dalloliogm

+0

Đây là lệnh tôi đang nhập: sed -i.bak -e 's% C: \\ tạm thời \%/home/liveon/public_html/tmp' liveon.sql và đây là lỗi tôi nhận được: sed: -e biểu thứC# 1, char 41: unterminated 's 'lệnh Bất kỳ ai? – coderama

+0

Bạn đang thiếu% cuối cùng, lệnh này cũng là% s% foo% bar% –

1

Lệnh sed thể làm điều đó. Thay vì thoát các dấu gạch chéo, bạn có thể chọn một delimiter khác nhau (_ trong trường hợp này):

sed -e 's_c://temp/_/home//some//blah/_' file1.txt > file2.txt 
+0

bạn đã bỏ lỡ dấu gạch dưới cuối cùng: "s_c: // temp/_/home // some // blah_" – dalloliogm

+0

thanks! Bây giờ nó đã được sửa. – stefanw

4

Hãy thử sed? Một cái gì đó như:

sed 's/c:\/\/temp/\/\/home\/\/some\/\/blah/' mydump.sql > fixeddump.sql 

Thoát tất cả các dấu gạch chéo này làm cho điều này trông kinh khủng, đây là ví dụ đơn giản thay đổi foo thành bar.

sed 's/foo/bar/' mydump.sql > fixeddump.sql 

Như những người khác đã lưu ý, bạn có thể chọn dấu phân cách của riêng mình, có chức năng chặn leaning toothpick syndrome trong trường hợp này:

sed 's|c://temp\\|home//some//blah|' mydump.sql > fixeddump.sql 

Điều thông minh về sed là nó hoạt động trên một dòng thay hơn một tệp cùng một lúc, vì vậy bạn có thể xử lý các tệp lớn chỉ bằng một lượng bộ nhớ khiêm tốn.

+0

Cảm ơn Paul! Intellij Idea trở nên điên rồ và làm điều này trong hàng chục phút trong khi với sed nó chỉ mất 1 giây để thay thế dấu gạch chéo ngược với dấu gạch chéo ngược đôi trong tập tin sql của tôi. – gumkins

12

Chỉ để hoàn thành. Thay thế tại chỗ bằng cách sử dụng perl.

perl -i -p -e 's{c://temp}{//home//some//blah}g' mysql.dmp 

Không yêu cầu dấu gạch chéo ngược. ;)

+10

Xin lưu ý rằng nếu bạn sử dụng cờ '-i' mà không có phần mở rộng, bạn sẽ nhận được * không sao lưu *. Nếu bạn muốn sao lưu, hãy thử '-i.bak' sẽ thực hiện chỉnh sửa tại chỗ * và * cung cấp cho bạn bản sao lưu của bản gốc là' original.bak', khá nhiều miễn phí. – Telemachus

+0

Tôi để hệ thống điều khiển phiên bản của tôi xử lý các bản sao lưu. – jrockway

+3

@ Jrockway: điều đó thật đáng yêu đối với bạn Tôi chắc chắn, nhưng nó giả định rằng các tệp đang được đề cập nằm dưới sự kiểm soát phiên bản và bạn biết những gì -i.bak làm và đã chọn không sử dụng nó. Tôi chỉ muốn những người đề nghị chuyển đổi -i sẽ mất hai giây để giải thích sự khác biệt giữa -i và -i.bak. Nó sẽ thực sự bị tổn thương nếu các tập tin bạn chơi với không phải là dưới sự kiểm soát phiên bản và bạn thực hiện một lỗi đánh máy đơn giản (ví dụ, quên lá cờ -p). – Telemachus

3

Ngoài ra còn có tiện ích UNIX không chuẩn, rpl, thực hiện chính xác những điều mà ví dụ sed làm; tuy nhiên, tôi không chắc chắn liệu rpl có hoạt động theo chiều luồng không, do đó, sed có thể là tùy chọn tốt hơn ở đây.

+0

Heh, mỗi cơ hội, bạn có phải là bạn của nhà phát triển của rpl không?:-) –

+0

Không, không bao giờ nghe nói về anh chàng bên ngoài của util; nó có ích để thực hiện công việc thay thế hàng loạt trên một vài nghìn tệp văn bản một lần và tôi đã giữ nó trong hộp công cụ của mình. –

+0

Nó sẽ là giá trị nói * tại sao * bạn đề nghị nó trong trường hợp này (hoặc tại sao bạn có thể, kể từ khi bạn một nửa lấy lại các khuyến nghị). Đó là, thay vì chỉ ném lên tên của một tiện ích, cho chúng tôi biết những gì bạn thích về nó, xin vui lòng. – Telemachus

1
perl -pi -e 's#c://temp#//home//some//blah#g' yourfilename 

-p sẽ xử lý tập lệnh này làm vòng lặp, nó sẽ đọc dòng tệp được chỉ định bằng cách chạy tìm kiếm và thay thế regex.

-i Cờ này phải được sử dụng cùng với cờ -p. Lệnh này Perl để chỉnh sửa tập tin tại chỗ.

-e Chỉ có nghĩa là thực thi mã perl này.

Chúc may mắn

+0

cảm ơn bạn đã giải thích –

1

gawk

awk '{gsub("c://temp","//home//some//blah")}1' file 
Các vấn đề liên quan