Commenting in a Bash script inside a multiline command
Solution 1
This will have some overhead, but technically it does answer your question:
echo abc `#Put your comment here` \
def `#Another chance for a comment` \
xyz, etc.
And for pipelines specifically, there is a clean solution with no overhead:
echo abc | # Normal comment OK here
tr a-z A-Z | # Another normal comment OK here
sort | # The pipelines are automatically continued
uniq # Final comment
See Stack Overflow question How to Put Line Comment for a Multi-line Command.
Solution 2
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}
Solution 3
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}
Solution 4
$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.
Solution 5
The backslash escapes the #, interpreting it as its literal character instead of a comment character.
Related videos on Youtube
Comments
-
BassKozz about 2 years
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?
-
DigitalRoss over 14 yearsWell, as you noticed, if you do # first, then the \ becomes just part of the comment, but if you do \ first, then the later characters on the line change its meaning away from "line continuation" to "quote". I've thought of one solution, given below.
-
Braiam over 9 yearspossible duplicate of How to Put Line Comment for a Multi-line Command
-
-
BassKozz over 14 yearsSeems rather complex, if there no simpler method?
-
DigitalRoss over 14 yearsOk, I've added a slightly simpler variation.
-
DigitalRoss over 14 yearsThe \ is not necessary when the pipeline command component ends with |
-
BassKozz over 14 yearsDigitalRoss, You are correct, I can just use the pipe and not the backslash and then my #comments will work perfectly... can you post that as an answer so I can accept it.
-
BassKozz over 14 yearsCan you modify your answer just to show the fact that the backslash is not needed so I can put the comments next to each line and just use a pipe?
-
Faheem Mitha over 12 yearsI verified that versions one and two work. However, can you explain why they do and what is going on here? Thanks.
-
DigitalRoss over 12 yearsThere used to be a shell
goto
command which branched to labels specified like: here
. The goto is gone but you can still use the: whatever
syntax ...:
is a sort of parsed comment now. -
Faheem Mitha over 12 yearsThanks for the explanation. I've opened a question on unix.sx asking for more details, bash multi line command with comments after the continuation character.
-
dubiousjim over 11 years"You should be able to put comment lines in between your commands": no, this is only working because the last interpreted character of the previous lines is
|
. If you trycat file1\<newline>#comment<newline>file2
, you'll see you don't getcat file1 file2
, but rathercat file1; file2
. -
dubiousjim over 11 yearsHowever, as others have mentioned,
cat file1 | # comment<newline>sort
works fine. So too doescat file1 && # comment<newline>echo foo
. So comments can be included after|
or&&
or||
, but not after `\` or in the middle of a command. -
Don Hatch over 7 yearsThe "for pipelines specifically" method is superficially nice, but it has a very annoying drawback: if I copy-paste your example into an interactive bash shell, it works great... but then if I then type !! or up-arrow to re-execute the command, it gets mangled. Your first suggestion seems to be more robust.
-
lonix over 4 yearsWill that create a new shell for every comment?
-
Jim Grisham about 3 yearsDoesn't that work even removing your list elements?
-
xebeche about 3 years@JimGrisham Yes, thanks for pointing this out. I've changed my answer accordingly. Now, technically, it's identical to other answers but strangely, so far, nobody else had shown code with leading pipes.
-
Mehrad Mahmoudian over 2 yearsJust for transparency as my changes are not peer-reviewed: The original post has
${__+
and it produced some error for me and after some searching I realized it should comply with${name:+word}
format to work and hence I changed it to${__:+
. For more info check out zsh.sourceforge.io/Doc/Release/Expansion.html and gnu.org/software/bash/manual/html_node/…