Я использую оболочку 'bash' и выполняю нижеприведенную команду 'awk' на файле с записями файла, разделенными различными символами, такими как скобки, двоеточия, круглые скобки, как показано ниже
...(field#13[field#14:]]:filed#18[filed#19)[...
Однако, когда я экранирую "][" с помощью одинарной скобки '\', команда awk не работает, и я должен дважды экранировать скобки '\\\', чтобы получить ожидаемый результат, как нужно использовать двойную скобку (в оболочке 'csh' это то же самое)?
awk -F"[\\[\\]:)(]" '{print $18}' inFile
filed#18
также, пожалуйста, обратите внимание, что я знаю, что для всех я могу избежать их с двойным escape '\\\', как ниже, я просто хочу знать, почему для Brackets это обязательно?
awk -F"[\\[\\]\\:\\)\\(]" '{print $18}' inFile
filed#18
даже использование signle escape дает предупреждение (кроме Brackets), но все равно команда execeute и результат приходит, спасибо
awk -F '[\\[\\]\:\)\(]' '{print $18}' inFile
awk: warning: escape sequence `\:' treated as plain `:'
awk: warning: escape sequence `\)' treated as plain `)'
awk: warning: escape sequence `\(' treated as plain `('
filed#18
Существует несколько уровней заключения в кавычки/выхода продолжения здесь. Во-первых, у Вас есть Ваш FS
regex (-F "[\\[\\]\:\)\(]"
) в двойных кавычках. Это - то, что дает предупреждения:
$ awk -F"[\\[\\]:)(]" '{print $2}' file
awk: warning: escape sequence `\[' treated as plain `['
awk: warning: escape sequence `\]' treated as plain `]'
awk: fatal: :, [., or [=: /[[]:)(]/
В то время как одинарные кавычки просто работают:
$ awk -F'[\\[\\]:)(]' '{print $2}' file
field#13
Поэтому что-либо в двойных кавычках сначала расширено оболочкой. Так, оболочка сначала расширяется \\[
кому: \[
и затем передачи это к awk. Вы видите этот случай с set -x
:
$ set -x
$ awk -F"[\\[\\]:)(]" '{print $2}' file
+ awk '-F[\[\]:)(]' '{print $2}' file
Как Вы видите выше, оболочка съела первый Escape. Не используйте "
здесь вообще.
Следующий выпуск - то, что сам awk интерпретирует Escape дважды. Поскольку -F
может принять специальные Escape как \t
и \r
и т.д. это сначала попытается читать \[
как единственный, завершенный символ. С тех пор \[
совпадает с [
(в отличие от этого, сказать \n
который не является тем же как n
с тех пор \n
новая строка), она дает Вам предупреждающее сообщение, объясняя, что она рассматривала \[
как [
.
Так, Вам нужен первый Escape для выхода \
самостоятельно, и второй Escape для выхода [
. Другими словами, в \\[
, 1-е \
выходит из второго \
так, чтобы, что awk
наконец получает, \[
.
Могло бы быть легче понять, рассматриваете ли Вы что-то вроде этого:
$ echo -e 'a\tb'
a b ## prints a tab character
$ echo -e 'a\\tb'
a\tb ## prints a literal \t
$ echo -e "a\\tb"
a b ## prints a tab because of the double quotes
$ echo -e "a\\\tb"
a\tb ## 3ple escaping! Prints a literal `\t` again.
Последним примером выше является большая часть сообщения. Так как строка, которая будет отражена, находится в двойных кавычках, она расширена оболочкой сначала (который ест тот \
), затем echo -e
(который ест другого \
) и наконец печатается как литерал \t
.