カテゴリー
【Sed活用講座】文字列中の特定の記号を一括削除する方法
※ 当ページには【広告/PR】を含む場合があります。
2021/04/04
2021/04/07
Csvデータ全体に渡って、セル内に含まれる文字列に区別無く存在する不要な記号を一括して削除したい場合が有ります。
このような特殊記号は当然ながら手動で検索しながら一つ一つ消していくのも面倒です。
また
$0
--slurp
ということで今回はCsvファイルの全体に渡るような文字列の置き換えをSedコマンドを利用して、一気に、そして高速に不要な文字を削除する方法を紹介します。
はじめに
当サイトではオフィス業務のComputer-Aidedなハイブリッドな方法を模索し、より効率的なExcel業務を実現したい多忙なオフィスワーカー向けの主にAwkとSedを使うシェル講座です。
シェルスクリプトはどこでもどんなOSでも基本的に使えて、しかも一度使い方を覚えると、Excelと組み合わせて最高に効率の良いオフィスワークツールが作れることでしょう。

Sedで使う基本的な正規表現
本題に入る前に、Sedの正規表現を少し復習しておきます。
ちなみに本記事で利用するSedは
Gnu sed
BSD sed
ところで、Sedでオプション指定できる正規表現には2通りあり、通常スクリプトモード(
-e/--expression
-r/--regexp-extended
デフォルトでは通常のスクリプトモードで、拡張モードにするためには明示に
-r
ただ通常スクリプトモードで利用する正規表現は以下の表中に表すように非常に紛らわしく、冗長な表現を適宜追加しないと正しく動きません。 通常スクリプトモーでは、複雑な文章解析への正規表現を利用するウマ味が薄くなるため、折角正規表現の拡張モードが備わっているならばこちらを積極的に利用する方が良いと思います。
このように、通常スクリプトモードと、拡張モードとは、正規表現の用法が異なるものがいくつかありますので、コーディングの際には注意が必要です。
たとえば、Sedの通常スクリプトモードには中括弧や丸括弧には文字エスケープが必要ですが、釘括弧はそうではないようです。
また+や?などの文字にも文字エスケープが必要ですが、,や*などには気を使う必要はない...などなど、Sedで正規表現を使うときに色々と気を遣うよりは、拡張モードを使う方が良いでしょう。
ちなみにGnu sedでは以下のPOSIXキャラクターが利用できます。 こちらも覚えておくと特定の文字をマッチさせたい場合に便利なときがあります。
ちなみにPOSIXキャラクターを使ったSedの用法は以下のようになります。
#👇スペースを全部消去
$ echo 'a b c d e f g' | sed -r 's/[[:space:]]//g'
abcdefg
#👇16進数(0-9a-fA-F)を全部消去
$ echo 'HEX: 01 2e 24 a5 8c 2f de' | sed -r 's/[[:xdigit:]]//g'
HX:
実践例① ~ 囲い文字の全消去
それでは具体的な例をやってみます。 CSV形式のデータを扱う時にもっとも良く使うだろう例としては
"
$ sed -r 's/"//g' <<EOF
"aaa"
"100","9"
"1 2 3 4 5",,,41,"冷麦"
EOF
#👇出力
aaa
100,9
1 2 3 4 5,,,41,冷麦
また
"
'
$ sed -r "s/\"|'//g" << EOF
"aaa",'bbb'
"100",'rgb',"9"
"1 2 3 4 5",'3','8',41,"冷麦"
EOF
#👇出力
aaa,bbb
100,rgb,9
1 2 3 4 5,3,8,41,冷麦
もしくは
$ sed -r "s/[\"']//g" << EOF
"aaa",'bbb'
"100",'rgb',"9"
"1 2 3 4 5",'3','8',41,"冷麦"
EOF
#👇出力
aaa,bbb
100,rgb,9
1 2 3 4 5,3,8,41,冷麦
とかけます。
ちなみにこのスクリプトの場合、シングルクォーテーション文字でも置き換えがしたいので、sedのプログラム構文ではダブルクォーテーション
"
\"
'
どうしてもsedのプログラム部分はシングルクォーテーション文字(')で囲いたい方は、
'...'スコープ外'....'
$ sed -r 's/"|'"'"'//g' << EOF
"aaa",'bbb'
"100",'rgb',"9"
"1 2 3 4 5",'3','8',41,"冷麦"
EOF
#👇出力
aaa,bbb
100,rgb,9
1 2 3 4 5,3,8,41,冷麦
EOF
ここでは
's/"|'
"'"
'//g'
デリミタを変える
Sedでは伝統的に
/
/
従って
/
/
$ sed -r 's@"@@g' <<EOF
"aaa"
"100","9"
"1 2 3 4 5",,,41,"冷麦"
EOF
aaa
100,9
1 2 3 4 5,,,41,冷麦
実践例② ~ 全角の数字やアルファベットを半角へ一括変換
こちらもCSVデータをAwkやJqで数値を集計計算する上で、前処理としてやっておくと便利なテクニックです。
たまに半角と全角の数値が混合して出現するExcelデータ内の数値を全て半角にする際のスクリプトをSedコマンドで変換したい場合には、yコマンド利用できます。
yコマンドは、
y/置換前文字リスト/置換後文字リスト/
$ echo 'ABcdefg0123456789' | sed '
y/0123456789/0123456789/;
y/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/;
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
'
ABcdefg0123456789
ほとんどのLinuxOSでは上記のやり方でOKなのですが、一部のAlpineなどのような軽量のディストーションでは、
locate
このyコマンドの性質上、文字の置き換え位置がバイト数が揃っていないと以下のように正しく動作しません。
#👇マルチバイト文字未対応の環境
$ echo 'ABcdefg0123456789' | sed '
y/0123456789/0123456789/;
y/abcdefghijklmnopqrstuvwxyz/abcdefghijklmnopqrstuvwxyz/;
y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
'
A01Fcd0bo0brg012101801�401�6701�01�
この場合、OS環境に則したマルチバイトのライブラリをインストールするか、以下のように泥臭い作業ですが、sコマンドで一文字づつ置き換えパターンを作成すると、OS環境に依らない置き換えも可能です。
echo 'ABcdefg0123456789' | sed -e '
s/0/0/g;s/1/1/g;s/2/2/g;s/3/3/g;s/4/4/g;s/5/5/g;s/6/6/g;s/7/7/g;s/8/8/g;s/9/9/g;
s/a/a/g;s/b/b/g;s/c/c/g;s/d/d/g;s/e/e/g;s/f/f/g;s/g/g/g;s/h/h/g;s/i/i/g;s/j/j/g;s/k/k/g;s/l/l/g;s/m/m/g;s/n/n/g;s/o/o/g;s/p/p/g;s/q/q/g;s/r/r/g;s/s/s/g;s/t/t/g;s/u/u/g;s/v/v/g;s/w/w/g;s/x/x/g;s/y/y/g;s/z/z/g;
s/A/A/g;s/B/B/g;s/C/C/g;s/D/D/g;s/E/E/g;s/F/F/g;s/G/G/g;s/H/H/g;s/I/I/g;s/J/J/g;s/K/K/g;s/L/L/g;s/M/M/g;s/N/N/g;s/O/O/g;s/P/P/g;s/Q/Q/g;s/R/R/g;s/S/S/g;s/T/T/g;s/U/U/g;s/V/V/g;s/W/W/g;s/X/X/g;s/Y/Y/g;s/Z/Z/g;
'
ABcdefg0123456789
まとめ
以上、Sedによる正規表現を用いたテキストファイルの文字列の置き換えの話を簡単にまとめてみました。
記事を書いた人
ナンデモ系エンジニア
主にAngularでフロントエンド開発することが多いです。 開発環境はLinuxメインで進めているので、シェルコマンドも多用しております。 コツコツとプログラミングするのが好きな人間です。
カテゴリー