Як уникнути єдиної цитати всередині awk


111

Я хочу зробити наступне

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

Але уникнути єдиної цитати таким чином не виходить

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

Як це зробити? Дякуємо за допомогу.


Кілька мов уникнути цитат, поставивши дві з них підряд, можливо, спробуйте це.
joshuahealy

Я спробував awk 'BEGIN {FS = "";} {printf "' '% s' '", $ 1}', але жодної цитати не було надруковано.

Ця сторінка говорить про те, що включення однієї цитати в рядок з цитуванням неможливо. Можливо, вам доведеться перетворити на подвійні лапки.
Джошуахелі

2
Це неможливо, але дві сусідні односкладові рядки оболонки склеюються в один параметр. А два одноцитовані рядки оболонки, склеєні символами, що не пробілюються, також склеюються в один великий глобус: 'abc'd'ef'це abcdef: буквальний плюс dплюс літеральний. dЗнаходиться поза лапок, і ви можете замінити , що dце з \'робити 'abc'\''ef', що оцінює до abc'ef.
Каз

Відповіді:


160

Це, можливо, те, що ви шукаєте:

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

Тобто, коли '\''ви закриєте отвір ', потім надрукуйте буквене позначення , 'уникнувши його і нарешті відкрийте 'знову.


48
Це не має нічого спільного з awk. 'Символ закриває отвір 'рядки оболонки буквально. Літерал оболонки не підтримує зворотний проріз для цього. Послідовність '\''робить трюк: він закриває одинарні лапки буквальною, указует на символ лапки (використовуючи втечу , який буде підтримуються поза одиночних лапок литералов) , а потім повторно відкриває нові одинарні лапки буквально. Ви можете розглянути це як послідовність втечі з чотирьох символів, щоб отримати єдину цитату. :)
Каз

2
@Steve: Дякую за вашу дуже корисну відповідь. Ти врятував мені багато головних болів!
John Slegers

4
@syntaxerror Те, що цитати ви використовуєте для підготовки аргументів для виклику, awk- суто питання інтерпретатора команд, який ви використовуєте для складання командних рядків. '{printf $2}'Отримує перетворилися в якій - то аргумент на користь execveсистемного виклику або аналогічний, де він просто виглядає як нуль C рядок без яких - або одинарних лапок. Awk ніколи не бачить цитат, а також sed. Ви можете фактично використовувати подвійні лапки, але подвійні лапки не перешкоджають експансії командного інтерпретатора з $2, так що ви повинні бігти знак долара з зворотної косої межі , щоб зробити його буквальним: "{printf \$2}".
Каз

4
@syntaxerror За звичаєм, вбудований сценарій awk зазвичай використовується з одинарними лапками, тому що синтаксис awk часто містить спеціальні для оболонки лексичні елементи, такі як подвійні літери, що цитуються з рядком, та нумеровані поля, позначені знаками долара. Якщо sed регулярний вираз (або будь-який інший) містить синтаксис оболонки, ви також повинні бути обережними. sed -e "s/$FOO/$BAR/"не працюватиме, якщо наміром буде замінити буквальний текст $FOOна $BAR. Найпростіше було б sed -e 's/$FOO/$BAR/.
Каз

1
@syntaxerror Якщо ви додасте програми awk у подвійні лапки, ви натрапите на багато втечі, наприклад awk "{ print \"abc\", \$1 }". Щоразу, коли в програмі awk з’являється подвійна цитата, її потрібно уникати, щоб вона не закривала цитату оболонки. І порівняйте це: awk '{print "\\"}'(роздрукуйте зворотну косу рису) та порівняну з подвійними лапками:, awk "BEGIN {print \"\\\\\" }"Phew! Обидві цитати потрібно уникати, і обидві зворотні риски. Оболонка перетворюється \\ на \ так, що нам потрібно \\\\ кодувати \\ .
Каз

76

Єдина цитата представлена ​​за допомогою \x27

Як у

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

Джерело


16
+1, але потрібно додати: \x27це розширення; POSIX Awk лише розпізнає \047. ( \47також нормально, якщо за нею не дотримується восьмерична цифра.)
hemflit

1
Як закінчується \ x27, якщо після нього є інше число?
Джейсон Аксельсон

1
Джейсоне, ви об'єднали два рядкові літерали: "AAA \ x27" "1". Або ви просто використовуєте восьмерик.
гемфліт

9
Завжди використовуйте octal ( \047), а не шістнадцятковий ( \x27), код втечі - див. Awk.freeshell.org/PrintASingleQuote .
Ед Мортон

35

Інший варіант - передавати єдину цитату як змінну awk :

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

Простіший приклад з об'єднанням рядків:

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

5
Це зрозуміло і стисло, особливо якщо вам потрібно використовувати багато цитат.
Пітер Глюк

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

1
Поки я пам’ятаю, що \047це вісімкова послідовність втечі для символу з одноцитатами, я вважаю, що ця альтернатива є найбільш читаною.
Ентоні

4

Для невеликих сценаріїв необов'язковим способом зробити його читабельним є використання такої змінної:

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

Я знайшов це звичайним у випадку, коли мені доводилося багато разів видавати символ з одною цитатою на виході, і \ 047 робили це абсолютно нечитабельним

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.