MIRACLE
メールサービス申込 ユーザー登録&ログイン パートナー情報
お問い合わせ FAQ サイトマップ
MIRACLE LINUXの特長 製品紹介 サービス案内 購入 サポート 技術フォーラム

プロフィール

日本発のリナックス企業、ミラクル・リナックスで奮闘する社員のブログです。

ミラクル関連リンク

採用情報

サイト検索

最近のトラックバック

2010年2月

  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28            

« 中国、下の事情 | メイン | JIS X 0213 の第三・第四水準漢字(3) »

「いざ、鎌倉」もとい「いざ、Ctrl+Z」

こんにちは。お正月からやっているドラクエ8をまだクリアできないkyagiです。・・・どうやったらレティシアに行けるのかわからないままレベル42です。(T_T)

今回は番外編としてシェルスクリプトの話を書きます。

先日のお昼下がりのこと。いつものようにEmacsのtetrisモード(M-x tetris)に熱中していたところ、業務を一生懸命に遂行していたところ、なにやら背後に怪しい人影が2つ 。カムイ伝だとここで「後をとったぞ、カムイ!」と対決シーンになるところですが、ここは「あの青くてちっちゃい星」のRL(Real Life)のお話。後ろにいたのは笑顔がステキでやさしくてかっこよくて、えーとえーと・・・その他いろいろですが理想の上司であるyoishiさんとrkさんの2人。「ちょっとスクリプトを書いてほしいんだけど・・・」とセミナールームに拉致されました。(T_T)

セミナールームでは「以下の3つのファイルを元にして、Asianux/distA/distBのパッケージ比較の表を作成せよ、30分以内でね!」というお題を頂戴しました。なんでも、パッケージ選定会議で使用したいのだ、ということでした。

3つのファイルとはそれぞれ、Asianux_pkg_list.txt/dist_A_list.txt/dist_B_list.txt で
内容は以下のようにそれぞれのディストリビューションに含まれているパッケージ名の一覧になっていました。

Asianux_pkg_list.txt/dist_A_list.txt/dist_B_list.txtの内容

a2ps
acl
acpid
adaptx
adjtimex
agg
aide
alacarte
(...以下、省略...)

ここから以下のような出力の表が欲しいとのこと。

Asianux  | distA   | distB
packageA | include | not-include
packageB | include | include
packageC | include | not-include
(...以下、省略...)

まずワンライナでロジックを組み立ててみます。比較のベースとなるAsianux_pkg_list.txt から1行読み込んでdist_A_list.txtとの比較を実行して出力を変化させるフィルタを作成してみました。

 cat Asianux_pkg_list.txt | while read line ; do echo -n "$line ,"; grep -q "^$line$" dist_A_list.txt;                if [ $? == 0 ]; then echo -n "include, "; else echo -n "no, "; fi; done

これで判定のロジックはできたので後は dist_B_list.txt ぶんのコードを追加してやればよいだけになりました。最終的には history | tail > filt.sh したものにcsv形式の出力にする修正を加え以下のようなスクリプトになりました。

#!/bin/sh

cat Asianux_pkg_list.txt |
while read line ; do

  echo -n "$line ,";
  # Asianux <-> distA
  grep -q "^$line$" dist_A_list.txt;
  if [ $? == 0 ]; then
    echo -n "include, ";
  else
    echo -n "not-include, ";
  fi

  # Asianux <-> distB
  grep -q "^$line$"  dist_B_list.txt
  if [ $? == 0 ]; then
    echo "include";
  else
    echo "not-include";
  fi
done | column -t

これで一件落着です。今回実感したことは「やはり Ctrl-z は押しにくい」「シェルでもフィルタは結構書ける」ということです。自席に戻って早速キー割り当てを変更したのはいうまでもありません。B-)

追記:

ruby でスクリプトを書き直してみました。機能を少し拡張し、3つのファイルのみならずN個のファイルの比較が可能です。使いかたは以下の通りです。

./Distribtuion2.rb org.txt compare1.txt compare2.txt .... compareN.txt
#!/usr/bin/env ruby

class Distribution
  attr_accessor:pkglist

  def initialize(file)
    @pkglist = Array.new()
    File.open(file) do |f|
      f.each do |line|
        @pkglist.push(line.chomp)
      end
    end
  end

  def is_include?(pkg)
    if (@pkglist.include?(pkg))
      "include"
    else
      "not-include"
    end
  end

end

instances = Array.new()
ARGV.each do |ins|
  instances.push(Distribution.new(ins))
end

instances[0].pkglist.each do |pkg|
  printf("%s ", pkg)
  (1 .. (instances.length - 1)).each do |idx|
    printf("%s ", instances[idx].is_include?(pkg))
  end
  print "\n"
end

トラックバック

このページのトラックバックURL:
http://www.typepad.jp/t/trackback/4447/6750688

このページへのトラックバック一覧 「いざ、鎌倉」もとい「いざ、Ctrl+Z」:

» Rubyで習作 トラックバック ユメのチカラ
最近会社でRubyの勉強会をしていて手習でRubyのスクリプトを書いたりする。h [続きを読む]

» [IT][勉強][Ruby] 3つのテキストファイルを比較するサンプル (Ruby素人編) トラックバック bonlife
VMWare Serverを会社のノートPCにインストールして、CentOS使ってあれこれ実験しようとしたところ、yumが妙なエラーで止まってしまい苦戦しているbonlifeです。FAQの5番目にある”[Errno -1] Header is not complete.”ってヤツですよ…。ということで、挫折感に打ちひしがれ... [続きを読む]

コメント

comm コマンド使っても楽にできますよ。

junさん、コメントありがとうございます。ひとつずつcommコマンドを使っていくのが一番手っとり早いかったかもしれませんね・・・(汗)。

comm asianux.txt distA.txt
comm asianux.txt distB.txt

でも!引数にいくつ指定してもだいじょうVなように拡張してみましたよ〜!えへへ(<仕事しろ、自分)

ドラクエネタに・・・
レティシアへの行き方って「ひかりの海図」を使うではなかったかな??
違う場所のことだったら・・申し訳ない。

take0513さん、お久しぶりです。情報ありがとうございます。その後、無事いけました。海賊みたいなやつ(キャプテンなんたら)に辿りつくのが一苦労でした。

いやいや、無事に行けて何より。
こっちは今はDQMJをやってますよ。
8の時のモンスターなど多数出てくるので懐かしい。
キャプテンクロウもね。

コメントを投稿

会社情報 採用情報 個人情報保護方針 商標等取り扱い事項 English
Copyright(c)2000-2006 MIRACLE LINUX CORPORATION. All Rights Reserved.