はじめに
ちょっとした小ネタです。truncate
コマンドはファイルの中身を残したまま、任意のファイルサイズまで切り詰めたり、または任意のファイルサイズまで拡張するコマンドです。正直言って使ったことはありません。使う場面は……仮想ディスクのイメージのサイズを変更したり?でもその場合は専用のコマンドを使うでしょうし、使う場面もあまり思いつきません。それでも truncate
コマンドというものが用意されているということは必要とする人もいるのでしょう。
さてこの truncate
コマンドですが POSIX コマンドではありません。Linux や FreeBSD には入っているようですが、macOS やその他の BSD には入っていないようです。この記事はこの truncate
コマンド相当のことを POSIX コマンドだけでやるにはどうするかという話です。
dd コマンドを使う
タイトルでネタバレしていますが、答えは dd
コマンドを使います。まず説明用にファイルを作成します。
$ printf '0123456789' > file.txt # 検証用に10バイトのファイルを作成
$ od -tx1 file.txt # 中身の確認
0000000 30 31 32 33 34 35 36 37 38 39
0000012
ファイルの切り詰め
ファイルの中身はそのままに 5 バイトまで減らします。
$ dd if=/dev/null of=file.txt obs=5 seek=1
0+0 records in
0+0 records out
0 bytes copied, 7.7843e-05 s, 0.0 kB/s
$ od -tx1 file.txt
0000000 30 31 32 33 34
0000005
ファイルの拡張
ファイルの中身はそのままに 10 バイトまで拡張します。
$ dd if=/dev/null of=file.txt obs=10 seek=1
0+0 records in
0+0 records out
0 bytes copied, 7.7843e-05 s, 0.0 kB/s
$ od -tx1 file.txt # 拡張した部分には NULL 文字が入る
0000000 30 31 32 33 34 00 00 00 00 00
0000012
解説
以下の例を元に解説します。
$ dd if=/dev/null of=file.txt obs=10 seek=1
obs
は書き込みのブロックサイズを 10 バイトに設定しています。そして seek
は書き込み時に移動するブロック数で 1 ブロック、つまり 10 バイトを移動してから書き込むという意味です。もし seek
が 2 なら 10 × 2 で 20 バイトです。書き込む内容は /dev/null
であるため何も書き込みません。もしここに中身のあるファイルを指定した場合は、そのファイルの内容が書き込まれます。
obs
と seek
を逆にして以下のようにしても同じよう動きますが、ブロック単位で処理することを考えると obs
でサイズを指定したほうが効率が良いと思います(未検証)
$ dd if=/dev/null of=file.txt obs=1 seek=10
おまけ サイズ指定について
POSIX で標準化されている obs
のサイズ指定には b
と k
の単位を指定できます。b
は 512 バイト、k
は 1024 バイトです。 POSIX で標準化されていない拡張機能ですが、おそらく M
や G
も使用可能です。
$ dd if=/dev/null of=file.txt obs=1b seek=1
0+0 records in
0+0 records out
0 bytes copied, 9.0135e-05 s, 0.0 kB/s
$ ls -al file.txt
-rw-rw-r-- 1 koichi koichi 512 Aug 21 20:07 file.txt
$ dd if=/dev/null of=file.txt obs=1k seek=1
0+0 records in
0+0 records out
0 bytes copied, 7.8725e-05 s, 0.0 kB/s
$ ls -al file.txt
-rw-rw-r-- 1 koichi koichi 1024 Aug 21 20:08 file.txt
そしてこちらも POSIX で標準化されている書き方ですが掛け算も使えます。
$ dd if=/dev/null of=file.txt obs=10x1k seek=1
0+0 records in
0+0 records out
0 bytes copied, 9.0135e-05 s, 0.0 kB/s
$ ls -al file.txt
-rw-rw-r-- 1 koichi koichi 10240 Aug 21 20:12 file.txt
このような書き方ができますが、あまり使うことはないでしょう。使うとしたら例えば 10M
の代わりに POSIX に準拠したわかりやすい(?)書き方として 10x1kx1k
と書く時ぐらいでしょうか。はいそうです。複数の値の掛け算ができますす。ちなみにこのような書き方ができるのは bs
、cbs
、ibs
、obs
のみです。
さいごに
以上です。