web-dev-qa-db-ja.com

シェルスクリプトのSPRINTF?

シェルスクリプトによって呼び出される自動生成ファイルが毎日あります。しかし、私が直面している問題は、自動生成されたファイルの形式があるということです:

FILE_MM_DD.dat

...ここで、MMとDDは2桁の月と曜日の文字列です。

私はいくつかの調査を行って自分でそれを打ちましたが、シェルスクリプトのみを使用してこれらのカスタム文字列を作成する方法がわかりません。

明確にするために、私はBashのDATE関数を知っていますが、私が探しているのはCのSPRINTF関数と同等です。

37
Manu R

Bashの場合:

_var=$(printf 'FILE=_%s_%s.dat' "$val1" "$val2")
_

または、同等のsprintfに近い:

_printf -v var 'FILE=_%s_%s.dat' "$val1" "$val2"
_

変数に先行ゼロ付きの10進値が含まれている場合、先行ゼロを削除できます。

_val1=008; val2=02
var=$(printf 'FILE=_%d_%d.dat' $((10#$val1)) $((10#$val2)))
_

または

_printf -v var 'FILE=_%d_%d.dat' $((10#$val1)) $((10#$val2))
_

$((10#$val1))は値を基数10に強制するため、形式仕様の_%d_は、「08」が無効な8進数値であるとは考えません。

date(少なくともGNU dateの場合)を使用している場合、次のように先行ゼロを省略できます。

_date '+FILE_%-m_%-d.dat'
_

完全を期すために、add先行ゼロを特定の幅にパディングする場合:

_val1=8; val2=2
printf -v var 'FILE=_%04d_%06d.dat' "$val1" "$val2"
_

または動的な幅で:

_val1=8; val2=2
width1=4; width2=6
printf -v var 'FILE=_%0*d_%0*d.dat' "$width1" "$val1" "$width2" "$val2"
_

先行ゼロを追加すると、簡単に並べ替えて列内できれいに整列する値を作成するのに役立ちます。

53

Coreutilsのprintfプログラムを使用しないのはなぜですか?

$ printf "FILE_%02d_%02d.dat" 1 2
FILE_01_02.dat
8
Daniel Böhmer

試してください:

sprintf() { local stdin; read -d '' -u 0 stdin; printf "$@" "$stdin"; }

例:

$ echo bar | sprintf "foo %s"
foo bar
1
kenorb