コマンドラインで脱Excel手作業 フォルダ内の全ファイルでドババンとソートや検索を行う(後編):マウスのいらないコマンドプロンプトの世界
データを順番通りに並べ替えたい場合、Excelを起動して、対象となるデータをシートに読み込んで、[並べ替え]コマンドを実行しているのではないだろうか。ただ、ファイルが複数に分かれていると作業が面倒だ。コマンドを使えば、ファイルを1つにまとめて並べ替えるのも簡単だ。
コマンドを使えば複数ファイルのデータをまとめることも簡単
データの並べ替えが必要な場面は意外と多い。Excelを起動して、ソートを実行することも多いと思うが、複数ファイルに分かれている場合は少し面倒だ。コマンドを使えば、複数ファイルをまとめて、ソートするのも簡単だ。
複数のデータファイルを1つに合わせて並べ替える
マウスのいらないコマンドプロンプトの世界「コマンドラインで脱Excel手作業 フォルダ内の全ファイルでドババンとソートや検索を行う(前編)」では、sortやfindコマンドを使って、単一のファイルに収められたデータの単純な並べ替え作業を行った。しかし、元データが常に1つのファイルに収められた形とは限らない。幾つかのファイルを1つにまとめたり、複数ファイルから目的のデータを集めてきたりして、並べ替えを行わなければならないという場合もある。
そこで今回は、複数のファイルからデータを読み取り、並べ替える方法を紹介する。
マウスのいらないコマンドプロンプトの世界「コマンドラインで脱Excel手作業 フォルダ内の全ファイルでドババンとソートや検索を行う(前編)」でも述べたが、複雑なデータの並べ替えや抽出を行うなら「Microsoft Excel(エクセル)」を使った方が効率的だ。しかし、元データが固定長のフィールドを持ち、単純な並べ替えを行うのであれば、Windows OSのコマンドを利用した方が手っ取り早い。
元データが複数のファイルに分かれている場合でも、データ構造や処理内容が条件に合致していれば、Excelを開いて作業を行うよりも、sortコマンドを使った方が早いだろう。ただし、sortコマンドには弱点もある。それを今回は乗り越えていきたい。
【今回のミッション】
また上司から仕事を頼まれた。
「昨日、全社で開催したボーリング大会のデータが届いたから。キミから指摘のあった点を参考に書式を改善し、スコアを名前より左に置いて点数で並べ替えできるようにして、所属と別に拠点名も追加したぞ。ただ、ファイルは東京本社、大阪支社、福岡支社の各拠点から届いたばかりで、3つに分かれたまま[score]フォルダの中に置いたよ。で、この3つのデータを1つにまとめて、スコアで並べ替えて社内総合スコアランキングを作ってほしいんだな」
何だかボーリング大会ばかりしているようだが、大丈夫なのか、この会社……、という不安はひとまず置いておいて、つまりこういうことだ。
では早速、取り掛かろう。
融通のきかないsortコマンドを小技で生かす
並べ替えの基準は「スコア」に変更されたが、その方法は前回紹介した。今回のポイントは、3つのファイルをまとめて扱うというところだ。
[score]フォルダの下にある「tokyo.txt」「osaka.txt」「fukuoka.txt」という3つのファイルの全てのデータを合わせて並べ替えるということで、まず思い付くのは次のようなコマンドラインではないだろうか。
sort /r score\*.txt > members_rank.txt[Enter]
少し横道にそれるが、「score\*.txt」という記述は、「カレントフォルダの下の[score]フォルダにある拡張子が『txt』のファイル全て」という意味だ。つまり[score]フォルダの親フォルダ(1つ上のフォルダ)をカレントフォルダとして作業している。「[score]フォルダをカレントフォルダにして、作業すれば余計な記述が減るのに」と思うかもしれないが、そうしない理由は後述する。
さて本題に戻ろう。sortコマンドは、引数に入力ファイルを複数並べて記述したり、ワイルドカードを使って複数のファイルを一括指定したり、といったことができない。
では、どうすればよいのだろうか。幾つか方法はあるが、最も手軽なのは標準入力からデータを読み込ませるという方法だ。
具体的には、別のコマンドで複数のファイルを1つにまとめる下処理をして、その結果をパイプライン経由でsortコマンドに渡せばいい(パイプラインについては「コピペの連続はつらいよ ファイルの一覧を文書に取り込む!」参照)。例えば、「ファイルの内容を表示する」というシンプルなコマンド「type」を使って、次のようにすれば、複数のファイルをまとめてsortコマンドに渡し、並べ替えることができる。
type *.txt | sort /r > members_rank.txt[Enter]
typeコマンドの結果をsortコマンドに渡す(1)
typeは入力ファイルを出力するだけというシンプルなコマンドだ。パイプラインと組み合わせれば、複数ファイルを連結してsortコマンドに渡すことができる。
前回紹介したfindコマンドも、typeと同様、複数のファイルを扱えるため、例えば3つのファイルから指定した検索語を含む行を集めてきてsortコマンドに渡すという場合は、複数ファイルからのデータの読み込みをfindコマンドが担ってくれる。3つのファイルから営業部のメンバーを抜き出して、並べ替えるなら次のように指定すればよい。
find "営業部" score\*.txt | sort /r > members_sales_rank.txt[Enter]
なぜデータが置いてあるフォルダで作業しないのか?
これまで、この連載ではデータを置くフォルダで作業をしてきた。しかし今回はデータを置くフォルダ(今回は[score]フォルダ)の1つ上のフォルダで作業を行っている。
その理由は、元データが保存されているファイルと結果を保存するファイルが混在してしまうのを避けるためだ。コマンドの入力例で出力先のファイルに拡張子が「.txt」のファイルを指定しているが、これが入力データと同じフォルダに作成されてしまうと、次回、別の処理を行いたくなったときに「*.txt」に含まれてしまい、正しい処理が行えなくなるのだ。
Copyright© Digital Advantage Corp. All Rights Reserved.