突破してみる? / Why don't you get over?

ソフトウェアエンジニアの備忘録 / Memorandum for software engineers

Bashで文字列の置換はどうするの? -- Bashのパラメータ展開

Bashのパラメータ展開

Bashでワイルドカードを使って文字列を置換したいときありますよね。Gentooだとebuildがシェルスクリプトなので、特に需要があると思います。難読な記法ですが、慣れると結構重宝します。

詳しくはman 1 bashのParameter Expansionを読むといいのですが、例を書いておきます。

${parameter/wildcard/string}, ${parameter//wildcard/string}

/だとwildcardに一致する最初の部分文字列をstringに置換します。
//だとwildcardに一致するすべての部分文字列をstringに置換します。

$ str_to_substitute='/usr/src/linux-3.16.6-gentoo'
$ echo "${str_to_substitute/-/_}"
/usr/src/linux_3.16.6-gentoo
$ echo "${str_to_substitute//-/_}"
/usr/src/linux_3.16.6_gentoo
$

ハイフンをアンダースコアに置換してみました。
Gentooのebuildでは、変数Pがパッケージネームとバージョンをハイフンでつないだ値を持っていますが、
それをアンダースコアに置換するときによく使います。

${parameter/#wildcard/string}, ${parameter/%wildcard/string}

/#だとwildcardの一致が先頭からになりstringに置換します。
/%だとwildcardの一致が末尾からになりstringに置換します。

${parameter#wildcard}, ${parameter##wildcard}

先頭からwildcardまでが削られます。
#だと最短一致になります。
##だと最長一致になります。

$ str_to_basename='/usr/src/linux-3.16.6'
$ echo "${str_to_basename#*\/}"
usr/src/linux-3.16.6
$ echo "${str_to_basename##*\/}"
linux-3.16.6
$

##を使ってbasenameコマンドのように削ってみました。

${parameter%wildcard}, ${parameter%%wildcard}

末尾からwildcardまでが削られます。
%だと最短一致になります。
%%だと最長一致になります。

$ str_to_dirname='/usr/src/linux-3.16.6'
$ echo "${str_to_dirname%\/*}"
/usr/src
$ echo "${str_to_dirname%%\/*}"

$

%を使ってdirnameコマンドのように削ってみました。

まとめ

*置換機能 *パラメータ展開例 *置換前 *置換後
substitute ${parameter/-/_} /usr/src/linux-3.16.6 /usr/src/linux_3.16.6
basename ${parameter##*\/} /usr/src/linux-3.16.6 linux-3.16.6
dirname ${parameter%\/*} /usr/src/linux-3.16.6 /usr/src
.ext抽出 ${parameter##*.} abc.patch patch