次のコマンドを実行しています。
some_command --flag "foo\
bar\
quux" arg2
これにより文字列がに渡されますfoo\tbar\tquux
。
タブを使用せずに(または他のスペース文字を追加せずに)このパラメータを渡す方法を探しています。しかし、インデントを保ちます(私のスクリプトを読むことができるように)。
答え1
some_command --flag "$(printf '%s' foo\
bar\
quux)" arg2
一番読みやすいわけではありませんが、そうします。 「foo」、「bar」、および「quux」をコマンドの引数とprintf
フォーマット%s
文字列として渡します。引数より少ない書式文字が指定されている場合、書式文字列は必要に応じて繰り返されます。これは%s%s%s
、3つの文字列すべてをスペースなしで順番に印刷するのと同じです。最後に、「foobarquux」コマンドの出力は引数にprintf
置き換えられますsome_command
。
答え2
ヘルパー機能を使用してください。
concat () (
IFS=
printf '%s' "$*"
)
printf '"%s"\n' "$(concat "foo" \
"bar" \
"baz" )"
これは出力されます
"foobarbaz"
または、最初に引数の文字列ビットを配列に入れてから、実際の引数を別々に作成します(配列付きのシェルを使用しているとします)。
concat () (
IFS=
printf '%s' "$*"
)
args=(
"foo"
"bar"
"baz"
)
concat_args=$( concat "${args[@]}" )
printf '"%s"\n' "$concat_args"
上記のPOSIXシェルと同じ:
concat () (
IFS=
printf '%s' "$*"
)
set -- \
"foo" \
"bar" \
"baz"
concat_args=$( concat "$@" )
printf '"%s"\n' "$concat_args"
実行の関数本体は、concat
独自のサブシェルで実行されます(これがすぐに(...)
実行されるアクションです)。これは、変更が関数IFS
に対してローカルであることを意味します。
関数で"$*"
置換を使用する理由は純粋に審美的です。"$@"
プログラムが"$*"
拡大される予定です。一つ印刷する文字列ですprintf
。この場合、実際の接続は$*
区切り文字(空白)なしでシェル拡張によって行われます$IFS
。代わりに、それを使用すると、フォーマット文字列が繰り返し適用される"$@"
複数の個別の文字列に展開されます。printf
この場合、接続は次のようになります。副作用特定の書式文字列をprintf
。
または同じアイデア(実際の引数文字列を別々に生成)ですが、対応するヘルパー関数がない場合
arg=\
"foo"\
"bar"\
"baz"
printf '"%s"\n' "$arg"
printf '"%s"\n'
すべての場合において、上記はあなたのものですsome_command --flag
。