Bash - ${##}を使用してコマンド結果から部分文字列を削除できますか?

Bash - ${##}を使用してコマンド結果から部分文字列を削除できますか?

私はこれが私にgitの現在のブランチの名前を与えると思います。

echo "${`git symbolic-ref HEAD`##refs/heads}"

しかし、これにより

-bash: ${`git symbolic-ref HEAD`##refs/heads}: bad substitution

結果を中間変数に保存せずに、1行のコマンド結果に##を使用できますか?それとも別の方法(例:?)を使用する必要がありますかsed

答え1

いいえbash。ただし、次のことができますzsh

printf '%s\n' "${$(git symbolic-ref HEAD)#refs/heads}"

そこで働きます。

または、いつでも次を使用してストリッピングを実行できますsed

printf '%s\n' "$(git symbolic-ref HEAD | sed '1s|^refs/heads||')"

削除する部分に改行文字が含まれていると、状況はさらに複雑になります。たとえば、削除する部分がある場合は、$'1\n2\n3\n'次のようなものが必要です。

cmd1 -- "$(cmd2 | sed '1{$!N;$!N;$!N; s/^1\n2\n3\n//;}')"

cmd2したがって、終了状態を維持するという利点を持つ一時変数を使用することもできます。

strip=$'1\n2\n3\n'

out=$(cmd2); cmd2_status=$?
cmd1 -- "${out#"$strip"}"

答え2

いいえ、残念ながら、この##イディオムは次のものであるため不可能です。変える拡張のみが可能なので、常に既存の変数を参照する必要があります。

しかし、あなたの場合は、次のヒントが好きです。

sh -c 'echo "${*##refs/heads}"' - "`git symbolic-ref HEAD`"

または:(より良いバシズムとして)

sh -c 'echo "${*##refs/heads}"' -- "$(git symbolic-ref HEAD)"

shこれは、コマンド出力を引数として使用して非対話型コマンドを実行し、その引数にイディオムをgit 使用##します。

コマンドの出力が十分に削除されたと信頼できる場合(たとえば、*または他のワイルドカードが含まれていない)、二重引用符を入力する時間を節約できます。

関連情報