How can I escape characters in SQLite via bash shell? - bash

I am trying to send a query to SQLite from the command line using bash. I need to escape both single quotes and double quotes, and escape them so that bash does not misinterpret them. Here is a typical query:
select * from contacts where source = "Nancy's notes";
How can I send this query from the command line? The basic syntax is something like this:
sqlite3.bin contacts.db 'select * from contacts where source = "Nancy's notes"'
But in this case, the shell misinterprets either the single or double quotes. I've tried escaping using both double and triple slashes but this doesn't work. I'm befuddled. Any suggestions?

The trouble with MarkusQ's solution is knowing which characters are special inside double quotes - there are quite a lot of them, including back-ticks, dollar-open parenthesis, dollar-variable, etc.
I would suggest it is better to enclose the string inside single quotes; then, each single quote inside the string needs to be replaced by the sequence quote, backslash, quote, quote:
sqlite3.bin contacts.db 'select * from contacts
where source = "Nancy'\''s notes"'
The first quote in the replacement terminates the current single-quoted string; the backslash-quote represents a literal single quote, and the final quote starts a new single-quoted string. Further, this works with Bourne, Korn, Bash and POSIX shells in general. (C Shell and derivatives have more complex rules needing backslashes to escape newlines, and so on.)

If bash is your only problem, enclose the whole thing in double quotes and then escape anything that's special within bash double quotes with a single backslash. E.g.:
sqlite3.bin contacts.db "select * from contacts where source = \"Nancy's notes on making \$\$\$\""

Here I use two single quotes that sqlite interprets as one.
sqlite3.bin contacts.db "select * from contacts where source = 'Nancy''s notes on making \$\$\$'"

foo_double_single_quote=`echo ${foo_with_single_quote} | sed "s/\'/\'\'/"g`
sqlite3 "INSERT INTO bar_table (baz_colname) VALUES ('${foo_double_single_quote}');"
if you have a variable foo_with_single_quote whose contents you want to insert into a DB, you can use sed like so to create a variable that has the ' character duplicated as necessary.

Related

How to add $USER inside of nested quotes? [duplicate]

This question already has answers here:
Difference between single and double quotes in Bash
(7 answers)
Closed last year.
I have a variable:
my_var="$('/some/path/to/username/more/path' 'and/something/else')"
and I want to change it to be more generic like:
my_var="$('/some/path/to/${USER}/more/path' 'and/something/else')"
but that doesn't work. How can I get the user inside of there?
The problem is that inside a single quoted string nothing is treated with a special meaning. This makes them good for scripting, eg. grep '^pattern$' ... and sed 's/abc$/def/'.
You can use double quotes instead.
$(...) is a command substitution. Is that correct? If so, then you can nest double qoutes:
my_var="$("/some/path/to/${USER}/more/path" 'and/something/else')"
This should be interpreted as two set of quotes, so the outer double quotes, isn't stopped at the first inner quote:
my_var="$( )" # First set of quotes
"/some/path/to/${USER}/more/path" # Second set of quotes
When assigning a variable, you don't need to wrap the expression in double quotes, so:
my_var=$("/some/path/to/${USER}/more/path" 'and/something/else')
would also be fine in this case. Most other cases you should always wrap parameter expansions ($abc), command substitutions ($(...)) etc. in double quotes as to avoid word splitting and pathname expansions.
However to me it seems like you are trying to create an array instead?
$ my_var=("/some/path/to/${USER}/more/path" 'and/something/else')
$ echo "${my_var[0]}"
/some/path/to/and/more/path

using double quotes in bash export statement

Hello I'm reading a book about bash scripting and the author says to add the following to the end of my .bashrc file. export PATH=~/bin:"$PATH" in order to execute my file from the command line by typing its name. I notice however that if I put export PATH=~/bin:$PATH I can achieve the same result. So my question is what is the difference between the one with quotes and the one without quotes? thanks.
The quotes won't hurt anything, but neither are they necessary. Assignments are processed specially by the shell. From the man page:
A variable may be assigned to by a statement of the form
name=[value]
If value is not given, the variable is assigned the null string. All values undergo tilde expansion, parameter and variable
expansion, command substitution, arithmetic expansion, and
quote removal (see EXPANSION below).
Notice that word-splitting and pathname generation are not on the list in bold. These are the two types of expansion you are trying to prevent by quoting a parameter expansion, but in this context they are not performed. The same rules apply to the assignments that are passed to the export built-in command.
You must include the variable PATH inside double quotes. So that it would handle the filepaths which has spaces but without double quotes, it won't handle the filenames which has spaces in it.
I was facing the same with trying to assign a JSON string to a variable in the terminal.
Wrap it with Single Quotes or Double Quotes
Use single quotes, if you string contains double quotes and vice-versa.
$ export TEMP_ENV='I like the "London" bridge'
$ echo $TEMP_ENV
>> I like the "London" bridge
$ export TEMP_ENV="I like the 'London' bridge"
$ echo $TEMP_ENV
>> I like the 'London' bridge

Is there a method in shell to ignore escape characters?

In C#, there is a verbatim string so that,
string c = "hello \t world"; // hello world
string d = #"hello \t world"; // hello \t world
I am new to shell script, is there a similar method in shell?
Because I have many folders with the name like "Apparel & Accessories > Clothing > Activewear", I want to know if there is a easy way to process the escape characters without write so many .
test.sh
director="Apparel & Accessories > Clothing > Activewear"
# any action to escape spaces, &, > ???
hadoop fs -ls $director
For definining the specific string in your example, Apparel & Accessories > Clothing > Activewear, either double quotes or single quotes will work; referring to it later is a different story, however:
In the shell (any POSIX-compatible shell), how you refer to a variable is just as important as how you define it.
To safely refer to a previously defined variable without side-effects, enclose it in double quotes, e.g., "$directory".
To define [a variable as] a literal (verbatim) string:
(By contrast, to define a variable with embedded variable references or embedded command substitutions or embedded arithmetic expressions, use double quotes (").)
If your string contains NO single quotes:
Use a single-quoted string, e.g.:
directory='Apparel & Accessories > Clothing > Activewear'
A single-quoted string is not subject to any interpretation by the shell, so it's generally the safest option for defining a literal. Note that the string may span multiple lines; e.g.:
multiline='line 1
line 2'
If your string DOES contain single quotes (e.g., I'm here.) and you want a solution that works in all POSIX-compatible shells:
Break the string into multiple (single-quoted) parts and splice in single-quote characters:
Note: Sadly, single-quoted strings cannot contain single quotes, not even with escaping.
directory='I'\''m here.'
The string is broken into into single-quoted I, followed by literal ' (escaped as an unquoted string as \'), followed by single-quoted m here.. By virtue of having NO spaces between the parts, the result is a single string containing a literal single quote after I.
Alternative: if you don't mind using a multiline statement, you can use a quoted here document, as described at the bottom.
If your string DOES contain single quotes (e.g., I'm here.) and you want a solution that works in bash, ksh, and zsh:
Use ANSI-C quoting:
directory=$'I\'m here.'
Note: As you can see, ANSI-C quoting allows for escaping single quotes as \', but note the additional implications: other \<char> sequences are subject to interpretation, too; e.g., \n is interpreted as a newline character - see http://www.gnu.org/software/bash/manual/bash.html#ANSI_002dC-Quoting
Tip of the hat to #chepner, who points out that the POSIX-compatible way of directly including a single quote in a string to be used verbatim is to use read -r with a here document using a quoted opening delimiter (the -r option ensures that \ characters in the string are treated as literals).
# *Any* form of quoting, not just single quotes, on the opening EOF will work.
# Note that $HOME will by design NOT be expanded.
# (If you didn't quote the opening EOF, it would.)
read -r directory <<'EOF'
I'm here at $HOME
EOF
Note that here documents create stdin input (which read reads in this case). Therefore, you cannot use this technique to directly pass the resulting string as an argument.
use strong quotes i.e. 'string', allowing escape char or special char for string.
e.g. declare director='Apparel & Accessories > Clothing > Activewear'
also using declare is a good practice while declaring variable.

how to show single quote in single-quoted text

I have a bash script,
echo 'abcd'
in shell, I want to show ab'c'd and I have tried following approach but without success
echo 'ab\'c\'d'
I am asking is it possible to show single quote in single quoted text?
From the bash manual section on Single Quotes:
A single quote may not occur between single quotes, even when preceded by a backslash.
You'll need to use double quotes instead. It's not pretty, but the following gives the output you are looking for:
echo 'ab'"'"'c'"'"'d'
A bash-specific feature, not part of POSIX, is a $'...'-quoted string:
echo $'ab\'c\'d'
Such a string behaves identically to a single-quoted string, but does allow for a selection of \-escaped characters (such as \n, \t, and yes, \').

Ruby - Making a newline within usage of gsub

I'm a bit stuck on this issue. I'm trying to make a newline using '\n'. I'm opening a file, then replacing the text, then writing it back as an html file:
replace = text.gsub(/aaa/, 'aaa\nbbb')
But this results in:
aaa\nbbb
I'm trying to make do:
aaa
bbb
In single-quoted strings a backslash is just a backslash (except if it precedes another backslash or a quote). Use double quotes: "aaa\nbbb" .
You'll want to read:Backslashes in Single quoted strings vs. Double quoted strings in Ruby?.

Resources