Экранирование обратной косой черты с помощью awk в OSX

Я пытаюсь сопоставить \ N в поле файла csv.

Я пробовал

awk -F "|" '($12=="\N") {print}' ./filename.csv
awk -F "|" '($12==\N) {print}' ./filename.csv
awk -F "|" '($12==\\N) {print}' ./filename.csv
awk -F "|" '($12==\\\\N) {print}' ./filename.csv

пока ничего не работает

0
02.12.2016, 22:52
1 ответ

В стиле Борна (например, bash ) , В оболочках, подобных Csh или rc, используйте:

awk -F'|' '$12 == "\\N"'

В строках awk обратная косая черта используется для введения C-подобных escape-последовательностей, таких как \ b для обратного пробела, \ n для новая строка, \ 123 для восьмеричных последовательностей ... Вам понадобится \\ для самой обратной косой черты. \ N в настоящее время не является известной управляющей последовательностью ни в одной известной мне реализации awk .

Некоторые реализации awk будут обрабатывать "\ N" как \ и N , некоторые как N , некоторые (gawk) вроде N с предупреждением. POSIX оставляет поведение неопределенным.

Обратите внимание, что это также относится к строкам, передаваемым как:

awk -F'|' -v value='\\N' '$12 == value'

Или:

awk -F'|' '$12 == value' value='\\N'

Вы можете использовать среду для передачи значения как есть, не беспокоясь об экранировании специальных символов для awk (и позволяет избежать проблем с GNU awk 4.2 или выше, где обрабатывает значения, начинающиеся с @ / и заканчивающиеся на / , особенно ):

VALUE='\N' awk -F'|' '$12 == ENVIRON["VALUE"]'

Это также относится к литералам регулярных выражений, которые выражаются как /.../ , как в:

awk -F'|' '$12 ~ /\\N/'

Однако это еще больше усложняется тем фактом, что обратная косая черта перегружается как вводный элемент escape-последовательности ( для \ n , \ b ...) и в качестве оператора цитирования для регулярных выражений ( \. или \ $ ... чтобы удалить их особое значение оператора регулярного выражения). POSIX в настоящее время неясен (и даже не соответствует действительности в некоторых случаях) в некоторых случаях (например, на /\\./ или / \ 56 / или / [\ 135] / ). Опять же, использование ENVIRON может помочь, хотя и не всегда. Например:

R='[\]' awk '$0 ~ ENVIRON["R"]'

предназначен для сопоставления с обратной косой чертой в POSIX, но возвращает ошибку во всех известных мне реализациях awk . Лучше всегда избегать \ даже внутри [...] , если понимать это буквально, на всякий случай.

Обратите внимание, что для раковины fish вам понадобится еще один слой экранирования, как для fish (в отличие от большинства других раковин), \ является особенным в одиночном цитаты. Итак, вам нужно:

awk -F'|' '$12 == "\\\\N"'

там. Хотя

awk -F'|' '$12 == "\\\N"'

тоже будет работать.

env 'V=\N' awk -F'|' '$12 == ENVIRON["V"}'

также должно работать (в fish и других семействах раковин).

3
28.01.2020, 02:34

Теги

Похожие вопросы