今回はタブをスペース(半角空白)に、スペースをタブに置換します。UNIXコマンドにはタブとスペースを相互変換するコマンドがあります。今回は、そのコマンドを使って処理してみます。
タブの処理はいい面もありますが悪い面もあります。どのような業務、シーンで使うかによってタブの方が便利だったりスペースの方が便利だったりするためトラブルの原因になることもあります。

今回もこれまで同様にサンプルで利用するファイル・ディレクトリはデスクトップのsampleディレクトリとしています。デスクトップにsampleディレクトリがない場合は作成しておいてください。(コマンド入力ならmkdir ~/Desktop/sampleとして作成することができます)
また、カレントディレクトリも上記の場所になります。cd ~/Desktop/sampleのようにコマンドを入力してカレントディレクトリを変更しておけばよいでしょう。

タブをスペースに置換

 まず、タブをスペースに置換してみましょう。タブをスペースに置換するにはexpandコマンドを使います。macOSとLinuxで若干違いはありますが、実用面では問題ないでしょう。なお、macOSの場合は以後に説明するGNU版expandコマンドをインストールすることでLinux版と同じように処理することが可能です。

man expand

 それではタブをスペースに変換してみましょう。1.txtの内容は以下のようになっています。タブがどこに入っているかはcatコマンドで-tを指定します。タブは^Iのように表示されます。^は制御コードであることを示し、その制御コードがアルファベットの順番でI番目、つまり9番目であることになります。9はASCIIコードでタブを示すので、^Iはタブコードであることになります。16までのASCIIコードの値とアルファベットの対応は以下のようになります。

1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16 
A|B|C|D|E|F|G|H|I|J |K |L |M |N |O |P


cat -t 1.txt

1.txtのテキストのタブをスペースにするには以下のように入力します。

expand 1.txt

出力結果を見ただけではタブがスペースに置換されたかわかりません。パイプ(|)を使って結果を渡しcatコマンドに-tをつけて表示すると、確かにすべてのタブがスペースに置換されています。

expand 1.txt | cat -t

処理した結果を保存するにはリダイレクト(>)を使います。以下の例ではカレントディレクトリに1s.txtというファイルとして保存されます。

expand 1.txt > 1s.txt

先頭のタブだけをスペースに置換

スペースをタブに、タブをスペースに置換するのは簡単ですが、多少の問題もあります。これらの命令はすべてのタブ・スペースが置換対象になってしまう事です。場合によっては先頭のタブだけスペースに置換したい事もあります。例えば字下げ(インデント)が重要なプログラム言語のPythonがあります。これは先頭の字下げとなるタブやスペースが重要であり、それ以外の場所では致命的な障害にはなりません。

先頭のタブだけを処理するにはexpandのiオプションを使います。以下のようにすると先頭のタブだけがスペースに置換されます。

expand -i 1.txt | cat -t

ただし、このオプションが指定できるのはLinux/GUN版expandだけです。macOSで実行するとエラーになります。macOSで同じように処理する場合はHomebrewでインストールするかsed,awkなどを使う必要があります。Homebrew経由の場合は、先にHomebrewをインストールしておきます。これはHomebrewのページにあるスクリプトをターミナルに貼り付けるだけです。

https://brew.sh/ja/

Homebrewがインストールできたら以下のコマンドを入力します。

brew install coreutils

インストールされたexpandコマンドはコマンド名がgexpandになります。(コマンド名の先頭にgが付く)
以下のようにするとmacOSでも先頭のタブだけをスペースに置換することができます。

gexpand -i 1.txt | cat -t

スペースをタブに置換

 今度はスペースをタブに置換してみましょう。この場合、unexpandコマンドを使います。

man unexpand

使い方はexpandコマンドと同じです。標準入力からのデータも受け付けています。
unexpandコマンドで1s.txt内のスペースをタブに置換するには以下のようにします。1s.txtは先ほどexpandで全てのタブをスペースに変換した結果を保存したファイルになります。

unexpand 1s.txt | cat -t

ファイルに保存する場合はリダイレクト(>)を使って以下のようにコマンドを入力します。この場合、結果は1t.txtのファイルに保存されます。

unexpand 1s.txt > 1t.txt

タブを に置換(sed/awk/perl/vi)

 他の文字に置換したい場合もあります。例えばタブやスペースをWebで使用される に置換したい場合です。この場合、expandコマンドでは用に足りません。このような場合、プログラムを作るという手段の方がよいかもしれません。が、ここはコマンドの世界なので頑張ってコマンドで何とかしてみます。

まず、定番のsedを使ってタブを に置換します。以下のようにすると、3.txtファイル内のタブが に置き換えられます。

sed 's/\t/ /g' 1.txt

スペースを に置換する場合は以下のようになります。

sed 's/ / /g' 1s.txt

sed以外ではawkを使って処理する方法もあります。

awk '{gsub("\t", "\ "); print}' 1.txt

コマンドではなくプログラミング言語を使う方法もあります。perlを使う場合は以下のようになります。 perl -pe 's/\t/ /g' 1.txt

n個のスペースをタブに置換

 場合によっては8個のスペースを1個のタブに置換したい場合もあります。このような場合はunexpandでは用に足りない場合があります。というのもunexpandでスペースをタブに置換する場合、タブストップ(nの倍数位置)を基準にして処理されてしまうためです。
8個のスペースを1個のタブにするような場合はunexpandでなくsedを使います。以下のように指定すると8個のスペースが1個のタブに置換されます。

sed 's/ {8}/\t/g' 1s.txt

変換されたタブコードを確認したい場合は以下のようにします。

sed 's/ {8}/\t/g' 1s.txt | cat -t

きっかり8個ではなく8個以上のスペースだったら1個のタブにする場合は以下のようになります。

sed 's/ {8,}/\t/g' 1s.txt</span

変換されたタブコードを確認したい場合は以下のようにします。

sed 's/ {8,}/\t/g' 1s.txt | cat -t

ちなみに先頭だけ8個以上のスペースが連続していた場合、1つのタブに置換するには以下のようになります。結果は示しませんので連続したスペースを含むテキストファイルを作成してからコマンドを実行してみてください。

sed 's/^ {8,}/\t/' 1.txt

それでは、また次回。

著者 仲村次郎
いろいろな事に手を出してみたものの結局身につかず、とりあえず目的の事ができればいいんじゃないかみたいな感じで生きております。