- 締切済み
[awk]2つのファイルを参照して1つのファイルに出力する方法
最近プログラミング(シェル、awk)を始めた者です。 かなり大まかなものは作れるようになったのですが、急遽、大規模なデータ整理を行わないといけなくなってしまったため、皆さんの知恵を貸していただきたく質問いたしましたm(_ _)m 以下に示すような2つのファイルがあります。 (file1) (file2) 1 6 1 1 2 10 11 2 3 2 3 5 7 8 3 5 3 6 2 12 13 4 1 4 9 4 5 19 5 2 5 10 19 1 5 6 4 6 4 8 2 9 file1を上から1行ずつ順に読んでいき、2列目の値と同じものをfile2の1列目から探します。合致したところで、file2の合致した行の2列目以降を行番号を付けて表示するというものです。 (「file1の2列目の値=file2の1列目の値」を探し、file2の合致行の値を出力。) 上記ファイルですと、結果的に 1 4 8 2 9 2 6 2 12 13 3 10 19 1 5 4 1 2 10 11 5 3 5 7 8 6 9 4 5 19 という具合になります。 2つのファイルの行数は同じではなく、また、両ファイルとも1列目が行番号というだけで、他の列の値に規則性はありません。 file2の行数は100万以上の大規模なものになります。 自分が作ったものを掲載できればよかったのですが、あいにく会社のPC内にありまして、持ち出しできないため、掲載できません。 動作環境はLinux(RedHat)になります。 他のプログラミング言語についてはまだ分からないため、awkもしくはシェルでお願いいたします。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- nza49739
- ベストアンサー率46% (29/62)
ごめんなさい、一部間違いがありました。 誤: tail -1 | head -(ここに取り出した番号を入れる) ↓ 正: head -(ここに取り出した番号を入れる) | tail -1 パイプの順序が逆でした。お詫びして訂正します。
- notnot
- ベストアンサー率47% (4900/10358)
file1の行数は少ないということでいいですか? 最初にfile1を配列に読み込んでしまって、file2を読むたびにその配列をチェックします。 BEGIN{n=1 while(getline < "file1"){ A[n]=$1; B[n]=$2; n++;} } {K=$1; $1=""; for(i in B){if(K==B[i]){A[i]=A[i] $0;}} } END{ for(i=1;i<n;i++) print A[i]; } これを script というファイル名で保存して、 awk -f script file2
- nza49739
- ベストアンサー率46% (29/62)
行単位のデータを書き込んでいくだけの処理のようですので、awkをつかわなくてもいけそうですね。 for ループでfile1のデータを順々に取り出して、tail -1 | head -(ここに取り出した番号を入れる)で行が取り出せるので、後はcatコマンドで合成 という方法ですね。
お礼
なるほど そういう方法もあるんですね!! ハードにはそこそこ強いんですけど、ソフトはまったくなので(^-^; 勉強になりますm(_ _)m
- osamuy
- ベストアンサー率42% (1231/2878)
スピードを求めなくて良いなら、 >両ファイルとも1列目が行番号 を利用して、file1の2列目が示す数字の行をfile2から抽出 awkならNR==なんとか、sedなら、なんとかpで出力。 ――というシェルスクリプトでいけそうな。 まあ、file2の行数より大きい値がfile1で指定されてた場合どういう振る舞いをすればよいのかとか仕様が不明確なところがありますが。 スピードを求めるなら、1000万行全部オンメモリに読み込んで、バイナリサーチするか、配列で添え字アクセスするか。
お礼
さっそくありがとうございますm(_ _)m >file2の行数より大きい値がfile1で指定されてた場合どういう振る舞いをすればよいのかとか 説明不足でした… file1の値がfile2の行数より大きくなることはありませんし、スピードも要求されます かなり欲張りな内容ですね… ハードはサーバ(Xeon系がItanium系CPU)なので、処理速度には問題ないと思います ちなみに、自分でも簡単なもの(if構文でループさせる回りくどいもの)を作ったのですが、200万行の処理に2日かかってしまいまして… NRの存在を忘れてました(^-^; 明日にでも試してみようと思います!! ありがとうございますm(_ _)m
- qaz_qwerty_me
- ベストアンサー率19% (214/1115)
> file2の行数は100万以上の大規模なものになります。 SQLiteなどの簡単なデータベースもあるので file2 をデータベースに入れて処理するのが簡単と思いますが・・・ データベース化しないなら file2の1列目をキーにした連想配列を作成するのがベタなコーディングだと思います。
お礼
さっそく回答ありがとうございますm(_ _)m そのようにできればいいのですが、この前にも後にも同じファイルを使った処理があるので、できたらそれらも含めた一つのプログラムとしたかったので…
お礼
詳しくありがとうございますm(_ _)m またも説明不足だったのですが、file1はfile2よりも少ないんですけど、それでも数十万行あります(^-^; 現在の方法だと、「file1を読むたびにfile2を読む」というループになってしまっていたので、長時間必要だったのだと思います さっそく試してみます!! ありがとうございますm(_ _)m