Làm cách nào tôi có thể hướng dẫn BSD sed diễn giải các chuỗi thoát như \ n và \ t?


14

Tôi có một lệnh thay thế sed mà tôi muốn tương thích với BSD sedcũng như GNU sed. Biểu thức chính quy mở rộng không phải là vấn đề vì tôi không cần chúng trong trường hợp này. Vấn đề chính của tôi là sự khác biệt trong cách hai seds diễn giải các chuỗi ký tự thoát trong chuỗi thay thế . Chuỗi thay thế của tôi chứa các tab và dòng mới và tôi muốn chúng hiển thị trong chuỗi lệnh để dễ bảo trì, tuy nhiên, BSD sedkhông diễn giải các chuỗi thoát và GNU sed cũng vậy . Cách thích hợp để hướng dẫn seddiễn giải các chuỗi thoát này trên BSD là gì? Hai đoạn trích sau đây là điển hình cho vấn đề của tôi:

GNU sed

echo ABC | sed 's/B/\n\tB\n'

anh em

A
    B
C

BSD sed

echo ABC | sed 's/B\n\tB\n'

sản lượng

AntBnC

Thông suốt, \n\tkhông được BSD hiểu là các chuỗi thoátsed

Bây giờ, với câu hỏi của tôi. Theo BSDsed :

Để chỉ định một ký tự dòng mới trong chuỗi thay thế, trước nó có dấu gạch chéo ngược.

Có phải điều này ngụ ý rằng tôi cần phải đi trước một dòng mới theo nghĩa đen bằng dấu gạch chéo ngược? Cách thích hợp để hướng dẫn seddiễn giải các chuỗi thoát như \ntrong văn bản thay thế là gì?


2
BSD sed không phải là GNU sed và tôi không nghĩ rằng nó hỗ trợ các lối thoát như vậy trong đầu ra. Bạn sẽ phải chèn các ký tự bằng chữ, cài đặt GNU sed hoặc chuyển sang thứ gì đó hỗ trợ các lối thoát như awk.
jw013

@ jw013, tôi rõ về sự khác biệt giữa hai. Cài đặt GNU sed không phải là một lựa chọn. Tôi đã hy vọng tìm thấy đủ điểm chung giữa hai người để hoàn thành những gì tôi đang theo đuổi sed. Cuối cùng, nó có thể có ý nghĩa để sử dụng awk. Vì vậy, bạn nghĩ gì về việc giải thích các trang web BSD sed tôi đã trích dẫn?
ephsmith

2
Có, bạn sẽ cần sử dụng các tab theo nghĩa đen và dòng mới, và với dòng mới, bạn cũng cần đặt trước chúng bằng dấu gạch chéo ngược, về cơ bản chỉ là một cơ chế tiếp tục dòng.
jw013

@ jw013, cảm ơn bạn đã trả lời tuyệt vời. Tại thời điểm này, để bảo trì vì lợi ích, tôi sẽ lấy lời khuyên của bạn và làm lại giải pháp của tôi trong awk.
ephsmith

Lựa chọn tốt - awk là một kế hoạch tốt hơn nhiều so với câu trả lời hiện đang được chấp nhận :)
jw013

Câu trả lời:


6

Nếu bạn cần viết các tập lệnh di động, bạn nên bám vào các tính năng trong tiêu chuẩn POSIX (còn gọi là Unix đơn hay còn gọi là Đặc tả cơ sở nhóm mở). Vấn đề 7 hay còn gọi là POSIX-1.2008 là mới nhất, nhưng nhiều hệ thống vẫn chưa hoàn thành việc áp dụng nó. Vấn đề 6 hay còn gọi là POSIX-1.2001 được cung cấp bởi tất cả các đơn vị hiện đại.

Trong sed , ý nghĩa của các chuỗi thoát như \t\nkhông phải là di động, ngoại trừ trong regex , \nlà viết tắt của một dòng mới. Trong văn bản thay thế cho một slệnh,\n không có khả năng di động, nhưng bạn có thể sử dụng chuỗi backslash-newline để thay thế cho một dòng mới.

Một cách di động để tạo một ký tự tab (hoặc bất kỳ ký tự nào khác được biểu thị bằng số bát phân) là với tr. Lưu trữ ký tự trong một biến shell và thay thế biến này trong đoạn mã sed.

tab=$(echo | tr '\n' '\t')
escape=$(echo | tr '\n' '\033')
embolden () {
  sed -e 's/^/'"$escape"'[1m/' -e 's/$/'"$escape"'[0m/'
}

Một lần nữa lưu ý rằng các dòng mới cần được thể hiện khác nhau trong các biểu thức chính quy và trong scác văn bản thay thế.

Bạn có thể muốn sử dụng awk thay thế. Nó cho phép thoát dấu gạch chéo ngược, bao gồm thoát bát phân \ooo, trong mỗi chuỗi ký tự.


7

Bạn có thể sử dụng $'...'trích dẫn bash để diễn giải các lối thoát trước khi chuyển chuỗi sangsed .

Từ trang bash man:

   Words  of  the  form  $'string'  are  treated specially.  The word
   expands to string, with backslash-escaped characters  replaced  as
   specified  by the ANSI C standard.  Backslash escape sequences, if
   present, are decoded as follows:
          \a     alert (bell)
          \b     backspace
          \e     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \'     single quote
          \nnn   the eight-bit character whose  value  is  the  octal
                 value nnn (one to three digits)
          \xHH   the eight-bit character whose value is the hexadeci-
                 mal value HH (one or two hex digits)
          \cx    a control-x character

   The expanded result is single-quoted, as if the  dollar  sign  had
   not been present.

   A  double-quoted  string  preceded by a dollar sign ($) will cause
   the string to be translated according to the current  locale.   If
   the  current locale is C or POSIX, the dollar sign is ignored.  If
   the string is translated and replaced, the replacement is  double-
   quoted.

3

Điều này đã được trả lời trên Stack Overflow:

/programming/1421478/how-do-i-use-a-new-line-replocation-in-a-bsd-sed

Đó là khá nhiều chính xác những gì jw013 nói.

Để chèn một loại thẻ chữ ctrl+ VTab.


cảm ơn đã tham khảo. Tôi ghét rằng các tìm kiếm google của tôi đã không trả về liên kết đó: D
ephsmith

1
Đề xuất tab ctrl-V phụ thuộc vào vỏ, ví dụ, nó sẽ không hoạt động trong cá.
anddam

Chưa bao giờ sử dụng cá tôi không biết, nhưng thật tốt khi biết.
bahamat
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.