Escaping quotes in bash (Embedded awk)
The easiest way to deal with this problem is to avoid it. Don't bother trying to escape your script to go on a command line: Pass it on stdin instead.
ssh root@server1 bash -s <<'EOF'
gzip -d /tmp/file.out-20171119.gz
# note that (particularly w/o a cd /tmp) this doesn't do anything at all related to the
# line above; thus, probably buggy as given in the original question.
echo file* | awk -F'[.-]' '{print $1$3".log"}'
EOF
A quoted heredoc -- one with <<'EOF'
or <<\EOF
instead of <<EOF
-- is passed literally, without any shell expansions; thus, $1
or $3
will not be replaced by the calling shell as they would with an unquoted heredoc.
If you don't want to go the avoidance route, you can have the shell do the quoting for you itself. For example:
external_function() {
gzip -d /tmp/file.out-20171119.gz
echo file* | awk -F'[.-]' '{print $1$3".log"}'
}
ssh root@server1 "$(declare -f external_function); external_function"
declare -f
prints a definition of a function. Putting that function literally into your SSH command ensures that it's run remotely.
Escaping nested double quotes in awk
The standard advice for Windows to avoid their nightmarish quoting rules is:
a) Don't call the script from Windows. Install cygwin or similar to get a UNIX-like environment and then call the script from that, or...
b) Don't specify the script text on the command line in Windows, save it in a file instead, i.e. put this in a file named foo.awk
:
BEGIN { FS="|" }
$4 ~ /JUVENILE/ {sum +=$6}
END {printf "%.3f", sum}
and then execute it as awk -f foo.awk sourcedata.file
How to escape a single quote inside awk
This maybe what you're looking for:
awk 'BEGIN {FS=" ";} {printf "'\''%s'\'' ", $1}'
That is, with '\''
you close the opening '
, then print a literal '
by escaping it and finally open the '
again.
Using double quotes in awk
If the awk
command is single quoted, the $2
is not interpreted by the shell, but is instead passed as the literal string $2
to awk
. awk
will then print
the second space delimited token in the input string, which in this case is a
.
echo "line1 a b c" | awk '{ print $2 }' # prints the second space-delimited token
> a
If the awk
command is double quoted, the $2
is interpreted by the shell. Because $2
is empty (in this case), the empty string is substituted. awk
sees a command which looks like awk "{ print }"
, which is an instruction to print everything.
echo "line1 a b c" | awk '{ print }' # prints all input
> line1 a b c
It is also possible to use double qotes, and escape the $
, which will cause the $
to not be interpreted by the shell, and instead the $2
string will be passed to awk
.
echo "line1 a b c" | awk "{ print \$2 }" # prints the second space-delimited token
> a
How to escape single quotes within single quoted strings
If you really want to use single quotes in the outermost layer, remember that you can glue both kinds of quotation. Example:
alias rxvt='urxvt -fg '"'"'#111111'"'"' -bg '"'"'#111111'"'"
# ^^^^^ ^^^^^ ^^^^^ ^^^^
# 12345 12345 12345 1234
Explanation of how '"'"'
is interpreted as just '
:
'
End first quotation which uses single quotes."
Start second quotation, using double-quotes.'
Quoted character."
End second quotation, using double-quotes.'
Start third quotation, using single quotes.
If you do not place any whitespaces between (1) and (2), or between (4) and (5), the shell will interpret that string as a one long word.
How to make awk ignore the field delimiter inside double quotes?
From the GNU awk manual (http://www.gnu.org/software/gawk/manual/gawk.html#Splitting-By-Content):
$ awk -vFPAT='([^,]*)|("[^"]+")' -vOFS=, '{print $1,$4}' file
"abc@xyz.com,www.example.com",field4
"def@xyz.com",field4
and see What's the most robust way to efficiently parse CSV using awk? for more generally parsing CSVs that include newlines, etc. within fields.
Nested quotes bash
You can still place single quotes as long as the variables are intended to be initially expanded before the whole command string is executed on the shell on the remote server.
sudo ssh server "echo \"$SOMEVAR\"; awk '/pattern/{print \"hello\"}1' file > file.tmp"
Related Topics
How to Pass Command Line Parameters with Quotes Stored in Single Variable
Docker Container Accessible Only via Cloudflare Cdn (Selected Ip Ranges)
Generate Public Ssh Key from Private Key
Errors While Installing Opencv and Ffmpeg Through Rightscripts
Having Trouble Finding the Method _Kernel_Vsyscall Within the Linux Kernel
Running Multiple Compass-Sass Watch Operations Automatically
Remove a Specific Line from a File Without Using Sed or Awk
Simulating a Spinner for Progress in Bash
Difference Between Kernel, Kernel-Thread and User-Thread
What's the Purpose of the Ud2 Opcode in the Linux Kernel
Start X86_64 Code on X86 (32Bit) Linux, Running on X86_64 Cpu
Synchronizing Four Shell Scripts to Run One After Another in Unix
This Script Wont Sort Correctly by Age
How to Mount Google Bucket as Local Disk on Linux Instance with Full Access Rights
Collecting the Data for a Partiulcar Process from Pmu for Every 1 Milli Second