BASH中参数之间的注释

BASH中参数之间的注释,bash,comments,Bash,Comments,我希望包含命令参数内联注释,例如: sed -i.bak -r \ # comment 1 -e 'sed_commands' \ # comment 2 -e 'sed_commands' \ # comment 3 -e 'sed_commands' \ /path/to/file 上面的代码不起作用。在参数行中嵌入注释有不同的方法吗?我建议对sed脚本使用更长的文本块,即 sed -i.bak ' # comment 1

我希望包含命令参数内联注释,例如:

sed -i.bak -r \
    # comment 1
    -e 'sed_commands' \
    # comment 2
    -e 'sed_commands' \
    # comment 3
    -e 'sed_commands' \
    /path/to/file

上面的代码不起作用。在参数行中嵌入注释有不同的方法吗?

我建议对sed脚本使用更长的文本块,即

sed -i.bak '
    # comment 1
    sed_commands
    # comment 2
    sed_commands
    # comment 3
    sed_commands
' /path/to/file
不幸的是,sed脚本块中嵌入的注释并不是普遍支持的功能。sun4版本允许您在第一行添加注释,但不允许在其他地方添加注释。AIXSED要么不允许任何注释,要么对注释使用除
之外的其他字符。您的结果可能会有所不同

我希望这会有所帮助。

您可以多次调用sed,而不是将所有参数传递给一个进程:

sed sed_commands |             # comment 1
    sed sed_commands |         # comment 2
    sed sed_commands |         # comment 3
    sed sed_commands           # final comment
这显然更浪费,但您可能会认为,在可读性和可移植性方面,三个额外的sed进程是一个公平的折衷方案(对于@sheller关于支持sed命令中的注释的观点)。这取决于你的情况


更新:如
-i
参数所示,如果最初打算就地编辑文件,则还必须进行调整。此方法需要管道。

如果确实需要注释参数,可以尝试以下方法:

ls $(
    echo '-l' #for the long list
    echo '-F' #show file types too
    echo '-t' #sort by time
)
这相当于:

ls -l -F -t
echo是一个内置的shell,因此不执行外部命令,因此速度足够快。但是,无论如何,这是疯狂的

makeargs(){whilereadline;do echo${line/.*/};done}

ls$(makeargs在shell plus sed中没有一种方法可以实现您想要实现的功能。我将注释放在
sed
脚本之前,如下所示:

# This is a remarkably straight-forward SED script
# -- When it encounters an end of here-document followed by
#    the start of the next here document, it deletes both lines.
#    This cuts down vastly on the number of processes which are run.
# -- It also does a substitution for XXXX, because the script which
#    put the XXXX in place was quite hard enough without having to
#    worry about whether things were escaped enough times or not.
cat >$tmp.3 <<EOF
/^!\$/N
/^!\\ncat <<'!'\$/d
s%version XXXX%version $SOURCEDIR/%
EOF

# This is another entertaining SED script.
# It takes the output from the shell script generated by running the
# first script through the second script and into the shell, and
# converts it back into an NMD file.
# -- It initialises the hold space with --@, which is a marker.
# -- For lines which start with the marker, it adds the pattern space
#    to the hold space and exchanges the hold and pattern space.  It
#    then replaces a version number followed by a newline, the marker
#    and a version number by the just the new version number, but
#    replaces a version number followed by a newline and just the
#    marker by just the version number.  This replaces the old version
#    number with the new one (when there is a new version number).
#    The line is printed and deleted.
# -- Note that this code allows for an optional single word after the
#    version number.  At the moment, the only valid value is 'binary' which
#    indicates that the file should not be version stamped by mknmd.
# -- On any line which does not start with the marker, the line is
#    copied into the hold space, and if the original hold space
#    started with the marker, the line is deleted.  Otherwise, of
#    course, it is printed.
cat >$tmp.2 <<'EOF'
1{
x
s/^/--@/
x
}
/^--@ /{
H
x
s/\([   ]\)[0-9.][0-9.]*\n--@ \([0-9.]\)/\1\2/
s/\([   ]\)[0-9.][0-9.]*\([     ][      ]*[^    ]*\)\n--@ \([0-9.][0-9.]*\)/\1\3\2/
s/\([   ][0-9.][0-9.]*\)\n--@ $/\1/
s/\([   ][0-9.][0-9.]*[         ][      ]*[^    ]*\)\n--@ $/\1/
p
d
}
/^--@/!{
x
/^--@/d
}
EOF
#这是一个非常直截了当的SED脚本
#--当遇到此处结尾的文档后接
#在下一个here文档的开头,它将删除两行。
#这大大减少了正在运行的进程的数量。
#--它还替换XXXX,因为
#把XXXX放在适当的位置是相当困难的,不必这样做
#担心事情是否逃脱了足够的次数。
类别>$tmp.3编号

如果将
\
放在
\
前面,它将转义注释字符,您将不再有注释

如果您将
\
放在
\
后面,它将成为注释的一部分,您将无法再跳出换行符


缺少内联注释是bash的一个限制,您最好适应它,而不是尝试使用已经提出的一些巴洛克风格的建议。

虽然该主题已经很老了,但我确实发现它适用于同一个问题,其他人也会如此。以下是我对该问题的解决方案:

您需要注释,这样,如果您在以后很长时间内查看代码,您可能会了解您在编写代码时的实际操作。我只是在编写第一个rsync脚本时遇到了相同的问题,它有很多参数,也有副作用

根据主题将属于一起的参数组合在一起,并将它们放入一个变量中,该变量将获得相应的名称。这便于识别参数的方向。这是您的简短注释。此外,您可以在变量声明上方添加注释,以查看如何更改行为。这是长版本注释

使用相应的参数变量调用应用程序

## Options
# Remove --whole-file for delta transfer
sync_filesystem=" --one-file-system \
                  --recursive       \
                  --relative        \
                  --whole-file      \ " ;

rsync \
      ${sync_filesystem}  \
      ${way_more_to_come} \
      "${SOURCE}"         \
      "${DESTIN}"         \

良好的概述,易于编辑,并且喜欢参数中的注释。这需要更多的努力,但因此具有更高的质量。

我将推荐另一种至少在某些情况下有效的方法:

假设我有命令:

foo --option1 --option2=blah --option3 option3val /tmp/bar`
我可以这样写:

options=(
--option1
--option2=blah
--option3 option3val
)

foo ${options[@]} /tmp/bar
现在,假设我想暂时删除第二个选项。我可以将其注释掉:

options=(
--option1
# --option2=blah
--option3 option3val
)
请注意,当您需要大量转义或引用时,此技术可能不起作用。我在过去遇到过一些与此相关的问题,但不幸的是,我现在不记得细节:(


不过,在大多数情况下,这种技术效果很好。如果您需要在参数中嵌入空格,请像往常一样将字符串括在引号中。

糟糕的想法-通过3个管道复制日期是浪费精力的。公平地说,我应该补充一点:如果文件大小只有千字节,这很好;如果文件是兆字节,则令人怀疑;如果文件是千兆字节E或更大,然后6个不必要的副本(三个管道中的每一个进出)太贵了。我通常试图在shell答案中给出最少数量的进程,但我提到这是一个选项,因为“糟糕”是相对的。在1983年,当然。在2011年,正如我所说,这可能值得权衡。你说可读性不值得几毫秒和几十个字节,但在某些情况下,如果脚本中可以澄清出臭名昭著的神秘正则表达式,那么这些碎屑可能非常值得牺牲。对不起,你添加了注释about文件大小,因为我正在键入我的辩护。这一点很好,OP需要记住。是的,“糟糕”太强了-我太晚了,无法淡化原始评论;我希望澄清部分弥补这一点。您已经提到的另一个问题是:用
sed
com序列覆盖原始文件更难很好-但是请注意,
do echo${line//#*/};
将起作用,只要您的命令不使用
-e
参数;如果它使用(如
tshark
),则它将被解释为
echo
的参数,并最终从输出中丢失。然后您可以使用
printf“%s”${line//#*/};
——但这就阻止了您使用
-r“$1”
之类的东西在参数中传递文件名,因为双引号将在命令中转义(并且不会被shell解释),从而弄乱文件名。
options=(
--option1
# --option2=blah
--option3 option3val
)