Làm thế nào để thay thế dấu ngoặc kép trong một tập tin với sed?


10

Tôi có một tệp chứa nhiều dòng xml. Tôi muốn thay thế một số phần của tập tin. Một số phần của tệp chứa dấu ngoặc kép ( ") mà tôi muốn thay thế. Tôi đã cố gắng thoát khỏi dấu ngoặc kép \, nhưng tôi không nghĩ rằng nó hoạt động dựa trên kết quả của tệp của tôi.

Đây là một ví dụ về một trong những lệnh sed của tôi:

sed -e "s/\"text\"/'text'/ig" file.xml > temp.tmp

Đây có phải là cách bạn thoát dấu ngoặc kép trong một lệnh sed hay tôi đang làm gì đó sai?


2
Lệnh của bạn có vẻ đúng để thay thế "text"bằng 'text'. Tất nhiên nó sẽ không làm gì cả "othertext". Hiển thị một vài dòng đầu vào, đầu ra không mong muốn tương ứng và giải thích đầu ra bạn muốn thay thế.
Gilles 'SO- đừng trở nên xấu xa'

Vì vậy, \"cách chính xác để thoát dấu ngoặc kép trong lệnh sed?
jbranchaud

4
Không dành cho sed: sed không cần, hoặc hỗ trợ, trốn thoát ". Nhưng lệnh shell của bạn sử dụng một chuỗi trích dẫn kép và \"đúng ở đó. Các sedchương trình coi s/"text"/'text'/ignhư là đối số để -e.
Gilles 'SO- đừng trở nên xấu xa'

@Gilles Còn không gian thì sao? Liệu sed có hiểu và tôn trọng khoảng trắng? Ví dụ, nếu lệnh của tôi chứa s/\"text\" /'text'/igNó sẽ chỉ tìm thấy "text" với khoảng trắng sau nó?
jbranchaud

3
Không gian phải khớp chính xác. Thay vì tiếp tục cuộc đối thoại này, tôi khuyên bạn nên đăng một số đầu vào mẫu và đầu ra mong muốn tương ứng (và có lẽ giải thích lý do tại sao bạn cần thay đổi trích dẫn). Thậm chí không rõ ràng đó sedlà công cụ phù hợp cho công việc, có thể bạn muốn một trình phân tích cú pháp XML.
Gilles 'SO- đừng trở nên xấu xa'

Câu trả lời:


11

Hai lời khuyên:

  1. Bạn không thể thoát khỏi một trích dẫn trong một chuỗi trích dẫn với các trích dẫn đơn. Vì vậy, bạn phải đóng báo giá, thêm một trích dẫn thoát, sau đó mở lại báo giá. Đó là : 'foo'\''bar', phân tích thành:

    • 'foo'        trích dẫn foo
    • \'             trốn thoát '
    • 'bar'        trích dẫn bar

    năng suất foo'bar.

  2. (tùy chọn) Bạn không nhất thiết phải sử dụng /trong sed. Tôi thấy rằng việc sử dụng /\trong cùng một biểu hiện sed làm cho nó khó đọc.

Ví dụ: để xóa các trích dẫn khỏi tệp này:

$ cat /tmp/f
aaa"bbb"'ccc'aaa

Đưa ra hai lời khuyên của tôi ở trên, lệnh bạn có thể sử dụng để xóa cả dấu ngoặc kép và dấu ngoặc đơn là:

$ sed -e 's|["'\'']||g'  /tmp/f

Dựa trên mẹo đầu tiên của tôi, shell giảm đối số thứ hai của sed (nghĩa là chuỗi sau -e) sang s|["']||gvà chuyển chuỗi đó sang sed. Dựa trên mẹo thứ hai của tôi, sed đối xử với điều này giống như s/['"]//g. Nó có nghĩa là

xóa tất cả các ký tự khớp với 'hoặc "   (nghĩa là thay thế chúng bằng không có gì)

Bạn có thể cần một cái gì đó phức tạp hơn thế này để làm những gì bạn muốn, nhưng đó là một sự khởi đầu.


1
Để đặt một điểm tốt hơn trên mẹo thứ hai của bạn: bạn có thể sử dụng bất kỳ ký tự nào thay thế / khi sử dụng các lệnh s và y, có thể trong số các lệnh khác. Khi sử dụng biểu thức chính quy với các lệnh sed khác, dấu phân cách đầu tiên (nếu sử dụng thay thế cho /) phải được thoát. Dấu phân cách ưa thích của bạn cũng phải được thoát nếu bạn đang cố khớp nó trong biểu thức chính quy.
Eli Heady

Thật khó để trộn các trích dẫn đơn và dấu ngoặc kép mà không bị lộn xộn. Một số người thấy dễ đọc hơn nếu bạn trích dẫn các trích dẫn đơn, bằng cách đặt chúng trong dấu ngoặc kép, thay vì thoát chúng. Vì vậy, thay vì 'foo'\''bar', chúng tôi có thể sử dụng 'foo'"'"'bar'.
Scott

1

Tôi có một cổng Windows của các tiện ích unix để các lệnh trông hơi khác một chút nhưng tôi có một tệp csv với dấu phẩy và dấu ngoặc kép. Sử dụng chủ đề này như một hướng dẫn, tôi đã có thể loại bỏ các trích dẫn thông qua lệnh này:

c:\Temp> cat report.csv | sed "s/\,/\ /g" | sed "s/[""]//g"

cảm ơn! đã bị mắc kẹt trên này!
gửi tiền
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.