sed với nhiều biểu hiện cho tranh luận tại chỗ


23

Tôi đang cố gắng thay thế nhiều từ trong tệp bằng cách sử dụng sed -i #expression1 #expression2

tập tin

Something  123 item1
Something  456 item2
Something  768 item3
Something  353 item4

Đầu ra (Mong muốn)

anything  123 stuff1
anything  456 stuff2
anything  768 stuff3
anything  353 stuff4

Dùng thử

Tôi có thể nhận được đầu ra sau bằng cách sử dụng sed -i2 lần.

 sed -i 's/Some/any/g' file
 sed -i 's/item/stuff/g' file

Tôi có thể có bất kỳ cách nào có thể để thực hiện điều này dưới dạng một lệnh tại chỗ như

sed -i 's/Some/any/g' -i 's/item/stuff/g' file

Khi tôi thử mã ở trên, nó sẽ s/item/stuff/glà một tệp và thử làm việc với nó ..


Nếu các tệp của bạn giống với ví dụ ở trên (nghĩa là chúng theo cùng một mẫu), bạn có thể thực hiện với một thay thế duy nhất:sed - i 's/Some\(.*\)item/any\1stuff/' file
don_crissti

Câu trả lời:


26

Tùy thuộc vào phiên bản sedtrên hệ thống của bạn, bạn có thể làm được

sed -i 's/Some/any/; s/item/stuff/' file

Bạn không cần gdấu gạch chéo cuối cùng trong slệnh ở đây, vì bạn chỉ thực hiện một thay thế trên mỗi dòng.

Cách khác:

sed -i -e 's/Some/any/' -e 's/item/stuff/' file

Các -itùy chọn kể sedđể chỉnh sửa tập tin tại chỗ; nếu có các ký tự ngay sau -iđó thì sedtạo bản sao lưu của tệp gốc và sử dụng các ký tự đó làm phần mở rộng của tệp sao lưu. Ví dụ,

sed -i.bak 's/Some/any/; s/item/stuff/' file

hoặc là

sed -i'.bak' 's/Some/any/; s/item/stuff/' file

sẽ sửa đổi file, lưu bản gốc vào file.bak.

Tất nhiên, trên hệ thống Unix (hoặc giống Unix), chúng ta thường sử dụng '~' thay vì '.bak', vì vậy

sed -i~ 's/Some/any/;s/item/stuff/' file

2
Lưu ý rằng bạn đang mô tả biến thể GNU. Biến thể BSD (như trong FreeBSD hoặc OS / X) yêu cầu một đối số cho -i. Vì vậy sed -i '' 's/a/b/;s/c/d/' filehoặc sed -i .back 's/a/b/;s/c/d/'hoặc sed -i.back 's/a/b/;s/c/d/'ở đó. Các sedtriển khai khác thường không hỗ trợ -i.
Stéphane Chazelas

Cảm ơn @ StéphaneChazelas đã làm rõ điều đó. Và tôi đoán tôi nên rõ ràng hơn khi nói rằng trong GNU sed không thể có khoảng cách giữa -iphần mở rộng và phần mở rộng.
PM 2Ring

sed -i 's/$username = "root"/$username = "newuser"/; s/$password = "password"/$password = "passwd"/; s/$dbname="handicraftstore"/$dbname="handicraft"' Web/database.phpkết quả sed: -e expression #1, char 141: unterminated s 'lệnh`
alrcal

@alhelal Xin lỗi, ý kiến ​​không phải là nơi thích hợp để đặt câu hỏi. Nhưng dù sao, slệnh cuối cùng của bạn đang thiếu cuối cùng của nó /.
PM 2Ring

@ PM2Ring vì tôi không nhận thấy rằng tôi đoán nó có liên quan đến giải pháp của bạn. Tuy nhiên, cảm ơn bạn.
alrcal

10

Bạn có thể xâu chuỗi các biểu thức sed cùng với ";"

%sed -i 's/Some/any/g;s/item/stuff/g' file1
%cat file1
anything  123 stuff1
anything  456 stuff2
anything  768 stuff3
anything  353 stuff4

5

Nhiều biểu thức sử dụng nhiều -etùy chọn:

sed -i.bk -e 's/Some/any/g' -e 's/item/stuff/g' file

hoặc bạn có thể sử dụng chỉ một:

sed -i.bk -e 's/Some/any/g;s/item/stuff/g' file

Bạn nên cung cấp một phần mở rộng cho tệp sao lưu, vì khi một số triển khai sed, như OSX sed không hoạt động với phần mở rộng trống (Bạn phải sử dụng sed -i ''để ghi đè các tệp gốc).


1

Bạn có thể sử dụng Vim trong chế độ Ex:

ex -sc '%s/Some/any/|%s/item/stuff/|x' file
  1. % chọn tất cả các dòng

  2. s thay thế

  3. x lưu và đóng

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.