评论Bash脚本

时间:2009-09-21 18:17:26

标签: bash syntax comments

如何评论脚本中以下几行的每一行?

   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}

如果我尝试添加评论:

cat ${MYSQLDUMP} | \ # Output MYSQLDUMP File

我明白了:

#: not found

可以在这里发表评论吗?

9 个答案:

答案 0 :(得分:174)

这会有一些开销,但从技术上来说它确实回答了你的问题:

echo abc `#Put your comment here` \
     def `#Another chance for a comment` \
     xyz, etc.

特别是对于管道,有一个没有开销的干净解决方案:

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

请参阅Stack Overflow问题 How to Put Line Comment for a Multi-line Command

答案 1 :(得分:37)

尾部反斜杠必须是该行的最后一个字符,才能将其解释为延续命令。之后不允许任何评论甚至空白。

您应该可以在命令之间添加注释行

# 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}

答案 2 :(得分:5)

反斜杠转义#,将其解释为文字字符而不是注释字符。

答案 3 :(得分:5)

正如DigitalRoss所指出的那样,当行在|结束时,不需要尾随反斜杠。您可以在|

之后的一行上添加评论
 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}

答案 4 :(得分:4)

$IFS评论黑客

此hack在$IFS上使用http://en.cppreference.com/w/cpp/language/final,用于分隔命令中的字词:

$ echo foo${IFS}bar
foo bar

类似地:

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

使用此功能,您可以在带有contination的命令行上发表评论:

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

但评论需要在\延续之前。

请注意,参数扩展是在评论中执行的:

$ 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

罕见异常

此失败的唯一罕见情况是$IFS以前是以完全文本开始的,该文本是通过扩展删除的(即在#字符之后):

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

请注意,最终foobar没有空格,说明问题。

由于默认情况下$IFS仅包含空格,因此

归功于parameter expansion,这引发了这个答案。

答案 5 :(得分:1)

而不是你尝试过的:

cat ${MYSQLDUMP} | \ # Output MYSQLDUMP File

其他人提到这应该有效:

cat ${MYSQLDUMP} |   # Output MYSQLDUMP File

因为分割线并不总是以竖线 (|) 结尾,所以您可以在它们自己的行上添加注释,就像这样

date && \
  # List current directory
  ls -l | awk '{ \
  # Filename is in the ninth column
      # This is just making "ls -l" work mostly like "ls -1"
  print $9 }'

不要在字符串中间这样做:

echo " Hello \
 # Localized name for your planet:
world."

在您的情况下,您可以使用此方法:

cat ${MYSQLDUMP} | \
# Output MYSQLDUMP File

扩展示例:

# Create .csv file from MySQL dump file
cat ${MYSQLDUMP} |   
# Output MYSQLDUMP File
# and pipe to first sed command
sed '1d' | \
# Pipe output to tr
tr ",;" "\n" | \
# Apply sed expression
sed -e 's/[asbi]:[0-9]*[:]*//g' -e '/^[{}]/d' -e 's/""//g' -e '/^"{/d' | \
    # Apply another two sed expressions
    # (and since whitespace is ignored, you can intent for clarity)
    sed -n -e '/^"/p' -e '/^print_value$/,/^option_id$/p' | \
    # Apply three more sed expressions
    sed -e '/^option_id/d' -e '/^print_value/d' -e 's/^"\(.*\)"$/\1/' | \
    # Use tr to ...
    tr "\n" "," | \
    # Apply yet another two sed expressions
    sed -e 's/,\([0-9]*-[0-9]*-[0-9]*\)/\n\1/g' -e 's/,$//' | \
    # Apply the final three sed expressions
    sed -e 's/^/"/g' -e 's/$/"/g' -e 's/,/","/g' >> ${CSV}

... 或混合两种方法:

# Create .csv file from MySQL dump file
cat ${MYSQLDUMP} |   # Output MYSQLDUMP File
# and pipe to first sed command
sed '1d' | \
# Pipe output to tr
...

(我相信这两种方法都有效,因为 shell 脚本文件是逐行解析的,就像 CLI 输入一样。)

最后说明:

  • 重要的是要记住,行继续符 (\) 在使用时应该是该行中的最后一个字符 (即使是一个被遗忘的尾随空格也会破坏你的晚上)

  • 如果从命令行手动输入,如果您打算使用命令历史记录功能,请仅使用第二种方法(每个注释在自己的行上)

  • 如果使用历史记录并希望保留评论,请不要使用这两种方法中的任何一种 - 使用此问题的不同答案中的一种。

答案 6 :(得分:0)

这是一个bash脚本,它结合了之前几条评论的想法和习惯用语,通过示例提供了具有一般形式${__+ <comment text>}的内联注释。

特别是

  • <comment text>可以是多行
  • <comment text>未参数展开
  • 没有产生子进程(因此评论有效)

<comment text>有一个限制,即不平衡的大括号'}'和括号')'必须受到保护(即'\}''\)')。

本地bash环境有一个要求:

  • 必须取消设置参数名称__

除非名称没有设置值,否则任何其他语法上有效的bash参数名称都将代替__

示例脚本如下

# 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 
------------------------------------------------}

答案 7 :(得分:0)

除了DigitalRoss的示例外,如果您更喜欢$()而不是反引号`

,还可以使用另一种形式。
echo abc $(: comment) \
     def $(: comment) \
     xyz

当然,您也可以在反引号中使用冒号语法:

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

附加说明

$(#comment)不起作用的原因是,一旦看到#,它将其余的行视为注释,包括右括号:comment)。因此括号永远不会关闭。

反引号的解析方式不同,即使在#之后,反引号也会检测到。

答案 8 :(得分:0)

我喜欢的管道连接命令的编码风格是

command1 \
| command2 \
| ...

正如 @JimGrisham 和其他人所建议的,注释行的一种方法是

command1 \
| # inline comment
  command2 \
| ...

另一种不调用子外壳的方法是使用始终有效的 Bash 的 { list; } 构造。所以在这里:

command1 \
| {
    # inline comment
    command2
  } \
| ...