【Sed活用講座】 不要な空白(文字列前後の空白や連続した空白)を削除


2021/04/05

セルに含まれる文字列には、インデントとして無駄に連続した空白が詰まっていたり、タブやスペースなどの複数のタイプの空白が混合して入っていたりする場合が有ります。

Excelには
TRIM関数というメソッドが備わっており、テキスト中に含まれている不要なスペースを削除するときに使用しますが、シェルコマンドから同様のテキスト全体に渡る文字列の処理させるには、AwkなどよりSedで行うほうが処理速度的にも、スクリプトの可読性的にも優れています。

今回はSedを使った余計な空白文字の除去・洗浄に関した内容を解説します。


はじめに

当サイトではオフィス業務のComputer-Aidedなハイブリッドな方法を模索し、より効率的なExcel業務を実現したい多忙なオフィスワーカー向けの主にAwkとSedを使うシェル講座です。

シェルスクリプトはどこでもどんなOSでも基本的に使えて、しかも一度使い方を覚えると、Excelと組み合わせて最高に効率の良いオフィスワークツールが作れることでしょう。

合同会社タコスキングダム|蛸壺の技術ブログ


空白文字のおさらい

空白文字とは言ってもスペース文字以外の文字も含みます。

スペース - wiki

通常これらの空白文字は表示されないので、空白文字同士の違いは分かりにくいのですが、以下のように機能として使い分けがあります。

ユニコード

名称

機能

U+0020

スペース

語と語の区切り

U+00A0

ノーブレークスペース

自動的な改行を防ぐ特殊スペース

U+0009

タブ

文章の整形・修飾

U+000D

CF(キャリッジリターン)

カーソルを左端の位置に戻す

U+000A

LF(ラインフィード)

カーソルを新しい行に移動する

U+3000

全角スペース

使用するフォント(全角)により幅が変化する

U+2000~U+200F

その他特殊スペース

文章の整形・修飾。様々な幅に対応

ここでは、空白文字はスペース文字(『 』)だけではないということを念頭の置いて次に進みます。


不要な空白文字を削除する

ここでは不要な空白文字とは、文の先頭や末尾に無用に残ってしまった空白文字であったり、文章中に長々と居座っている連続した空白文字の塊を意味しています。これらはExcelシートをCsv形式に変換したときに、セル内で複数行表示させたときに出るゴミのような物で、しばしば目にすることもあると思います。

前の回の改行文字を削除する方法の内容では、xlsx2csvの-eオプションを用いてセル内改行の適切な位置で\nとして改行エスケープする方法を検討しました。

先ほどの節でも触れたように、空白文字とはスペースだけでなく、改行文字も含まれていますが、xlsx2csvの-eオプションで文字エスケープしてくれるのはCFかLFかタブ文字ですので、ほとんどの空白文字は残っている状態です。

明らかに無駄な空白文字が文章中にそのままになっているのも気持ち悪いですので、ここはSed使って無駄な空白を除去する方法を考えていきます。

色々と考え方はあると思いますが、今回は
不要な空白文字のルールを以下のように決めます。

            
            + 文字列のセルはダブルクォーテーション("文字)で囲む
+ "文字直後から始まる空白があれば削除する
+ "文字直前にある空白があれば削除する
+ 改行エスケープ(\n)直後から始まる空白があれば削除する
+ \n直前にある空白があれば削除する
+ それ以外の連続する空白は、1文字の空白に置換する
        
このルールは色々と後で変更が効きますので、細かいルール付けは各自で修正してください。

ということで、以上の空白文字の置き換えルールが複数ある場合には、Sedスクリプトをシークエンスとして処理させると見通しが良いと思います。以下に具体例をあげます。

            
            $ sed -r '
s/"[[:blank:]]+/"/g
s/\\n[[:blank:]]+/\\n/g
s/[[:blank:]]+"/"/g
s/[[:blank:]]+\\n/\\n/g
s/[[:blank:]]+/ /g
' <<EOF
"      のどか  な\n       田園      風景    ","       あ       \n小林      さん!","  メガネ  は\n   ずれ   落ち        る"
EOF
"のどか な\n田園 風景","あ\n小林 さん!","メガネ は\nずれ 落ち る"
        
ポイントとしてはSedスクリプト内で空白文字を表す\sを使って正規表現パターンを作成しても良いのですが、改行文字を除外する意味でPOSIXキャラクタークラスから[:blank:]を呼び出し、対象をスペース文字に限定させて利用してみました。


まとめ

今回はCSVデータとしてエクスポートさせたセル内テキストに含まれる不要な空白文字部分の処理をどう扱うかを考えてみました。

Sedを使えば空白文字の箇所だけで無く、より複雑なテキストの文字列パターンを除去・置換できますので、今回のテクニックを少し捻るだけでより応用的なスクリプトに修正することも可能かと思います。
記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。