【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法

データ整形作業が煩わしいと感じたことはありませんか?

この記事では、バッチファイルCygwinawkスクリプトを組み合わせ、数行のコードで、以下の例に示す複雑なデータ整形をPowerQueryを使わずに手軽に実現可能とする驚くべき方法を紹介します。

この記事ではCygwinの基本から始め、awkスクリプトの作り方、バッチファイルと Cygwinの awk スクリプトを組み合わせ方まで順にご紹介しますので興味のある方はぜひ最後までご覧下さい。

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
整形作業前CSVファイル

 

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
整形作業後CSVファイル
【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
しらかば堂

この記事には @ac4tweet さんより沢山の貴重なアドバイスを頂いています。
@ac4tweet さんには心より御礼申し上げます。

Cygwinとは?

Cygwinは、Windows環境でUNIX/Linux風のコマンドや環境を使用できるようにするツールです。

このCygwinの中には、Windows上にUNIX互換のオペレーティングシステムをエミュレートするためのライブラリ「cygwin1.dll」や、Windows環境で動作するようにコンパイルされた多数のツールが含まれており

これにより、bash、sed、grep、awkなど、通常UNIX/Linux環境で利用される便利なツールを、Windows環境のターミナル画面「Cygwin64 Terminal」からも利用することができるようになっています。

Cygwin のインストール方法、基本的なコマンド、そして標準入出力・リダイレクション・パイプといった UNIX/Linux 環境下でコマンドをより便利に使うための重要な考え方については以下のような素晴らしい記事が公開されていますので必要に応じてこれらの記事を参照頂ください。

具体的には以下のWindowsの「Cygwin64 Terminal」から起動される

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法

 
次のターミナル画面から bashsedgrepawkといった通常 UNIX/Linux で利用可能な便利なツールを Windows 環境下の下記ターミナル画面から実行します。

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法

Cygwinの実行パスを確認しよう

さてこのCygwin の実行パスはどこにあるのでしょうか。

実はこの実行パスは他の Windows 10 で使用可能なアプリケーションの実行パスの求め方と同様に求めることができます。

つまり下記のように
Windows メニュー > Cygwin > Cygwin64 Terminal > その他 > ファイルの場所を開く

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法


を順番に選択していき、以下のように Cygwin64 Terminal へのショートカットキーへたどり着いた後に

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法


このショートカットキーをマウスで右クリックして コンテキストメニューを表示し、1番下の プロパティ を選択すると次のような画面が出ます。

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法


このリンク先(T): に記入された絶対パスの先頭部分  C:\cygwin64\bin が今まで見てきた画面に登場するフォルダの絶対パス名です。

コマンドライン画面からCygwinを操作する方法

実はWindowsのコマンドラインでCygwinがインストールされているディレクトリへ移動したり、そのディレクトリの実行PATHを設定した後は、Windowsのコマンドラインやバッチファイルから、直接Linuxのコマンドを指定して実行することも可能です。

Cygwinでどんなコマンドが使えるかは先ほどの

C:\cygwin64\bin

配下で “ls *.exe” コマンドを入力すると以下のように確認できます。

つまりこのフォルダ下で .exe という拡張子がついているものが Cygwin で使用可能なコマンドです(Cygwin 配下では .exe の指定は不要)。

Microsoft Windows [Version 10.0.19045.3324]
(c) Microsoft Corporation. All rights reserved.

C:\Users\devel.RVH>cd \cygwin64\bin

C:\cygwin64\bin>ls *.exe
'[.exe'                      env.exe            ld.bfd.exe       pic.exe            tac.exe
 addftinfo.exe               eqn.exe            ld.exe           pinky.exe          tail.exe
 addr2line.exe               expand.exe         ldd.exe          pldd.exe           tar.exe
 ar.exe                      expr.exe           ldh.exe          post-grohtml.exe   taskset.exe
 arch.exe                    factor.exe         less.exe         pr.exe             tbl.exe
 as.exe                      false.exe          lessecho.exe     pre-grohtml.exe    tee.exe
 ash.exe                     file.exe           lesskey.exe      preconv.exe        test.exe
 b2sum.exe                   find.exe           lexgrog.exe      printenv.exe       testlibusb-win.exe
 base32.exe                  flock.exe          link.exe         printf.exe         testlibusb.exe
 base64.exe                  fmt.exe            lkbib.exe        profiler.exe       tfmtodit.exe
 basename.exe                fold.exe           ln.exe           ps.exe             tic.exe
 bash.exe                    gawk-5.1.1.exe     locale.exe       ptx.exe            timeout.exe
 bunzip2.exe                 gawk.exe           locate.exe       pwd.exe            toe.exe
 bzcat.exe                   gcc-ar.exe         logger.exe       pzstd.exe          touch.exe
 bzip2.exe                   gcc-nm.exe         login.exe        ranlib.exe         tput.exe
 bzip2recover.exe            gcc-ranlib.exe     logname.exe      readelf.exe        tr.exe
 c++filt.exe                 gcc.exe            look.exe         readlink.exe       troff.exe
 cal.exe                     gcov-dump.exe      lookbib.exe      readshortcut.exe   true.exe
 cat.exe                     gcov-tool.exe      ls.exe           realpath.exe       truncate.exe
 catman.exe                  gcov.exe           lsattr.exe       rebase.exe         trust.exe
 chattr.exe                  gencat.exe         lto-dump.exe     refer.exe          tset.exe
 chcon.exe                   getconf.exe        lzmadec.exe      regtool.exe        tsort.exe
 chgrp.exe                   getent.exe         lzmainfo.exe     rename.exe         tty.exe
 chmod.exe                   getfacl.exe        make.exe         renice.exe         tzset.exe
 chown.exe                   getopt.exe         man-recode.exe   rev.exe            ul.exe
 chroot.exe                  gkill.exe          man.exe          rm.exe             umount.exe
 chrt.exe                    gmondump.exe       mandb.exe        rmdir.exe          uname.exe
 cksum.exe                   gpg.exe            manpath.exe      run.exe            unexpand.exe
 clear.exe                   gpgsplit.exe       mcookie.exe      runcon.exe         uniq.exe
 cmp.exe                     gpgv.exe           md5sum.exe       script.exe         unlink.exe
 col.exe                     gprof.exe          minidumper.exe   scriptreplay.exe   users.exe
 colcrt.exe                  grep.exe           mintty.exe       sdiff.exe          uuidgen.exe
 colrm.exe                   grn.exe            mkdir.exe        sed.exe            uuidparse.exe
 column.exe                  grodvi.exe         mkfifo.exe       seq.exe            vdir.exe
 comm.exe                    groff.exe          mkgroup.exe      setfacl.exe        vi.exe
 cp.exe                      grolbp.exe         mknod.exe        setmetamode.exe    vim.exe
 cpp.exe                     grolj4.exe         mkpasswd.exe     setsid.exe         wc.exe
 csplit.exe                  grops.exe          mkshortcut.exe   sh.exe             wget.exe
 curl.exe                    grotty.exe         mktemp.exe       sha1sum.exe        whatis.exe
 cut.exe                     groups.exe         more.exe         sha224sum.exe      whereis.exe
 cygcheck.exe                gzip.exe           mount.exe        sha256sum.exe      which.exe
 cygpath.exe                 head.exe           mv.exe           sha384sum.exe      who.exe
 cygstart.exe                hexdump.exe        namei.exe        sha512sum.exe      whoami.exe
 cygwin-console-helper.exe   hostid.exe         nice.exe         shred.exe          windmc.exe
 dash.exe                    hostname.exe       nl.exe           shuf.exe           windres.exe
 date.exe                    hpftodit.exe       nm.exe           size.exe           x86_64-pc-cygwin-gcc-11.exe
 dd.exe                      id.exe             nohup.exe        sleep.exe          x86_64-pc-cygwin-gcc-ar.exe
 df.exe                      indxbib.exe        nproc.exe        soelim.exe         x86_64-pc-cygwin-gcc-nm.exe
 diff.exe                    info.exe           numfmt.exe       sort.exe           x86_64-pc-cygwin-gcc-ranlib.exe
 diff3.exe                   infocmp.exe        objcopy.exe      split.exe          x86_64-pc-cygwin-gcc.exe
 dir.exe                     install-info.exe   objdump.exe      ssp.exe            xargs.exe
 dircolors.exe               install.exe        od.exe           stat.exe           xmlcatalog.exe
 dirname.exe                 ipcmk.exe          openssl.exe      stdbuf.exe         xmllint.exe
 dlltool.exe                 ipcrm.exe          p11-kit.exe      strace.exe         xxd.exe
 dllwrap.exe                 ipcs.exe           passwd.exe       strings.exe        xz.exe
 du.exe                      isosize.exe        paste.exe        strip.exe          xzdec.exe
 dumper.exe                  join.exe           pathchk.exe      stty.exe           yes.exe
 echo.exe                    jq.exe             peflags.exe      sum.exe            zdump.exe
 editrights.exe              kill.exe           pfbtops.exe      sync.exe           zstd.exe
 elfedit.exe                 lastlog.exe        pg.exe           tabs.exe

C:\cygwin64\bin>


この “ls *.exe” はLinux の代表的なコマンドの一つで、 Windows のコマンドラインにおける dir *.exe に相当するコマンドです。

Cygwin64 Terminalでの操作手順

では同じことを Cygwin64 Terminal でも実行してみましょう。

devel@rvhsv01 ~
$ cd '\cygwin64\bin'

devel@rvhsv01 /usr/bin
$ ls *.exe
'[.exe'                      gzip.exe           refer.exe
 addftinfo.exe               head.exe           regtool.exe
 addr2line.exe               hexdump.exe        rename.exe
 ar.exe                      hostid.exe         renice.exe
 arch.exe                    hostname.exe       rev.exe
 as.exe                      hpftodit.exe       rm.exe
 ash.exe                     id.exe             rmdir.exe
 b2sum.exe                   indxbib.exe        run.exe
 base32.exe                  info.exe           runcon.exe
 base64.exe                  infocmp.exe        script.exe
 basename.exe                install-info.exe   scriptreplay.exe
 bash.exe                    install.exe        sdiff.exe
 bunzip2.exe                 ipcmk.exe          sed.exe
 bzcat.exe                   ipcrm.exe          seq.exe
 bzip2.exe                   ipcs.exe           setfacl.exe
 bzip2recover.exe            isosize.exe        setmetamode.exe
 c++filt.exe                 join.exe           setsid.exe
 cal.exe                     jq.exe             sh.exe
 cat.exe                     kill.exe           sha1sum.exe
 catman.exe                  lastlog.exe        sha224sum.exe
 chattr.exe                  ld.bfd.exe         sha256sum.exe
 chcon.exe                   ld.exe             sha384sum.exe
 chgrp.exe                   ldd.exe            sha512sum.exe
 chmod.exe                   ldh.exe            shred.exe
 chown.exe                   less.exe           shuf.exe
 chroot.exe                  lessecho.exe       size.exe
 chrt.exe                    lesskey.exe        sleep.exe
 cksum.exe                   lexgrog.exe        soelim.exe
 clear.exe                   link.exe           sort.exe
 cmp.exe                     lkbib.exe          split.exe
 col.exe                     ln.exe             ssp.exe
 colcrt.exe                  locale.exe         stat.exe
 colrm.exe                   locate.exe         stdbuf.exe
 column.exe                  logger.exe         strace.exe
 comm.exe                    login.exe          strings.exe
 cp.exe                      logname.exe        strip.exe
 cpp.exe                     look.exe           stty.exe
 csplit.exe                  lookbib.exe        sum.exe
 curl.exe                    ls.exe             sync.exe
 cut.exe                     lsattr.exe         tabs.exe
 cygcheck.exe                lto-dump.exe       tac.exe
 cygpath.exe                 lzmadec.exe        tail.exe
 cygstart.exe                lzmainfo.exe       tar.exe
 cygwin-console-helper.exe   make.exe           taskset.exe
 dash.exe                    man-recode.exe     tbl.exe
 date.exe                    man.exe            tee.exe
 dd.exe                      mandb.exe          test.exe
 df.exe                      manpath.exe        testlibusb-win.exe
 diff.exe                    mcookie.exe        testlibusb.exe
 diff3.exe                   md5sum.exe         tfmtodit.exe
 dir.exe                     minidumper.exe     tic.exe
 dircolors.exe               mintty.exe         timeout.exe
 dirname.exe                 mkdir.exe          toe.exe
 dlltool.exe                 mkfifo.exe         touch.exe
 dllwrap.exe                 mkgroup.exe        tput.exe
 du.exe                      mknod.exe          tr.exe
 dumper.exe                  mkpasswd.exe       troff.exe
 echo.exe                    mkshortcut.exe     true.exe
 editrights.exe              mktemp.exe         truncate.exe
 elfedit.exe                 more.exe           trust.exe
 env.exe                     mount.exe          tset.exe
 eqn.exe                     mv.exe             tsort.exe
 expand.exe                  namei.exe          tty.exe
 expr.exe                    nice.exe           tzset.exe
 factor.exe                  nl.exe             ul.exe
 false.exe                   nm.exe             umount.exe
 file.exe                    nohup.exe          uname.exe
 find.exe                    nproc.exe          unexpand.exe
 flock.exe                   numfmt.exe         uniq.exe
 fmt.exe                     objcopy.exe        unlink.exe
 fold.exe                    objdump.exe        users.exe
 gawk-5.1.1.exe              od.exe             uuidgen.exe
 gawk.exe                    openssl.exe        uuidparse.exe
 gcc-ar.exe                  p11-kit.exe        vdir.exe
 gcc-nm.exe                  passwd.exe         vi.exe
 gcc-ranlib.exe              paste.exe          vim.exe
 gcc.exe                     pathchk.exe        wc.exe
 gcov-dump.exe               peflags.exe        wget.exe
 gcov-tool.exe               pfbtops.exe        whatis.exe
 gcov.exe                    pg.exe             whereis.exe
 gencat.exe                  pic.exe            which.exe
 getconf.exe                 pinky.exe          who.exe
 getent.exe                  pldd.exe           whoami.exe
 getfacl.exe                 post-grohtml.exe   windmc.exe
 getopt.exe                  pr.exe             windres.exe
 gkill.exe                   pre-grohtml.exe    x86_64-pc-cygwin-gcc-11.exe
 gmondump.exe                preconv.exe        x86_64-pc-cygwin-gcc-ar.exe
 gpg.exe                     printenv.exe       x86_64-pc-cygwin-gcc-nm.exe
 gpgsplit.exe                printf.exe         x86_64-pc-cygwin-gcc-ranlib.exe
 gpgv.exe                    profiler.exe       x86_64-pc-cygwin-gcc.exe
 gprof.exe                   ps.exe             xargs.exe
 grep.exe                    ptx.exe            xmlcatalog.exe
 grn.exe                     pwd.exe            xmllint.exe
 grodvi.exe                  pzstd.exe          xxd.exe
 groff.exe                   ranlib.exe         xz.exe
 grolbp.exe                  readelf.exe        xzdec.exe
 grolj4.exe                  readlink.exe       yes.exe
 grops.exe                   readshortcut.exe   zdump.exe
 grotty.exe                  realpath.exe       zstd.exe
 groups.exe                  rebase.exe

devel@rvhsv01 /usr/bin
$


さてここで一番最初に入力した

$ cd '\cygwin64\bin'


というコマンドに注目してみましょう。

この2つの ’ ’ (シングルクオーテーション)で囲んでいる中身の部分の表現は Windows のコマンドラインで使用しているフルパスの表記法と同じです。

つまり Cygwin では Windows のコマンドライン、エクスプローラで使用しているフルパス表現を2つの ’ ’ (シングルクオーテーション)で囲むことでそのまま使用することができます。

 

参考情報:WSL2 Ubuntsu でのWindows フォルダの指定方法

参考の為に同じことを Windows 10 内の WSL2 機能を使ってインストールした正式なLinux、つまり Ubuntu 22.04.2 でもやってみると

devel@rvhsv01:~$ cd '\cygwin64\bin'
-bash: cd: \cygwin64\bin: No such file or directory

残念ながら Ubuntu 22.04.2 では Cygwin内で許容された

cd 'c:\cygwin64\bin'


という様な Windowsのフルパス記述は許容されていません。

代わりに同ディレクトリの Linux としての完全なパス名である

cd /mnt/c/cygwin64/bin


というフルパスの入力(この /mnt/c という表現は Linux のOS にマウントされているドライブの中の C: ドライブのことを指します)をします。

あるいは wsl 環境でWindows環境、Linux環境間でのパスを取得する wslpath コマンドを使って

devel@rvhsv01:~$ echo $(wslpath -u 'c:\cygwin64\bin')
/mnt/c/cygwin64/bin
devel@rvhsv01:~$ echo $(wslpath -w '/mnt/c/cygwin64/bin')
C:\cygwin64\bin


あるいは

devel@rvhsv01:~$ echo `wslpath -u 'c:\cygwin64\bin'`
/mnt/c/cygwin64/bin
devel@rvhsv01:~$ echo `wslpath -w '/mnt/c/cygwin64/bin'`
C:\cygwin64\bin


を使ってcd コマンドのパス名を求め

devel@rvhsv01:~$ cd `wslpath -u 'c:\cygwin64\bin'`
devel@rvhsv01:/mnt/c/cygwin64/bin$

といった書き方をします。この $()あるいは2つの“(バッククォート)はその中に囲まれたコマンドを実行した結果の文字列を使うという意味です。

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
しらかば堂

こういった方法を使えばUbuntuでもWindows のフルパス名から Ubuntsu 内のフルパス名を求めることが可能ですが Cygwin でのフォルダ名を2つの  ’ ’ (シングルクオーテーション)で囲むやり方の方が直観的でわかりやすいですよね。

そこでしらかば堂はバッチファイルから Linux コマンドを利用したいときは Ubuntu ではなく Cygwin を利用しています。

参考情報: CygwinでのWindows フォルダの指定方法

ところで Cygwin にも Ubuntu 同様 Cygwin 環境でWindows環境、Linux環境間でパスを取得する cygpath コマンドというものが準備されており

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ cygpath -w "/usr/local/bin"
C:\cygwin64\usr\local\bin

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ cygpath -u "C:\cygwin64\usr\local\bin"
/usr/local/bin


この cygpath コマンドと$()を使って作業フォルダを変更したり、

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ echo $(cygpath -u "C:\cygwin64\usr\local\bin")
/usr/local/bin

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ cd $(cygpath -u "C:\cygwin64\usr\local\bin")

devel@rvhsv01 /usr/local/bin
$


あるいは cygpath コマンドと2つの “(バッククォート)を使って作業フォルダを変更することができます。

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ echo `cygpath -u "C:\cygwin64\usr\local\bin"`
/usr/local/bin

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ cd $(cygpath -u "C:\cygwin64\usr\local\bin")

devel@rvhsv01 /usr/local/bin
$ cd 'C:\cygwin64\usr\local\bin'

devel@rvhsv01 /usr/local/bin
$


ここに見るようにCygwinからWindowsのフォルダを指定する場合

cd $(cygpath -u "C:\cygwin64\usr\local\bin")

cd 'C:\cygwin64\usr\local\bin'

はほぼ同じ効果をもたらしますが、Cygwinのbash からWindowsのパスで指定したシェルスクリプトを起動する際は2つの’ ’ (シングルクオーテーション)で囲んだパスでは何故か起動できず、$()で囲んだパスのみで起動できるという差分があります。

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
しらかば堂

なお Linux/UNIX環境下のシェルスクリプトにおける, ”, “”, \, “, $()の使用方法について @HAHOHIHOHU さんが素晴らしい記事を書かれているので必要に応じてそちらも必要に応じて参照くださいね。

Shell scriptにおける, ”, “”, \, “, $()まとめ

パワフルなスクリプト言語awk

サンプルデータでawkの力を体感しよう

さて Cygwin 配下で利用可能なスクリプト言語 awk の便利さを体感するため
なんちゃって個人情報 にて500件ほどデータを作成し、これを文字コードutf-8csv形式で

%USERPROFILE%\Downloads\dummy.csv

へ保存し、これを Cygwin Terminal で出力してみましょう。

%USERPROFILE% については必要に応じて以下の関連記事も参照下さい。

【Windows業務効率化】バッチファイルの基本テクニックを知ろう

まずWindows上での絶対パスを確認するために、一旦Windowsのコマンドプロンプト内で上記のフォルダへ cd コマンドで移動します。

Microsoft Windows [Version 10.0.19045.3324]
(c) Microsoft Corporation. All rights reserved.

C:\Users\devel.RVH>cd %USERPROFILE%\Downloads

C:\Users\devel.RVH\Downloads>
C:\Users\devel.RVH\Downloads>dir d*.csv
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 2485-30D8 です

 C:\Users\devel.RVH\Downloads のディレクトリ

2023/08/18  22:42            74,559 dummy.csv
               1 個のファイル              74,559 バイト
               0 個のディレクトリ  281,937,391,616 バイトの空き領域

C:\Users\devel.RVH\Downloads>

 

このコマンド結果から上記の絶対パス名が

C:\Users\devel.RVH\Downloads

ファイル名が

dummy.csv

であることがわかりました。

今度はこれを Cygwin64 Terminal で参照し、csvファイルの中身を確認してみましょう。

$ cd 'C:\Users\devel.RVH\Downloads'

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Downloads
$ ls d*.csv
dummy.csv

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Downloads
$ wc d*.csv
  501  1596 74559 dummy.csv

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Downloads
$ head d*.csv
名前,ふりがな,アドレス,性別,年齢,誕生日,婚姻,都道府県,携帯,キャリア,カレーの食べ方
越智 たまき,おち たまき,ochi_tamaki@example.com,女,40,1982/11/6,既婚,群馬県,090-7685-7025,au,右ルー・せき止め派
川添 佳乃,かわぞえ よしの,kawazoe_yoshino@example.com,女,21,2002/5/31,未婚,熊本県,090-7883-1303,ドコモ,ぶっかけ・別口派
毛利 莉緒,もうり りお,mouri_rio@example.com,女,61,1962/8/2,既婚,神奈川県,090- 132-3456,ツーカー,左ルー・せき止め派
大山 光,おおやま ひかる,ooyama_hikaru@example.com,男,26,1997/1/27,既婚,神奈川県,080-9974-2396,ソフトバンク,奥ルー・せき止め派
五味 圭,ごみ けい,gomi_kei@example.com,男,63,1960/8/14,既婚,兵庫県,080-1923-7247,au,ぶっかけ・混ぜ混ぜ派
秋葉 信吾,あきば しんご,akiba_shingo@example.com,男,48,1975/2/28,既婚,秋田県,080- 241-7694,ドコモ,左ルー・せき止め派
平田 憲史,ひらた のりひと,hirata_norihito@example.com,男,53,1969/9/3,既婚,東京都,080-1106-5699,au,右ルー・混ぜ混ぜ派
柳沢 和之,やなぎさわ かずゆき,yanagisawa_kazuyuki@example.com,男,56,1966/11/18,既婚,岡山県,080-1425-4206,ドコモ,左ルー・せき止め派
平川 芽以,ひらかわ めい,hirakawa_mei@example.com,女,24,1998/10/6,既婚,長野県,080-3727-1124,ドコモ,ぶっかけ・ルー攻め派

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Downloads
$

 

ここでの操作の内容を簡単に紹介すると以下のようになります。

行数 コマンド 意味
1 cd ‘C:\Users\devel.RVH\Downloads’ Windows コマンドラインで確認したパスを使ってCygwin の中でフォルダ(ディレクトリ)移動します。その結果このフォルダはCygwinの中では
/cygdrive/c/Users/devel.RVH/Downloads
と表現されることがわかります。
4 ls d*.csv このフォルダに中に目的のファイル dummy.csv が存在するかを ワイルドカード * 付きの ls コマンドで確認しています。
8 wc d*.csv 念のためこの dummy.csv の行数(、単語数、文字数)を wc コマンドで確認しました。 なんちゃって個人情報 では件数を500件と指定して作成しているので、表題部も入れて501行あります。
12 head d*.csv 全部表示するとえらいことになるので、 head コマンドで最初の表題部も含めた10行分を表示しています。


この実行結果から、この dummy.csv が次のようなフィールド構成を持ったcsvファイルであることがわかりますね。

フィールド位置フィールド名
1名前
2ふりがな
3アドレス
4性別
5年齢
6誕生日
7婚姻
8都道府県
9携帯
10キャリア
11カレーの食べ方

条件付きレコードとフィールドの抽出をマスターするawkの使い方

さて、ここからがこの記事の真骨頂です。

まずは以下をご覧ください。

これは dummy.csv から$4[つまり4番目の性別フィールド]が”” かつ $8[つまり8番目の都道府県フィールド]が“東京都”という条件を満たすレコードのみを対象に、”,” をフィールドのセパレータとして指定した時の$1[つまり1番目の名前フィールド]と$9[つまり9番目の携帯フィールド]のみを”,”で区切って表示するawkコマンド(スクリプト言語)とその実行結果です。

$ cat dummy.csv  | awk -F , '$4=="男" && $8=="東京都" { printf("%s,%s\n", $1,$9) }'
平田 憲史,080-1106-5699
原口 長利,080-3334-3271
大和 隆,090- 981-6868
細山 正義,080-7782-3514
根岸 豊,090-6475-2324
今田 光臣,090-9669-3186
池田 憲一,090-7560-9114
角谷 聡,080-4061-1381
水谷 優一,080-2592-6348
村上 洋,080-2751-6213
皆川 正敏,090-9582-6568
岡田 ケンイチ,090-3325-3107
臼井 充則,090-7661-8985
深沢 ジョージ,080-9273-8284
北野 努,080-8757- 243
久保田 大,080-7019-1834
奥 ヒロ,090-5213-5174
浅見 優一,090-1933-5006
高松 まさし,080-3287-8809
羽田 健,090-3691-4825
根岸 徹,090-5238-9615
三原 光臣,090- 581-8093
長岡 米蔵,080-1606-3401
大和田 完爾,080-4688-9697
堀口 正義,090-8284- 128
福原 惇,080-7191-3891

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Downloads
$


そしてさらに先ほどの実行結果に次のパイプ以降をつなげると

$ cat dummy.csv  | awk -F , '$4=="男" && $8=="東京都" { printf("%s,%s\n", $1,$9) }' | nkf -Lw -s >output.csv

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Downloads
$


あっという間にここで抽出条件にあったcsvファイルができてしまいました。

またこの’nkf -Lw -s’というコマンドはCygwinの公式パッケージには含まれているコマンドではありませんが、文字コードをutf-8からShift-JISに変更するためのフィルタプログラムです。

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
整形作業後CSVファイル
【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
しらかば堂

この awk というスクリプト言語はしらかば堂がWindows環境下でもUnix/Linuxの環境を使いたいと考える理由の相当の部分を占めており

前のコマンドの出力結果を’|’(パイプ)を使って次のawkスクリプトの入力として printf 文でコマンド列を作成し、さらに’|’(パイプ)を使ってそれを続くshコマンドに渡してそれを実行する

といったこと、例えばあるフォルダ配下のサブフォルダ配下に含まれるpdfファイルを指定フォルダ配下に一括コピーするといったこと、を本当に簡単に実現可能な最強のスクリプト言語の一つです。興味のある方は、以下の書籍で確認してみてくださいね。

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
しらかば堂

nkf コマンドもCygwinの公式パッケージには含まれていないのですが、nurse 氏を筆頭とする開発者の方が開発された Windows のShift-JISコードと Cygwin のutf-8 コード間の橋渡しをする重要なフィルタ(データストリームを処理するプログラム)です

興味のある方は@ITの以下の記事

【 nkf 】コマンド――文字コードと改行コードを変換する

で利用方法等について併せて参照ください。

nkf の最新版を利用する場合には nurse 氏の GitHub に clone されているので v2_1_5 等の tag から tar.gz 拾うか master の tar.gz 拾ってビルドする必要があります。

参考情報:CSVとTSVどちらを選ぶか

この記事では入力ファイルをCSVファイル(フィールドを’,’で区切ったファイル)としたためawkコマンドでフィールドの区切りを “-F ,” とし、’,’ をセパレータとして指定していますが、フィールドの文字列の中に’,’を含むケースもあるかと思います。

そういったケースでは入力ファイルをTSVファイル(フィールドをTABで区切ったファイル)にできないかを検討しましょう。文字列のなかに TAB を含むケースではは同様の問題が生じますが、’,’ を含む場合に比べればレアケースでしょう。

この場合はawkコマンドでフィールドの区切りは “-F \t“のように指定します。

データ整形を効率化!Cygwinのawkスクリプトをバッチファイルで実行

Cygwinのawkスクリプトを習得しよう

さて以上を踏まえ、先ほど Cygwin 内で実行したawkコマンドをTeraterm等のエディタで作成し、utf-8コードで保存することで、次の様なスクリプトファイル

cat "$1" | awk -F , '$4=="男" && $8=="東京都"  { printf("%s,%s\n", $1,$9) }' | nkf -Lw -s >"${1%.*}_extructed.${1##*.}"
echo "${1%.*}_extructed.${1##*.}" を作成しました。

 

  • get_nameAndPhoneNumber.sh

を作成し 

  • %USERPROFILE%\Tools\bash

配下に保存し

C:\Users\devel.RVH>cd %USERPROFILE%\Tools\bash

C:\Users\devel.RVH\Tools\bash>dir
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 2485-30D8 です

 C:\Users\devel.RVH\Tools\bash のディレクトリ

2023/08/20  13:28    <DIR>          .
2023/08/20  13:28    <DIR>          ..
2023/08/20  13:48                85 get_nameAndPhoneNumber.sh
               1 個のファイル                  85 バイト
               2 個のディレクトリ  289,922,293,760 バイトの空き領域

C:\Users\devel.RVH\Tools\bash>

 

さらにCygwin Terminalでこのファイルにシェルスクリプトとして実行可能とするためにchmod コマンドで x(実行権)パーミッションを追加します。

devel@rvhsv01 ~
$ cd 'C:\Users\devel.RVH\Tools\bash'

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ ls
get_nameAndPhoneNumber.sh

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ cat get_nameAndPhoneNumber.sh
cat "$1" | awk -F , '$4=="男" && $8=="東京都"  { printf("%s,%s\n", $1,$9) }' | nkf -Lw -s >"${1%.*}_extructed.${1##*.}"
echo "${1%.*}_extructed.${1##*.}" を作成しました。

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ ls -l
total 1
-rw-rw-rw-+ 1 devel Domain Users 85 Aug 20 13:48 get_nameAndPhoneNumber.sh

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ chmod 775 get_nameAndPhoneNumber.sh

devel@rvhsv01 /cygdrive/c/Users/devel.RVH/Tools/bash
$ ls -l
total 1
-rwxrwxr-x+ 1 devel Domain Users 85 Aug 20 13:48 get_nameAndPhoneNumber.sh


このスクリプト get_nameAndPhoneNumber.sh はその1行目にパイプ’|’、リダイレクション’>’からなる複数のパートから構成されていますが、その内容を紹介すると以下のようになります。

行数 項番 コマンド 意味
1 1 cat “$1” |

このシェルスクリプトget_nameAndPhoneNumber.shの第1パラメータで指定されるファイル内容をパイプ’|‘経由で次のコマンドの標準入力に渡します。
ここでは空白を含むパスが渡された際にも正しく動作するように$1を””で囲んで “$1”としています。

2 awk -F , ’$4==”男” && $8==”東京都” { printf(“%s,%s\n”, $1,$9) }’ |

標準入力からのデータを、先ほどCygwin Terminal 内で実行した
$4[つまり4番目の性別フィールド]が”” かつ
$8[つまり8番目の都道府県フィールド]が“東京都”
という条件を満たすレコードのみを対象に、

,” をフィールドのセパレータとして指定したときの
$1[つまり1番目の名前フィールド]と
$9[つまり9番目の携帯フィールド]のみを
“,”で区切って表示するawkスクリプトで、

結果をさらにパイプ’|‘経由で次のコマンドの標準入力に渡します。

3 nkf -Lw -s >”${1%.*}_extructed.${1##*.}”

標準入力からのデータを、nkf コマンドで文字コードをutf-8からShift-JISに変更し、

その結果をリダイレクト’>‘を使って”${1%.*}_extructed.${1##*.}“というファイルに書き込みます。

この”${1%.*}”、”${1##*.}”という表現はbash環境で変数を展開し、ファイル名や拡張子の取得する方法で、

${1%.*}”は$1の拡張子を取り除いたファイ名
“${1##*.}”は拡張子部分

になります。

ここでは空白を含むパスが渡された際にも正しく動作するようにこれらをを””で囲んでいます。

2 “${1%.*}_extructed.${1##*.}” を作成しました。 1行目の項番3で作成したファイル名を確認のために表示しています。
【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
しらかば堂

ここで1行目の項番1の “$1”はシェルスクリプトget_nameAndPhoneNumber.shのパラメータ順を表していますが

項番2の$1,$9awkコマンドの標準入力に対するフィールド順番を表しており、意味が違うので注意が必要です。

またbashの変数展開については @mriho さんの素晴らしい記事

bashの変数展開によるファイル名や拡張子の取得

がありますので、こちらも必要に応じて参照ください。

アクセス権(パーミッション)

Linux/Cygwinのファイルやディレクトリには、アクセス権が設定されます。アクセス権(パーミッション)とは、どのユーザーに対してどういった操作を許可するのかという情報のことです。

アクセス権は、所有者、所有グループに属するユーザー、その他のユーザーの、3種類に対して設定できます。アクセス権には、読み取り可能、書き込み可能、実行可能の3種類があります。

ファイルに対して読み取り権のみが与えられている場合、そのファイルの内容を
読み取ることができますが、変更を加えることはできません。ディレクトリに対して読み取り権が与えられている場合、そのディレクトリ内のファイル一覧を表示すること
ができます。

ファイルに対して書き込み権が与えられている場合、ファイルの内容を変更した
り、削除したりすることができます。ディレクトリに対して書き込み権が与えられている場合、そのディレクトリ内でファイルを作成したり、削除したりすることができます。

ファイルに対して実行権が与えられている場合、そのファイルを実行することができます。ディレクトリに対して実行権が与えられている場合、そのディレクトリ内のファイルにアクセスすることができます。アクセス権は、以下のように表記されます。

権限 表記
読み取り権
書き込み権
実行権
$ ls -l
total 1
-rwxrwxr-x+ 1 devel Domain Users 85 Aug 20 13:48 get_nameAndPhoneNumber.sh

実行結果の左のほうにある「rwxrwxr-x」の部分がアクセス権です。
アクセス権は左から3文字ずつ、「ユーザー(所有者)のアクセス権」「グループのア
クセス権」「その他ユーザーのアクセス権」を表しており、「-」はその部分のアクセス権がないことを意味します。get_nameAndPhoneNumber.shというファイルでは、アクセス権は次のようになっています。
● 所有者に対しては「読み取り可能、書き込み可能、実行可能」
● グループに対しては「読み取り可能、書き込み可能、実行可能」
● その他ユーザーに対しては「読み取り可能、実行可能」

アクセス権の左側の1文字は、ファイルの種別を表します。「-」は通常のファイ
ル、「d」はディレクトリ、「l」はリンクを表します。

またアクセス権は、数値でも表すことができます。この場合、「読み取り=4」「書き込み=2」「実行=1」として、所有者、グループ、その他ユーザーごとに足した数
値で表します。

所有者 グループ その他ユーザー
rwx rwx r-x :記号表記
421 421 41
7 7 5 :数字表記


バッチファイルの作成手順をステップバイステップで解説

そしてこのスクリプトファイルを起動するバッチファイルとして次のバッチファイル

  • GetNameAndPhoneNumber.bat

を作成し 

  • %USERPROFILE%\Tools\bat

配下に保存しましす。

@echo on
setlocal
PATH=C:\cygwin64\bin;%PATH%
bash  --login -i -c """$(cygpath -u ""C:\Users\devel.RVH\Tools\bash\get_nameAndPhoneNumber.sh"")"" '%~1'"
endlocal


こちらのバッチファイルについても簡単にその内容を説明します。

説明
1 このコマンド以降以降の出力を抑制します。
2 バッチファイル中のendlocalまでに利用する変数(具体的には$PATH)をローカル変数として利用する宣言をします
3 このバッチファイルの中でCygwinのコマンドが利用可能なようにWindowsの実行パス%PATH%にCygwinの実行パス”C:\cygwin64\bin“を追加します。
4

バッチファイルからCygwin環境下のbash経由でシェルスクリプト
C:\Users\devel.RVH\Tools\bash\get_nameAndPhoneNumber.sh’
(=/cygdrive/c/Users/devel.RVH/Tools/bash/get_nameAndPhoneNumber.sh)
‘%~1‘ (つまりこのバッチファイルの第一パラメータで指定されたcsvファイルのパスをCygwinのパスに変更したもの)を付けて起動します(注)
これらのパラメータはシェルスクリプトの中では $1として参照されます。

5

3行目で宣言したローカル変数宣言を解除します。

(注) バッチファイルから Cygwinbash を実行する際は次のように記述します。
\cygwin64\bin\bash –login -i -c “bash に渡すコマンド文字列”

この実行時パラメータの意味は以下のようになっています。

パラメータ 意味
-login Cygwin へログインする
-i  bash をインタラクティブモード、つまり後続のコマンド文字列が端末から入力されたかのようにbash を動かすことを指定
-c 次にくる2つのダブルクオーテーション ” ” で囲んだ文字列を bash に渡すコマンド文字列とすること
【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
しらかば堂

バッチファイルのパラメータに関する修飾演算子に付いては必要に応じて下記の関連記事を参照ください。

【Windows業務効率化】バッチファイルの引数、Shiftコマンド、Forコマンド、修飾子を知ろう

バッチファイル実行の結果を詳細に分析

以下がこの

%USERPROFILE%\Downloads\dummy.csv

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
整形作業前CSVファイル

に対し

  • GetNameAndPhoneNumber.bat

を実行した結果です。

Microsoft Windows [Version 10.0.19045.3324]
(c) Microsoft Corporation. All rights reserved.

C:\Users\devel.RVH>cd %USERPROFILE%\Tools\bat

C:\Users\devel.RVH\Tools\bat>dir GetN*
 ドライブ C のボリューム ラベルがありません。
 ボリューム シリアル番号は 2485-30D8 です

 C:\Users\devel.RVH\Tools\bat のディレクトリ

2023/08/21  05:29               583 GetNameAndPhoneNumber.bat
               1 個のファイル                 583 バイト
               0 個のディレクトリ  289,975,209,984 バイトの空き領域

C:\Users\devel.RVH\Tools\bat>GetNameAndPhoneNumber %USERPROFILE%\Downloads\dummy.csv
\Users\devel.RVH\Downloads\dummy_extructed.csv を作成しました。

C:\Users\devel.RVH\Tools\bat>

 

そしてこれが抽出結果

%USERPROFILE%\Downloads\dummy_extructed.csv

【特集】データ整形を簡単に!バッチファイルからCygwinのawkスクリプトを呼び出す方法
整形作業後CSVファイル

です。

ほんの一瞬で変換が終わりました。

まとめ:データ整形の驚くべき方法がここに

いかがですか?

この記事では、バッチファイルCygwinawkスクリプトを組み合わせ、数行のコードで、以下の例に示す複雑なデータ整形をPowerQueryを使わずに手軽に実現可能とする驚くべき方法を紹介しました。

この記事ではCygwinの基本から始め、awkスクリプトの作り方、バッチファイルと Cygwinの awk スクリプトを組み合わせ方まで順にご紹介しました。

この方法はawkスクリプト部分をカスタマイズすることで、こういったデータ整形のみならずWindowsのファイルの一括移動、名称変更、一括削除等にも流用が可能な汎用的な技術ですので是非あなたの業務効率化にお役立て下さい。

この記事が少しでも読者の方のお役に立てれば幸いです。