что случилось со следующим?
make -C <kernel source root directory>/tools/perf
Существует четыре способа включить единственную цитату, которую вам нужно.
Невозможно избежать ни одной строки кавычек в пределах одной цитируемой строки. Однако можно заканчивать цитируемую строку, вставьте сбежавшую одноцитату, а затем запустите новую односимурируемую строку.
Таким образом, поставить одну цитату в середине «AB»
, используйте: 'A' \ '' B '
. Или, используя команду SED, которая вам нужна:
$ sed -r 's/,([^ ),]+)/,'\''\1'\''/g; s/,,/,'\'\'',/g' file
INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');
Вторым способом является использование двойной цитируемой строки, в этом случае можно легко вставить одноцитату:
$ sed -r "s/,([^ ),]+)/,'\1'/g; s/,,/,'',/g" file
INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');
Эта проблема с двойными цитируемыми строками состоит в том, что Оболочка делает обработку на них. Здесь, однако, нет активных символов, поэтому это легко.
Третий метод состоит в том, чтобы использовать Hex Escape, поскольку PM2RING демонстрирует.
Четвертый путь, предложенный в комментариях Джонатана Лейффлера, заключается в том, чтобы разместить команды SED
в отдельном файле:
$ cat script.sed
s/,([^ ),]+)/,'\1'/g
s/,,/,'',/g
$ sed -rf script.sed file
INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');
Таким образом, имеет сильное преимущество SED
Команды непосредственно без каких-либо помех от оболочки. Следовательно, это полностью избегает необходимости избежать активных символов оболочки и позволяет вводить команды в чисто SED
синтаксис .
SED
решение . Хитрость состоит в том, чтобы положить отдельные цитаты вокруг запятых строк, которые вы хотите, но не вокруг остальных. Основываясь на одном примере, который вы дали, вот один подход:
S /, ([^),] +) /, '\ 1' / G
Это ищет одно или несколько несобностей, не -COMMA и не закрытые символы, которые следуют за запятую. Эти символы размещаются внутри одиночных кавычек.
S / ,, /, '', / G
Это ищет последовательные запятые и помещает две односмысленные цитаты между ними.
, чтобы избежать дополнительных задних чехлов, вышеупомянутые выражения SED
используют расширенные регулярные выражения. С GNU они вызываются как -R
, но, с BSD, они называются -E
. Кроме того, некоторые не GNU SED
не принимают несколько команд, разделенных с запятой. Таким образом, на OSX, попробуйте:
sed -E -e "s/,([^ ),]+)/,'\1'/g" -e "s/,,/,'',/g" file
из комментариев, у нас есть следующий вход;
$ cat file3
INSERT INTO radcheck(username, attribute, op, value) VALUES (00:23:32:c2:a9:e8,'Auth-Type',':=','Accept');
и, мы хотим поставить однозначные цитаты вокруг MAC-адреса, который следует за открытым Parens. Для этого:
$ sed -r "s/\(([[:xdigit:]:]+)/('\1'/" file3
INSERT INTO radcheck(username, attribute, op, value) VALUES ('00:23:32:c2:a9:e8','Auth-Type',':=','Accept');
в любой локали, [: XDIGIT:]
будет соответствовать любой шестнадцатеричной цифре. Таким образом, ([[: xDIGIT:]:] +)
будет соответствовать MAC-адресу (Hex Digit или Colon).
Попробуйте:
SED 'S / ,, /, \ x27 \ x27, /'
\ x27
- это код Escape Hex для
DEMO
$ echo 'INSERT INTO `radcheck`(`id`, `username`, `attribute`, `op`, `value`) VALUES (,,00:23:32:c2:a9:e8,Auth-Type,:=,Accept);' |
> sed 's/,,/,\x27\x27,/'
INSERT INTO `radcheck`(`id`, `username`, `attribute`, `op`, `value`) VALUES (,'',00:23:32:c2:a9:e8,Auth-Type,:=,Accept);
Когда вы работаете глобально, вы должны подумать о том, как sed
читает. Лобальная замена g
разделит пространство шаблонов на отдельные поля, разделенные в соответствии с вашими спецификациями, и будет работать с каждым из них. Разделители распознаются слева направо - в порядке их считывания - и sed
применит каждое действие, как только это будет возможно. Вот единственное утверждение s///
ubstitution, которое может делать то, что вы просите:
sed "s/\(([^)]*)[^,]*\)\{0,1\},\([^,)]*\)/\1,'\2'/g
" <<\IN
INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,,00:23:32:c2:a9:e8,Auth-Type,:=,Accept);
When run, that print:
INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');
Here's how:
\(((([^)]*)[^,]*\)\{0,1\}
- Самое важное - это распределение *
zero+ совпадений и другого вида. Весь этот блок необязателен - sed
будет счастливо сопоставлять нулевую строку на своем месте при такой возможности - и на самом деле делает это часто, иначе это вообще не сработало бы. Но так как используется \{0,1\}
sed
, то не будет совпадать больше , чем целая последовательность, подобная этой. И поэтому распределение важно. Внутри этого блока мы имеем:
(
- хотя бы один левый родитель. [^)]*
- ноль+ не-правых парен. )
- один правый родитель[^,]*
- ноль+ не-комм. sed
будет соответствовать каждой из них по порядку - и как блок, потому что они \(
сгруппированы\)
. Совпадение *
zero+ является очень важным в глобальном масштабе - если вы используете +
хотя бы одну из этих настроек, то вы резко снижаете эффективность применяемых вами правок. Для простого ввода блока выше, sed
разделяет вашу строку таким образом:
INSERT INTO radcheck
- Эта строка приходит до любого из наших совпадений и не содержит ни одного из них. Она игнорируется.
(id, имя пользователя, атрибут, оп, значение) VALUES (
- Эта строка составляет весь наш дополнительный блок совпадений *
. Сначала sed
совпадает с (
), затем вся строка [^)]*
, затем )
и последняя - и это важно - вся строка [^,]*
, которая переносит нас за еще один случай совпадения для (
). Теперь она не может совпасть - и поэтому пропустите следующую (
) для этой необязательной группы совпадений. sed
попробует вместо этого следующую. И пока sed
применяет замены для \2
во второй последовательности (...,..)
, она будет по-прежнему применять замены для \1
, так как она все еще совпадает с \1
. Впервые я сравнил \1
как весь (...,...)...(
) блок, сохранил его в \1
и заменил на \1
- на себя. От начала второй последовательности до следующей происходящей (
sed
заменит \1
на нулевую строку каждый раз, когда она совпадает с одной - то есть каждый раз, когда она совпадает с запятой.
Учитывая множество последовательностей, подобных этой, на строке - и учитывая, что запятые встречаются только внутри разделителей (
)
, sed
будет поочередно кавычки для каждой из последовательностей. Вот Ваш пример несколько раз:
INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');INSERT INTO radcheck(id, username, attribute, op, value) VALUES (,'','00:23:32:c2:a9:e8','Auth-Type',':=','Accept');
,\([^,)]*\)
- обратите внимание, что единственным дополнительным совпадением не для всего регекса является запятая ,
. Другой блок встречается перед ним в выражении и во входе, поэтому sed
позволяет его применить - но запятая имеет приоритет, когда все остальное равно, и это единственная причина, по которой sed
не вставляет ''
везде, так как все нуль-строки между каждым байтом на двух других блоках совпадают не с нуль-строками при применении - sed
разделителей на ней. sed
будет продолжать совпадать с \2
- и сохранит к нему - каждую последовательность символов, которые не являются )
, а не ,
. Каждая запятая будет заменена на встречу с , '\2'
. Так будет продолжаться до тех пор, пока не встретится с (
, после чего можно будет заполнить \1
, и так будет сделано.