web-dev-qa-db-ja.com

Bashスクリプトでコメントする

スクリプトから次の行の各行にコメントするにはどうすればよいですか?

   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

ここにコメントすることはできますか?

142
BassKozz

これにはいくらかオーバーヘッドがありますが、技術的にはあなたの質問に答えます:

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 question複数行コマンドの行コメントの入力方法を参照してください。

177
DigitalRoss

後続のバックスラッシュは、継続コマンドとして解釈されるためには、行の最後の文字でなければなりません。その後のコメントや空白は許可されません。

コマンド間にコメント行を挿入できるはずです

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

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}
5
mob

バックスラッシュは#をエスケープし、コメント文字ではなくリテラル文字として解釈します。

5
tobiasvl

$IFSコメントハック

このハックは$IFSparameter expansion を使用します。これはコマンド内の単語を区切るために使用されます。

$ echo foo${IFS}bar
foo bar

同様に:

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

これを使用して、次のようにコマンドラインにコメントを入力できます。

$ 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が以前にexact textで始まっていた場合で、これは展開によって(つまり、#文字の後)削除されます:

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

最後のfoobarにはスペースがなく、問題を示していることに注意してください。

$IFSにはデフォルトで空白のみが含まれているため、この問題に遭遇する可能性は非常に低いです。


@ pjhのコメント のおかげで、この答えが生まれました。

4
Tom Hale

DigitalRossによる例に加えて、バックティック`の代わりに$()を好む場合に使用できる別のフォームがあります

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

もちろん、コロンの構文をバックティックとともに使用することもできます。

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

その他の注意事項

$(#comment)が機能しない理由は、#を検出すると、行の残りを閉じ括弧を含むコメントとして処理するためです:comment)。したがって、括弧は閉じられません。

バックティックは異なる方法で解析され、#の後でも閉じているバックティックを検出します。

1
wisbucky

以下に、以前のいくつかのコメントのアイデアとイディオムを組み合わせて、一般的な形式${__+ <comment text>}を持つインラインコメントを例とともに提供するbashスクリプトを示します。

特に

  • <comment text>は複数行にすることができます
  • <comment text>はパラメーター展開されていません
  • サブプロセスは生成されません(したがって、コメントは効率的です)

<comment text>には1つの制限があります。つまり、不均衡な中括弧'}'と括弧')'を保護する必要があります(つまり、'\}''\)')。

ローカルbash環境には1つの要件があります。

  • パラメーター名__は設定解除する必要があります

名前に値が設定されていない場合、構文的に有効な他の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 
------------------------------------------------}
0
John Sidles