Как избежать двойных кавычек внутри двойных кавычек?

Кто-нибудь может показать мне, как избежать двойных кавычек внутри двойной строки в bash?

Например, в моем сценарии оболочки

#!/bin/bash

dbload="load data local infile \"'gfpoint.csv'\" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY \"'\n'\" IGNORE 1 LINES"

Я не могу получить ЗАКРЫТЫЙ ПО \" с двойной кавычкой корректно Я не могу использовать одинарные кавычки для моей переменной, потому что я хочу использовать переменную $dbtable,

10 ответов

Используйте обратную косую черту:

echo "\""     # Prints one " character.

Простой пример экранирования кавычек в оболочке:

$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc

Это делается путем отделки уже открытой одной ('), размещение сбежавшего (\'), затем открыв еще один (').

В качестве альтернативы:

$ echo 'abc'"'"'abc'
abc'abc
$ echo "abc"'"'"abc"
abc"abc

Это делается путем отделки уже открытой одной ('), разместив цитату в другой цитате ("'"), затем открыв еще один (').

Дополнительные примеры: экранирование одинарных кавычек в одиночных кавычках

Я не знаю, почему эта старая проблема всплыла сегодня в списках с тегами bash, но на всякий случай для будущих исследователей, имейте в виду, что вы можете избежать побега, используя ascii-коды символов, которые вам нужно отобразить. Пример:

echo -e "this is \x22\x27\x22\x27\x22text\x22\x27\x22\x27\x22"                                                                                                          
this is "'"'"text"'"'" 

\x22 это код ASCII (в шестнадцатеричном виде) для двойных кавычек и \x27 для одинарных кавычек. Точно так же вы можете повторить любой символ.

Я полагаю, если мы попытаемся отразить указанную выше строку с помощью обратной косой черты, нам понадобится беспорядочный эхо с двумя строками обратной косой черты...:)

Для присвоения переменной это эквивалентно:

$ a=$'this is \x22text\x22'                                                                                                                                               
$ echo "$a"                                                                                                                                                               
this is "text"

Если переменная уже установлена ​​другой программой, вы все равно можете применять двойные / одинарные кавычки с помощью sed или аналогичных инструментов. Пример:

$ b="just another text here"
$ echo "$b"
just another text here
$ sed 's/text/"'\0'"/' <<<"$b" #\0 is a special sed operator
just another "0" here #this is not what i wanted to be
$ sed 's/text/\x22\x27\0\x27\x22/' <<<"$b"
just another "'text'" here #now we are talking. You would normally need a dozen of backslashes to achieve the same result in the normal way.

Bash позволяет размещать строки рядом друг с другом, и в итоге они будут склеены.

Итак, это:

$ echo "Hello"', world!'

производит

Hello, world!

Хитрость заключается в чередовании одинарных и двойных кавычек по мере необходимости. К сожалению, это быстро становится очень грязным. Например:

$ echo "I like to use" '"double quotes"' "sometimes"

производит

I like to use "double quotes" sometimes

В вашем примере я бы сделал это примерно так:

$ dbtable=example
$ dbload='load data local infile "'"'gfpoint.csv'"'" into '"table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"'"'"' LINES "'TERMINATED BY "'"'\n'"'" IGNORE 1 LINES'
$ echo $dbload

который производит следующий вывод:

load data local infile "'gfpoint.csv'" into table example FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY "'\n'" IGNORE 1 LINES

Трудно увидеть, что здесь происходит, но я могу аннотировать это с помощью кавычек Unicode. Следующее не будет работать в bash - это просто для иллюстрации:

dbload='load data local infile """'gfpoint.csv'""" into""table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"""""' LINES""TERMINATED BY """'\n'""" IGNORE 1 LINES'

Кавычки, подобные "'" в приведенном выше, будут интерпретироваться bash. Цитаты как " ' будет в конечном итоге в переменной.

Если я приведу ту же процедуру в предыдущем примере, это будет выглядеть так:

$ echo"I like to use"'"double quotes"'"sometimes"

Сохраните символ двойной кавычки как переменную:

DQT ='"'
echo "Двойные кавычки ${dqt}X${dqt} внутри строки в двойных кавычках"

Выход:

Двойные кавычки "X" внутри строки в двойных кавычках 

Проверить printf...

#!/bin/bash
mystr="say \"hi\""

Без использования printf

echo -e $mystr

выход: сказать "привет"

Использование printf

echo -e $(printf '%q' $mystr)

вывод: скажи \"привет \"

Используйте $"string".

В этом примере это было бы,

dbload = $ "загрузить данные локального файла \"'gfpoint.csv'\"в таблицу $dbtable ПОЛЯ, ПРЕКРАЩАЕМЫЕ ',' ЗАКЛЮЧЕНЫ \ '' ЛИНИЯМИ, ПРЕКРАЩЕНЫМИ \"'\n'\" IGNORE 1 LINES"

Примечание (со страницы руководства):

Строка в двойных кавычках, перед которой стоит знак доллара ($"string"), приведет к переводу строки в соответствии с текущей локалью. Если текущим языковым стандартом является C или POSIX, знак доллара игнорируется. Если строка переведена и заменена, замена заменяется двойными кавычками.

Для использования с переменными, которые могут содержать пробелы в сценарии Bash, используйте тройные кавычки внутри основной кавычки, например:

      [ "$(date -r """$touchfile""" +%Y%m%d)" -eq "$(date +%Y%m%d)" ]

Как насчет использованияecho.

Например,

      x=$(echo \"a b c\")

Чтобы использовать переменную,

      echo $x && ls "$x"

Причина, по которой я предпочитаю echo, а не printf, заключается в том, что это более просто.

Добавлять "\" перед двойной кавычкой, чтобы избежать этого, вместо \

#! /bin/csh -f

set dbtable = balabala

set dbload = "load data local infile "\""'gfpoint.csv'"\"" into table $dbtable FIELDS TERMINATED BY ',' ENCLOSED BY '"\""' LINES TERMINATED BY "\""'\n'"\"" IGNORE 1 LINES"

echo $dbload
# load data local infile "'gfpoint.csv'" into table balabala FIELDS TERMINATED BY ',' ENCLOSED BY '"' LINES TERMINATED BY "''" IGNORE 1 LINES
Другие вопросы по тегам