検索
連載

コマンドラインで脱Excel手作業 フォルダ内の全ファイルでドババンとソートや検索を行う(前編)マウスのいらないコマンドプロンプトの世界

データを順番通りに並び替えたい場合、Excelを起動して、対象となるデータをシートに読み込んで、[編集]グループの[並べ替え]コマンドを実行しているのではないだろうか。ファイルが複数に分かれていると作業がさらに面倒になる。でも、データによってはコマンドを使った方が数倍速く処理できる。コマンドを使って時短しよう。

Share
Tweet
LINE
Hatena
並べ替えはデータベースやExcelの仕事?
並べ替えはデータベースやExcelの仕事?
データの並べ替えが必要な場面は意外と多い。データベースやExcelを起動して、ソートを実行することも多いと思う。データによっては、データベースやExcelの起動を待っている間に、コマンドを使ってサックリとソートが実行できる。

ほとんどはExcelで済ますが、全てではない!

 データを一定の基準に従って並べ替えるというニーズは、世の中の至るところにある。例えば、入力順の取引データを決済日付順に並べ替えたり、あいうえお順に並ぶ名簿を会員番号順に並べ替えたりするようなケースだ。

 こうした並べ替えは、一般に業務システムやデータベース管理システムといったデータを扱うアプリケーション側に機能として組み込まれていることも多い。だが、何らかの理由により自前で並べ替えなければならない事態に直面することもある。

 筆者はそうしたとき、ほとんどの場合、「Microsoft Excel(エクセル)」を利用している。ただし「ほとんどの場合」であり、「全ての場合」ではない。なぜならデータの構造や並べ替えの基準によっては、Windows OSのコマンドラインから処理した方が圧倒的に早いからだ。

 Excelなら、まず起動してデータを読み込み、[データ]メニューを選択し、表示されるリボン上で[並べ替え]を選択して、ダイアログボックス上で並べ替えのためのキーを指定して並び替えを実行する。その後、[ファイル]メニューから[名前を付けて保存]を選択し、ダイアログボックスでファイル名を指定して保存するという一連の手順を踏む。特に複数のファイルを処理したいような場合は、ファイルごとにこの作業を行わなくてはならず、と意外と面倒だ。

 これは、例えるなら鉛筆を削るために多機能で重たい電動工具を引っ張り出してくるようなものだ。目の前の鉛筆1本を削るだけなら、手動の鉛筆削り器やカッターナイフで事足りるし、むしろ手早い。Windows OSのコマンドならば、この一連の作業がコマンドラインをわずか1行記述するだけで片付けられるのだ。これを順番に行うようにすれば、大量のファイルであっても簡単に作業できる。

 今回は、まず複数ファイルを処理する前段階として、1つのファイルで並べ替えする方法を取り上げる。

【今回のミッション】

 上司から、次のような内容の名簿データが収められたテキストファイルmembers_rnd.txtを渡された。一人分のデータの各項目が、カンマで区切られて1行にまとめられている、いわゆるCSV形式というやつだ。

並べ替える前のCSVデータ
並べ替える前のCSVデータ
CSV形式のファイルは1行が1件分のデータで、各行のカンマで区切られたそれぞれの範囲を「フィールド」と呼ぶ。例では、「社員番号」「所属部署」「氏名」「スコア」という4つのフィールドから構成されている。

 現在は順不同に並んでいるこのデータを、行頭の社員番号の若い順に並べ替えてほしいというのだ。

 「そんなの最初から従業員データベースで社員番号をキーにして抽出すればいいのでは?」と進言してみた。

 すると「じゃあ、キミがそのようにやっておいてくれたまえ。ヨロシク。ちなみにそれ、社内ボーリング大会のアベレージスコアなので従業員データベースには入ってないのよね」と言われた。

 ここはさっさと言われたことを済ませてしまった方が得策。さて、どうやる?


単純な並べ替えならsortコマンド一発で!

 今回のミッションは、もちろんExcelでも処理できるが、行頭の社員番号で並べ替えるだけならWindows OSのコマンドの方が手っ取り早い。次の1行で結果がmembers_num.txtに保存される。

sort members_rnd.txt > members_num.txt[Enter]


CSVファイルの中身を並べ替えてファイルに書き出すコマンド

 おそらくExcelの起動を待つ間に、全ての処理が終わってしまうはずだ。実行結果は次の通り。

sortコマンドの実行結果(1)
sortコマンドの実行結果(1)
並べ替え(ソート)を実行する前のデータを確認しておこう。それにはmoreコマンドを使って、ファイルの中身を表示すればよい。
sortコマンドの実行結果(2)
sortコマンドの実行結果(2)
リダイレクトを使っているので、sortコマンドの実行結果は画面に表示されずファイルに保存される。実行後、moreコマンドでファイルを表示させると、社印番号順に並べ替えられていることが分かる。

 このコマンドラインは「sortコマンドにmembers_rnd.txtを読み込み、行頭から文字を比較して、昇順(「0」から「9」、「A」から「Z」の順)でデータを並べ替え、結果をmembers_num.txtというファイルに出力する」というものだ。ちなみに「/R」オプションを指定すれば降順(「9」から「0」、「Z」から「A」の順)で並べ替えられる。

 コマンドライン後半の「> members_num.txt」という部分は「結果を画面に出力する代わりに指定したファイルに出力する」という指定だ。このように出力先を切り替える操作を「リダイレクト」と呼ぶ。

 前回のこのコーナーで紹介したパイプラインと似ているが、パイプラインは出力結果を受け渡す別のコマンドを指定するのに対して、リダイレクトでは出力先にファイルを指定する点が異なる。

sortコマンドで処理できるデータとは?

 では、今回のケースのように行頭に並べ替えのキーがあれば、何でもsortコマンドで処理すればいいのかというと、そうでもない。sortコマンドで処理できるデータは、かなり限定されているからだ。細かく説明し始めると長くなるので大胆かつシンプルにいうと、次の2つの条件を満たしている必要がある。

  • 並べ替えのキー(基準)となる文字列が、各行とも行頭から数えて同じ位置にある
  • 桁数がそろっている

 簡単に説明しておこう。並べ替えのキーは必ずしも行頭にある必要はないが、どの行についても、行頭から数えて同じ文字数の位置に比較対象となるキーが配置されていなければならない。

キーの先頭位置は行頭から数えて同じ文字数の場所になければならない
キーの先頭位置は行頭から数えて同じ文字数の場所になければならない
並べ替えのキーは、行頭から同じ文字数の位置にそろっている必要がある。そのため固定長のフィールドを持つデータに向いている。

 ちなみにsortコマンドは、何も指定しないと行頭から1文字ずつ比較をして並べ替えを行う。一方、「/+<文字数>」オプションを指定すると、<文字数>で指定した桁からの文字をキーとして並べ替えを行う。上記のデータで部署名は5文字目から始まるので、部署名で並べ替えたければ次のように指定する。

sort /+5 menmbers_rnd.txt[Enter]


先頭から5文字目をキーとして並べ替えるコマンド

 なお、sortコマンドは並べ替えのキーを文字コード(文字をPC内部で処理するための番号)の大小で判断している。「0」から「9」や「A」から「Z」は文字コードの小さい順に並んでいるため、数字での並べ替えやアルファベットでの並べ替えは一般的なイメージ通りに行われるが、部署名は漢字なので、漢字の文字コード順に並べ替えられる点は注意が必要だ。

 また、並べ替えのキーに「8」と「99」と「100」という記述があったとしても、この三者の意味(複数の文字が集まってある数値を示しているということ)を認識するわけではないため、「100」「8」「99」というように先頭の数字の順に並んでしまう。このような場合、「半角スペース」や「0」で桁数を右詰めに、「008」「099」「100」といったようにそろえていないと正しく比較されない。

sortコマンドでの数値の比較(数値が左詰めの場合)
sortコマンドでの数値の比較(数値が左詰めの場合)
複数の数字をまとめて数値として扱う訳ではなく、1文字ずつ文字コード比較していくため、左詰めの場合、数値の大きさとは異なる並び順になってしまう。

sortコマンドでの数値の比較(桁をそろえて右詰めの場合)
sortコマンドでの数値の比較(桁をそろえて右詰めの場合)
数値は「半角スペース」や「0」で桁数をそろえて、右詰めになっていると、数値の大きさの順に並べ替えが行える。

 今回の例では、スコアのフィールドは空白で桁数がそろえられているが、左にある氏名のフィールドが可変長であるため、スコアをキーにした並べ替えは正しく行うことができない。

 こうした制限があるため「あらゆるデータの並べ替えをsortコマンドで……」というわけにはいかないが、条件に合致したデータならば、わざわざExcelを起動して処理するよりも早く処理を済ませることができる。

特定部署のメンバーを抽出する

 さて、さっさと済ませて上司に提出したら、返ってきた言葉が「あれ、全部並べちゃった? 営業部のメンバーのリストだけが欲しかったんだけど。言わなかったっけ?」。言ってない、絶対。しかし、ここで水掛け論をしても仕方がない。

 Excelならば、フィルターを使って必要な部署を選んでおいて、社員番号を昇順に指定して並べ替え、別名でファイルに保存するだろう。

 コマンドラインからなら、findコマンドで必要な部署のメンバーのデータを抽出すればいい。findコマンドは、指定した入力データから、指定検索語を含む行を全て抜き出して表示するというもの。書式は次の通りだ。

find "<検索語>" <ファイル名>[Enter]


検索単語を含む行を抜き出すfindコマンド

 <ファイル名>は、ファイルからデータを読み込む場合に指定する。パイプラインから入力データを受け取る場合は、ファイル名を記述する必要はない。その他のコマンドオプションについては、「/?」オプションを指定して実行するとオプションの説明が表示されるのでそちらを参照してほしい。

 話を元に戻そう。新たなミッションは、社員番号順に並べ替えたデータから「営業部」という文字列を含む行を抜き出せばいい。すでに並べ替えたデータがあるので次のようなコマンドを実行すれば良い。ただし、findコマンドにファイル名を指定してデータを読み込む場合は、出力にファイル名が挿入されるので、不要なら後から削除する必要がある。

find "営業部" members_num.txt > members_num_sales.txt[Enter]


CSVファイルから「営業部」を含む行を抜き出すコマンド

 もし、最初から分かっていれば、前回紹介したパイプライン処理を使って次のようなコマンドライン1行で処理することができたはずだ。

sort members_rnd.txt | find "営業部" > members_num_sales.txt[Enter]


並べ替えたデータから「営業部」を含む行を抜き出すコマンド

並べ替えたデータから特定の条件のものを抽出する
並べ替えたデータから特定の条件のものを抽出する
パイプライン処理ならばfindコマンドがファイル名を挿入することもないので、純粋にデータだけがファイルに保存される。

 コマンドのオプションや組み合わせを工夫すると、もっと複雑な並べ替えや行の抽出なども行える。だが、そこに時間をかけ始めると、Excelを使った方が早いという事態になりかねない。それよりも、普段からデータの構造に目を向け「これならsortの方が早い」と判断できるようにしておくことが大切だ。

今回紹介したコマンド

sort、find、>(リダイレクト)


Copyright© Digital Advantage Corp. All Rights Reserved.

ページトップに戻る