複数行コマンド内のBashスクリプトでのコメント


164

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

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

ここにコメントすることは可能ですか?


1
さて、お気づきのように、最初に#を実行すると、\はコメントの一部になりますが、最初に\を実行すると、行の後の文字の意味が「行継続」から「引用」に変わります。以下に示す1つの解決策を考えました。
DigitalRoss

回答:


203

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

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
より簡単な方法がない場合、かなり複雑に見えますか?
BassKozz 2009

1
わかりました、もう少し簡単なバリエーションを追加しました。
DigitalRoss

1
バックスラッシュが不要であることを示すためだけに回答を変更して、コメントを各行の横に配置してパイプを使用することはできますか?
BassKozz 2009

バージョン1と2が機能することを確認しました。しかし、なぜ彼らはそれをするのか、そしてここで何が起こっているのか説明できますか?ありがとう。
Faheem Mitha、2011

1
説明ありがとう。unix.sxで詳細を尋ねる質問を開きました。継続文字の後にコメントを付けて複数行コマンドをbashします
Faheem Mitha、2011

39

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

コマンドの間にコメント行を入れることができるはずです

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

12
パイプラインコマンドコンポーネントが|で終わる場合、\は不要です。
DigitalRoss

2
DigitalRoss、正解です。バックスラッシュではなくパイプを使用するだけで、#commentsは完全に機能します。それを回答として投稿して、受け入れることができます。
BassKozz 2009

8
「コマンドの間にコメント行を入れることができるはずです」:いいえ、これは機能し|ます。これは、前の行の最後に解釈された文字がであるためです。あなたがしようとした場合cat file1\<newline>#comment<newline>file2、あなたが得ることはありません表示されますcat file1 file2が、むしろcat file1; file2
dubiousjim 2012年

5
ただし、他の人が述べたように、cat file1 | # comment<newline>sort正常に動作します。それもそうcat file1 && # comment<newline>echo fooです。したがって、コメントは|or &&またはの後に含めることができます||が、 `\`の後やコマンドの途中には含めることができません。
dubiousjim 2013年

7

DigitalRossが指摘したように、行woudがで終わる場合、末尾のバックスラッシュは必要ありません|。そして、次の行にコメントを付けることができます|

 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

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


3

$IFS コメントハック

このハックでは、コマンドの単語を区切るために使用されるのパラメーター拡張$IFS使用します。

$ 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以前に展開によって削除された正確なテキストで開始された場合(つまり、#文字の後)です。

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

ファイナルにfoobarはスペースがなく、問題を示していることに注意してください。

以来$IFS、デフォルトでは空白だけが含まれ、それはだ非常にあなたは、この問題に実行されます可能性は低いです。


功績@ PJHさんのコメントこの答えをオフに巻き起こしました。


1

DigitalRossの例に加えて、$()バックティックの代わりに使用したい場合に使用できる別のフォームを次に示します`

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

もちろん、コロンもバックティックで使用できます。

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

その他の注意事項

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

バックティックは別の方法で解析し、の後でさえ、閉じるバックティックを検出し#ます。


1
コメントごとに新しいシェルが作成されますか?
lonix '13年

0

これは、以前のコメントのアイデアとイディオムを組み合わせて、例として、一般的な形式のインラインコメントを提供するbashスクリプトです${__+ <comment text>}

特に

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

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

ローカル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 
------------------------------------------------}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.