【シェルコマンドだけで極める!】SedとAwkによるCsvファイルの行・列の操作アレコレ


2021/03/30

Csvファイルをコマンドから行を挿入したり列を削除したりなどの操作をする場合には、SedやAwkなどを使うのが一般的です。

今回はシェルコマンドだけで実現できるCsvデータの行と列の操作の基礎的なテクニックをまとめてみます。


はじめに

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

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

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


行の挿入

個別の行の操作にはSedがもっとも適しているコマンドになります。

例えば以下のような簡単なcsvファイルを編集するようなシチュエーションで、以降の各節において具体的なシェルコマンドの実装を考えていきましょう。

            
            $ cat << EOF > employee.csv
山下 モゲ雄,営業部,本社,3年
島田 フガ子,経理部,名古屋支部,15年
岡田 ピポ太,製造部,山口工場,8年
沢口 モフ代,人事部,本社,4年
銭形 ガメ吉,海外部,メキシコ支部,11年
EOF
        

最終行に挿入

最終行に新規の行を挿入する場合にはsedの処理部分を$ a 行内容としてあげます。

            
            $ sed -i '$ a 出川 ゴボ之,営業,大阪支部,1年' employee.csv
$ cat employee.csv
山下 モゲ雄,営業部,本社,3年
島田 フガ子,経理部,名古屋支部,15年
岡田 ピポ太,製造部,山口工場,8年
沢口 モフ代,人事部,本社,4年
銭形 ガメ吉,海外部,メキシコ支部,11年
出川 ゴボ之,営業,大阪支部,1年
        
なおファイルに上書きする場合にsedでのオプションは-iを指定します。

指定の行に挿入

どこか特定の指定された行に挿入したい場合には、やはりsedで行番号i 行内容とします。

            
            $ sed -i '3i 出川 ゴボ之,営業,大阪支部,1年' employee.csv
$ cat employee.csv
山下 モゲ雄,営業部,本社,3年
島田 フガ子,経理部,名古屋支部,15年
出川 ゴボ之,営業,大阪支部,1年
岡田 ピポ太,製造部,山口工場,8年
沢口 モフ代,人事部,本社,4年
銭形 ガメ吉,海外部,メキシコ支部,11年
        
ちなみに行番号は1から順にカウントされるため、3iで挿入した行内容は3行目に来ています。


行の削除

では先ほどとは逆に行を削除させてみます。

指定の行を削除

まずファイルの1行目を消去してみます。

            
            $ sed -i '1d' employee.csv
$ cat employee.csv
島田 フガ子,経理部,名古屋支部,15年
岡田 ピポ太,製造部,山口工場,8年
沢口 モフ代,人事部,本社,4年
銭形 ガメ吉,海外部,メキシコ支部,11年
        
ちゃんと1行目が消えました。

行数dで指定の行番号の内容が削除できます。4行目を消したければ、

            
            $ sed -i '4d' employee.csv
$ cat employee.csv
山下 モゲ雄,営業部,本社,3年
島田 フガ子,経理部,名古屋支部,15年
岡田 ピポ太,製造部,山口工場,8年
銭形 ガメ吉,海外部,メキシコ支部,11年
        
となります。

最終行のみの削除は、最終行を意味する
$を使って、

            
            $ sed -i '$d' employee.csv
$ cat employee.csv
山下 モゲ雄,営業部,本社,3年
島田 フガ子,経理部,名古屋支部,15年
岡田 ピポ太,製造部,山口工場,8年
沢口 モフ代,人事部,本社,4年
        
とできます。

指定の行範囲を削除

先程は一行単位での削除でしたが、範囲削除で複数の連続行も削除可能です。

以下は2〜4行目を削除してみる例です。

            
            $ sed -i '2,4d' employee.csv
$ cat employee.csv
山下 モゲ雄,営業部,本社,3年
銭形 ガメ吉,海外部,メキシコ支部,11年
        
範囲削除の作法としては先頭行,終端行dの構文で利用できます。

ファイルの最終行までを消したい場合には、最終行を表す
$を使って、

            
            $ sed -i '3,$d' employee.csv
$ cat employee.csv
山下 モゲ雄,営業部,本社,3年
島田 フガ子,経理部,名古屋支部,15年
        
とも出来ます。

パターン検索による削除

正規表現を利用して/パターン/dとするとパターンマッチした全ての行を一括して消すことができます。

            
            $ sed -i '/岡田/d' employee.csv
$ cat employee.csv
山下 モゲ雄,営業部,本社,3年
島田 フガ子,経理部,名古屋支部,15年
沢口 モフ代,人事部,本社,4年
銭形 ガメ吉,海外部,メキシコ支部,11年

$ sed -i '/本社/d' employee.csv
$ cat employee.csv
島田 フガ子,経理部,名古屋支部,15年
岡田 ピポ太,製造部,山口工場,8年
銭形 ガメ吉,海外部,メキシコ支部,11年
        

行の抽出

先程の削除とは逆の操作で、該当した行だけを抜き出すテクニックもやってみます。

特定行の抽出

どこか特定の一行のみを取り出したい場合には、行数pという制御文を指定します。

            
            $ sed -n -i '4p' employee.csv
$ cat employee.csv
沢口 モフ代,人事部,本社,4年
        
最終行のみ表示させたい場合には以下のようにできます。

            
            $ sed -n -i '$p' employee.csv
$ cat employee.csv
銭形 ガメ吉,海外部,メキシコ支部,11年
        

範囲指定による抽出

やはり上記の内容と同じ作法で、先頭行,終端行pで範囲指定による抜き出しが行えます。

            
            $ sed -n -i '2,4p' employee.csv
$ cat employee.csv
島田 フガ子,経理部,名古屋支部,15年
岡田 ピポ太,製造部,山口工場,8年
沢口 モフ代,人事部,本社,4年
        

パターン検索による抽出

正規表現を利用して/パターン/pとするとパターンマッチした全ての行を一括して抽出することができます。

            
            $ sed -n -i '/支部/p' employee.csv
$ cat employee.csv
島田 フガ子,経理部,名古屋支部,15年
銭形 ガメ吉,海外部,メキシコ支部,11年
        

列の挿入

Csvデータ前提であれば、列の場合にはAwkを利用する方が細かい制御が可能です。

まずは以下のような追加したい列のデータを用意します。

            
            $ cat << EOF > add_employee.csv
山下 モゲ雄,25歳
島田 フガ子,42歳
岡田 ピポ太,30歳
沢口 モフ代,27歳
銭形 ガメ吉,34歳
EOF
        
csvデータでの列の挿入とは、2つ以上のデータの併せからなるものです。

以前、
別の技術記事でもAwkによる複数のcsvデータの掛け合わせを紹介しましたが、やっていることがその内容と全く同じです。

以下にadd_employee.csvの2列目の内容を、employee.csvの3列目に挿入する例を以下に示します。

            
            $ awk -F "," '
BEGIN {
    OFS=","
}
F == 0 {
    open_arr[$1] = $2;
    next;
}
{
    if($1 in open_arr) {
        print $1, open_arr[$1], $2, $3, $4;
    }
}
' F=0 add_employee.csv F=1 employee.csv > combined.csv
$ cat combined.csv
#👇出力
山下 モゲ雄,25歳,営業部,本社,3年
島田 フガ子,42歳,経理部,名古屋支部,15年
岡田 ピポ太,30歳,製造部,山口工場,8年
沢口 モフ代,27歳,人事部,本社,4年
銭形 ガメ吉,34歳,海外部,メキシコ支部,11年
        

列の削除・範囲取り出し

最後に行の削除(=範囲取り出し)のテクニックをやってみましょう。

これは先程の列の挿入よりは簡単です。

例えばemployee.csvから2行目と4行目を削除した内容(つまり1行目と3行目だけ)にしてみます。

            
            $ awk -F"," '
BEGIN {
    OFS=","
}
{
    print $1, $3;
}
' employee.csv > trimmed.csv
$ cat trimmed.csv
#👇出力
山下 モゲ雄,本社
島田 フガ子,名古屋支部
岡田 ピポ太,山口工場
沢口 モフ代,本社
銭形 ガメ吉,メキシコ支部
        

まとめ

今回はシェルコマンドからcsvの行と列の操作の概論を紹介してきました。

当サイトではこれら紹介してきたテクニックは既知として出現するときもあるので、行と列の操作が分からなくなった場合にはその都度この記事の内容をご確認していただけると幸いです。
記事を書いた人

記事の担当:taconocat

ナンデモ系エンジニア

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