次のように複数のエコー呼び出しを使用せずに、Bashで複数行の文字列を出力するにはどうすればよいですか?
echo "usage: up [--level <n>| -n <levels>][--help][--version]"
echo
echo "Report bugs to: "
echo "up home page: "
Bashビルトインのみを使用して、これを行うためのポータブルな方法を探しています。
次のように複数のエコー呼び出しを使用せずに、Bashで複数行の文字列を出力するにはどうすればよいですか?
echo "usage: up [--level <n>| -n <levels>][--help][--version]"
echo
echo "Report bugs to: "
echo "up home page: "
Bashビルトインのみを使用して、これを行うためのポータブルな方法を探しています。
ここでは、ドキュメントがこの目的でよく使用されます。
cat << EOF
usage: up [--level <n>| -n <levels>][--help][--version]
Report bugs to:
up home page:
EOF
これらは、Bashのすべてのバージョンを含むすべてのボーン派生シェルでサポートされています。
またはあなたはこれを行うことができます:
echo "usage: up [--level <n>| -n <levels>][--help][--version]
Report bugs to:
up home page: "
このページの洞察に満ちた回答に触発されて、私は混合アプローチを作成しました。これは、最も単純でより柔軟なアプローチだと思います。どう思いますか?
まず、変数で使用法を定義します。これにより、さまざまなコンテキストで使用法を再利用できます。形式は非常に単純で、ほとんどWYSIWYGであり、制御文字を追加する必要はありません。これは私にはかなり移植性があるようです(私はMacOSとUbuntuで実行しました)
__usage="
Usage: $(basename $0) [OPTIONS]
Options:
-l, --level <n> Something something something level
-n, --nnnnn <levels> Something something something n
-h, --help Something something something help
-v, --version Something something something version
"
その後、私はそれを次のように簡単に使用できます
echo "$__usage"
またはさらに良いことに、パラメーターを解析するときに、ワンライナーでエコーすることができます。
levelN=${2:?"--level: n is required!""${__usage}"}
オプションを使用すると、文字列に-e
改行文字を印刷でき\n
ます。
サンプル(ただし、良いものかどうかはわかりません)
楽しいのは、オプションがまだ使用可能である間、 MacOSのマニュアルページ-e
に文書化されていないことです。Linuxのマニュアルページに記載されています。
printf
コメントで お勧めしたので、おそらくその使用法の例をいくつか挙げる必要があります(ただし、使用法メッセージを印刷する場合は、DennisまたはChrisの回答を使用する可能性が高くなります)。printf
を使用するよりも少し複雑ですecho
。その最初の引数はフォーマット文字列であり、エスケープ(のような\n
)は常に解釈されます。また、で始まるフォーマットディレクティブを含めることもできます%
。これは、追加の引数をどこにどのように含めるかを制御します。使用法メッセージに使用するための2つの異なるアプローチを次に示します。
まず、メッセージ全体をフォーマット文字列に含めることができます。
printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: \nup home page: \n"
echo
とは異なり、最後の改行を明示的に含める必要があることに注意してください。また、メッセージに%
文字が含まれている場合は、として記述する必要があります%%
。バグレポートとホームページのアドレスを含めたい場合は、非常に自然に追加できます。
printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: %s\nup home page: %s\n" "$bugreport" "$homepage"
次に、フォーマット文字列を使用して、追加の各引数を別々の行に出力することができます。
printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: " "up home page: "
このオプションを使用すると、バグレポートとホームページのアドレスを追加するのはかなり明白です。
printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: $bugreport" "up home page: $homepage"
また、インデントされたソースコードを使用する<<-
と、(末尾のダッシュを使用して)先頭のタブを無視できます(先頭のスペースは無視できます)。
例:これ:
if [ some test ]; then
cat <<- xx
line1
line2
xx
fi
先頭に空白を付けずにインデントされたテキストを出力します。
line1
line2
私は通常、より柔軟で直感的な組み込みの読み取りコマンドを使用します。行の内容を変数に読み込み、特別なシェル変数IFSに関連付けられた単語分割を可能にします。詳細については、このブログまたはmanページを参照してください。
read -r -d '' usage <<-EOF
usage: up [--level <n>| -n <levels>][--help][--version]
Report bugs to: $report server
up home page: $HOME
EOF
echo "$usage"
-e引数とエスケープ文字を使用します\n:
echo -e "This will generate a next line \nThis new line is the result"
もう1つprintf
、事前定義された変数(ここでは:)msg
をテンプレートとして使用します。
msg="First line %s
Second line %s
Third line %s
"
one='additional message for the first line'
two='2'
tri='this is the last one'
printf "$msg" "$one" "$two" "$tri"
この^^^は%s
、提供された順序ではなく、追加の変数が挿入されたメッセージ全体を出力します。
You can write your
text
freely,
in a separate:
----file.
その後
echo "$(</pathto/your_multiline_file)"
これを行う:
dedent() {
local -n reference="$1"
reference="$(echo "$reference" | sed 's/^[[:space:]]*//')"
}
text="this is line one
this is line two
this is line three\n"
# `text` is passed by reference and gets dedented
dedent text
printf "$text"
最初に呼び出さずに出力dedent
:
this is line one
this is line two
this is line three
...そして最初に呼び出しdedent
て(上記のように):
this is line one
this is line two
this is line three
完全な説明については、私がこれについてすでに書いたところを参照してください:
そしてもちろん、ここでその関数の一部を見せてくれたsed
@AndreasLouvに感謝します。