[bash] Commenting in a Bash script inside a multiline command

How can I comment on each line of the following lines from a script?

cat ${MYSQLDUMP} | \
sed '1d' | \
tr ",;" "\n" | \
sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' | \
sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' | \
sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$/\1/' | \
tr "\n" "," | \
sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n\1/g' -e 's/,$//' | \
sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

If I try and add a comment like:

cat ${MYSQLDUMP} | \ # Output MYSQLDUMP File

I get:

#: not found

Is it possible to comment here?

This question is related to bash syntax comments

The answer is


In addition to the examples by DigitalRoss, here's another form that you can use if you prefer $() instead of backticks `

echo abc $(: comment) \
     def $(: comment) \
     xyz

Of course, you can use the colon syntax with backticks as well:

echo abc `: comment` \
     def `: comment` \
     xyz

Additional Notes

The reason $(#comment) doesn't work is because once it sees the #, it treats the rest of the line as comments, including the closing parentheses: comment). So the parentheses is never closed.

Backticks parse differently and will detect the closing backtick even after a #.


The trailing backslash must be the last character on the line for it to be interpreted as a continuation command. No comments or even whitespace are allowed after it.

You should be able to put comment lines in between your commands

# output MYSQLDUMP file
cat ${MYSQLDUMP} | \
# simplify the line
sed '/created_at/d' | \
# create some newlines
tr ",;" "\n" | \
# use some sed magic
sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' | \
# more magic
sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' | \
# even more magic
sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$/\1/' | \
tr "\n" "," | \
# I hate phone numbers in my output
sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n\1/g' -e 's/,$//' | \ 
# one more sed call and then send it to the CSV file
sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

As DigitalRoss pointed out, the trailing backslash is not necessary when the line woud end in |. And you can put comments on a line following a |:

 cat ${MYSQLDUMP} |         # Output MYSQLDUMP file
 sed '1d' |                 # skip the top line
 tr ",;" "\n" | 
 sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' |
 sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' |
 sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$/\1/' |
 tr "\n" "," |
 sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n\1/g' -e 's/,$//' |   # hate phone numbers
 sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

$IFS comment hacks

This hack uses parameter expansion on $IFS, which is used to separate words in commands:

$ echo foo${IFS}bar
foo bar

Similarly:

$ echo foo${IFS#comment}bar
foo bar

Using this, you can put a comment on a command line with contination:

$ echo foo${IFS# Comment here} \
> bar
foo bar

but the comment will need to be before the \ continuation.

Note that parameter expansion is performed inside the comment:

$ ls file
ls: cannot access 'file': No such file or directory
$ echo foo${IFS# This command will create file: $(touch file)}bar
foo bar
$ ls file
file

Rare exception

The only rare case this fails is if $IFS previously started with the exact text which is removed via the expansion (ie, after the # character):

$ IFS=x
$ echo foo${IFS#y}bar
foo bar
$ echo foo${IFS#x}bar
foobar

Note the final foobar has no space, illustrating the issue.

Since $IFS contains only whitespace by default, it's extremely unlikely you'll run into this problem.


Credit to @pjh's comment which sparked off this answer.


Here is a bash script that combines the ideas and idioms of several previous comments to provide, with examples, inline comments having the general form ${__+ <comment text>}.

In particular

  • <comment text> can be multi-line
  • <comment text> is not parameter-expanded
  • no subprocesses are spawned (so comments are efficient)

There is one restriction on the <comment text>, namely, unbalanced braces '}' and parentheses ')' must be protected (i.e., '\}' and '\)').

There is one requirement on the local bash environment:

  • the parameter name __ must be unset

Any other syntactically valid bash parameter-name will serve in place of __, provided that the name has no set value.

An example script follows

# provide bash inline comments having the form
#     <code> ${__+ <comment>} <code> 
#     <code> ${__+ <multiline
#                   comment>} <code>

# utility routines that obviate "useless use of cat"
function bashcat { printf '%s\n' "$(</dev/stdin)"; }
function scat { 1>&2 bashcat; exit 1; }

# ensure that '__' is unset && remains unset
[[ -z ${__+x} ]] &&  # if '__' is unset
  declare -r __ ||   # then ensure that '__' remains unset 
  scat <<EOF         # else exit with an error
Error: the parameter __='${__}' is set, hence the
  comment-idiom '\${__+ <comment text>}' will fail
EOF

${__+ (example of inline comments)
------------------------------------------------
the following inline comment-idiom is supported
    <code> ${__+ <comment>} <code> 
    <code> ${__+ <multiline
                  comment>} <code> 
(advisory) the parameter '__' must NOT be set;
  even the null declaration __='' will fail
(advisory) protect unbalanced delimiters \} and \) 
(advisory) NO parameter-expansion of <comment> 
(advisory) NO subprocesses are spawned
(advisory) a functionally equivalent idiom is 
    <code> `# <comment>` <code> 
    <code> `# <multiline
               comment>` <code>
however each comment spawns a bash subprocess
that inelegantly requires ~1ms of computation 
------------------------------------------------}

The backslash escapes the #, interpreting it as its literal character instead of a comment character.


Examples related to bash

Comparing a variable with a string python not working when redirecting from bash script Zipping a file in bash fails How do I prevent Conda from activating the base environment by default? Get first line of a shell command's output Fixing a systemd service 203/EXEC failure (no such file or directory) /bin/sh: apt-get: not found VSCode Change Default Terminal Run bash command on jenkins pipeline How to check if the docker engine and a docker container are running? How to switch Python versions in Terminal?

Examples related to syntax

What is the 'open' keyword in Swift? Check if returned value is not null and if so assign it, in one line, with one method call Inline for loop What does %>% function mean in R? R - " missing value where TRUE/FALSE needed " Printing variables in Python 3.4 How to replace multiple patterns at once with sed? What's the meaning of "=>" (an arrow formed from equals & greater than) in JavaScript? How can I fix MySQL error #1064? What do >> and << mean in Python?

Examples related to comments

Way to create multiline comments in Bash? Jenkins: Can comments be added to a Jenkinsfile? /** and /* in Java Comments Where is the syntax for TypeScript comments documented? Multiple line comment in Python How do I add comments to package.json for npm install? How to comment multiple lines with space or indent Is there a shortcut to make a block comment in Xcode? How to comment and uncomment blocks of code in the Office VBA Editor Which comment style should I use in batch files?