Как избежать двойных кавычек внутри двойных кавычек?
Кто-нибудь может показать мне, как избежать двойных кавычек внутри двойной строки в 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