Làm thế nào để thoát khỏi một câu trích dẫn duy nhất bên trong awk


110

Tôi muốn làm những điều sau

awk 'BEGIN {FS=" ";} {printf "'%s' ", $1}'

Nhưng thoát khỏi trích dẫn đơn theo cách này không hoạt động

awk 'BEGIN {FS=" ";} {printf "\'%s\' ", $1}'

làm như thế nào? Cảm ơn vì sự giúp đỡ.


Một số ngôn ngữ thoát khỏi dấu ngoặc kép bằng cách đặt hai trong số chúng liên tiếp, có thể thử điều đó.
joshuahealy

Tôi đã thử awk 'BEGIN {FS = "";} {printf "' '% s' '", $ 1}', nhưng không có trích dẫn nào được in.

Trang này nói rằng việc bao gồm một trích dẫn duy nhất trong một chuỗi được trích dẫn duy nhất là không thể. Có thể bạn sẽ phải chuyển sang dấu ngoặc kép.
joshuahealy

2
Không thể, nhưng hai chuỗi shell được trích dẫn đơn liền kề lại kết dính với nhau thành một tham số. Và hai chuỗi shell được trích dẫn đơn được dán bởi các ký tự không có khoảng trắng cũng kết dính thành một khối cầu lớn: 'abc'd'ef'abcdef: nghĩa đen cộng dvới nghĩa đen. Phần dbên ngoài của dấu ngoặc kép và bạn có thể thay thế phần dđó bằng \'để tạo 'abc'\''ef'giá trị cho abc'ef.
Kaz

Câu trả lời:


160

Đây có thể là những gì bạn đang tìm kiếm:

awk 'BEGIN {FS=" ";} {printf "'\''%s'\'' ", $1}'

Đó là, với việc '\''bạn đóng lỗ mở ', sau đó in một ký tự 'bằng cách thoát nó và cuối cùng mở 'lại.


47
Nó không liên quan gì đến awk. Ký 'tự đóng 'chuỗi shell mở theo nghĩa đen. Chữ shell không hỗ trợ thoát dấu gạch chéo ngược cho việc này. Trình tự '\''thực hiện mẹo: nó đóng ký tự trích dẫn đơn, chỉ định ký tự trích dẫn (sử dụng một lối thoát được hỗ trợ bên ngoài các ký tự trích dẫn đơn) và sau đó mở lại một ký tự trích dẫn đơn mới. Bạn có thể coi nó như một chuỗi thoát gồm bốn ký tự để nhận được một câu trích dẫn duy nhất. :)
Kaz

2
@Steve: Cảm ơn rất nhiều vì câu trả lời rất hữu ích của bạn. Bạn đã cứu tôi rất nhiều đau đầu!
John Slegers

4
@syntaxerror Những dấu ngoặc kép nào bạn sử dụng để chuẩn bị các đối số cho việc gọi awkhoàn toàn là vấn đề của trình thông dịch lệnh mà bạn đang sử dụng để soạn các dòng lệnh. Nó '{printf $2}'được biến thành một số đối số cho một execvelệnh gọi hệ thống hoặc tương tự, nơi nó trông giống như một chuỗi C kết thúc bằng rỗng mà không có bất kỳ dấu ngoặc kép nào. Awk không bao giờ thấy các dấu ngoặc kép, và sed cũng vậy. Bạn có thể trong thực tế sử dụng hai dấu ngoặc kép, nhưng dấu ngoặc kép không ngăn chặn sự bành trướng của vỏ $2, vì vậy bạn phải thoát khỏi dấu đô la với một dấu gạch chéo để làm cho nó theo nghĩa đen: "{printf \$2}".
Kaz

4
@syntaxerror Theo tùy chỉnh, một tập lệnh awk nội dòng thường được thoát bằng dấu ngoặc kép, vì cú pháp awk thường chứa các phần tử từ vựng đặc biệt đối với trình bao, chẳng hạn như các ký tự chuỗi được trích dẫn kép và các trường được đánh số được biểu thị bằng dấu đô la. Nếu một biểu thức chính quy sed (hoặc bất cứ thứ gì) chứa cú pháp shell, bạn cũng phải cẩn thận. sed -e "s/$FOO/$BAR/"sẽ không hoạt động nếu mục đích là thay thế văn bản theo nghĩa đen $FOObằng $BAR. Cách dễ nhất sẽ là sed -e 's/$FOO/$BAR/.
Kaz

1
@syntaxerror Nếu bạn đặt các chương trình awk trong dấu ngoặc kép, bạn sẽ gặp rất nhiều lỗi thoát, chẳng hạn như awk "{ print \"abc\", \$1 }". Bất kỳ khi nào một dấu ngoặc kép xuất hiện trong chương trình awk, nó phải được thoát ra để không đóng dấu ngoặc kép. Và so sánh điều này: awk '{print "\\"}'(in dấu gạch chéo ngược) so với những gì nó cần với dấu ngoặc kép : awk "BEGIN {print \"\\\\\" }", Phù! Cả hai dấu ngoặc kép phải được thoát và cả hai dấu gạch chéo ngược. Shell chuyển đổi \\ thành \ vì vậy chúng ta cần \\\\ mã hóa \\ .
Kaz

76

Một trích dẫn duy nhất được trình bày bằng cách sử dụng \x27

Giống như trong

awk 'BEGIN {FS=" ";} {printf "\x27%s\x27 ", $1}'

Nguồn


16
+1, nhưng cần thêm: \x27là phần mở rộng; POSIX Awk chỉ nhận dạng \047. ( \47Là ok quá nếu không muốn nói tiếp theo là một chữ số bát phân.)
hemflit

1
Làm thế nào để bạn kết thúc \ x27 nếu bạn có một số khác sau nó?
Jason Axelson

1
Jason, bạn nối hai chuỗi ký tự: "AAA \ x27" "1". Hoặc bạn chỉ sử dụng bát phân.
hemflit

9
Luôn sử dụng mã bát phân ( \047), không phải hex ( \x27), mã thoát - xem awk.freeshell.org/PrintASingleQuote .
Ed Morton

35

Một tùy chọn khác là chuyển một trích dẫn duy nhất dưới dạng biến awk :

awk -v q=\' 'BEGIN {FS=" ";} {printf "%s%s%s ", q, $1, q}'

Ví dụ đơn giản hơn với nối chuỗi:

# Prints 'test me', *including* the single quotes.
$ awk -v q=\' '{print q $0 q }' <<<'test me'
'test me'

5
Điều này rõ ràng và ngắn gọn, đặc biệt nếu bạn cần sử dụng nhiều dấu ngoặc kép.
Peter Gluck

18
awk 'BEGIN {FS=" "} {printf "\047%s\047 ", $1}'

1
Miễn là tôi nhớ đó \047là chuỗi thoát bát phân cho ký tự dấu ngoặc đơn, tôi thấy thay thế này là dễ đọc nhất.
Anthony Geoghegan

4

Đối với các tập lệnh nhỏ, một cách tùy chọn để làm cho nó có thể đọc được là sử dụng một biến như sau:

awk -v fmt="'%s'\n" '{printf fmt, $1}'

Tôi tìm thấy nó tiện lợi trong trường hợp tôi phải tạo nhiều lần ký tự dấu ngoặc kép trong đầu ra và \ 047 làm cho nó hoàn toàn không thể đọc được

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.