質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

Q&A

解決済

2回答

838閲覧

unixの操作 数字の集計

退会済みユーザー

退会済みユーザー

総合スコア0

UNIX

UNIXとは、AT&Tのベル研究所で開発されたコンピューター用のマルチユーザー・マルチタスクのオペレーションシステム(OS)です。政府や教育機関や研究所で広範囲に採用されています。

0グッド

0クリップ

投稿2017/07/28 05:56

いつもお世話になっております。

A.txt

728
435
202
762
673
351
621
723
551
250
421
2080
232



(数十万行続く)

このようなファイルについて、

200未満の数字がx個
200〜300の数字がy個
300〜400の数字がz個



3000以上の数字がn個

というような特定の数字の範囲に分けて集計する方法を御教授頂けますでしょうか。
unixのコマンドではなく、perl等のスクリプトによるものでも嬉しいです。
どうか宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

perl

1#!/usr/bin/perl 2 3use strict; 4 5my %x; 6while(<>){ 7 my $c=($_ < 200) ? 0 8 :($_ >= 3000) ? 3000 9 :int($_ / 100) * 100; 10 $x{$c}++; 11} 12 13foreach my $k (sort {$a<=>$b} keys %x){ 14 print "$k $x{$k}\n"; 15}

投稿2017/07/28 07:10

KojiDoi

総合スコア13669

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/07/28 09:47

perlでの御回答、大変嬉しいです。 勉強不足で申し訳御座いませんが、while(<>) { の箇所をwhile(<A.txt>) { と修正し、A.txtがあるダイレクトリにて実行したのですが、 0 1 とだけ返ってくるだけでした。スクリプトに修正を加えず実行した際は当然全く動きませんでした。私の操作に間違いがあれば、加えて御指摘頂けたら幸いです。
KojiDoi

2017/07/28 10:05

> while(<A.txt>) { と修正し もちろんそれでは動きません。 過去のやりとりからopenとwhileの組み合わせ方は当然ご存知だと思っていましたが。 スクリプト中で入力ファイルを指定したい場合はopen($fhi, "<", "A.txt");などとして ファイルハンドルを作り while(<$fhi>)で読み取らなくてはなりません。 ここでは標準入力から読み取るように書いているので、 当該スクリプトを例えばtest.plなどとしてファイルにセーブし $ perl test.pl A.txt などとしてください。
退会済みユーザー

退会済みユーザー

2017/07/28 10:50

大変失礼致しました。どの参考資料にもあるような、 open (FH, "< A.txt"); while (<FH>) { とすればうまく行きました。更に申し訳御座いませんが、最初に提示した"A.txt"の中に200未満の数字は1つもありませんでした。この場合、出力された情報の最初の行は200〜300の数字の数、最終行は3000以上の数字の数、といった解釈で宜しいでしょうか。
KojiDoi

2017/07/28 11:07

そうなりますね。ゼロも明示したい場合は、最後のforループにもうひと工夫必要です。
退会済みユーザー

退会済みユーザー

2017/07/29 01:34

御返答有難う御座いました。 今回はゼロを明示する必要はありませんが、するとしたら最後のfor文なんですね。私はwhile文のほうかと思ってました。自分なりに考えて今後の勉強とさせて頂きます。
guest

0

200〜299の数字がy個

300〜399の数字がz個

ということであれば、

Bash

1#!/bin/bash 2while read data 3do let x=data/100 4 let counts[x]++ 5done < A.txt 6for i in ${!counts[*]} 7do echo ${i}00-${i}99 = ${counts[$i]} 8done

投稿2017/07/28 06:24

編集2017/07/28 12:08
otn

総合スコア84421

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/07/28 09:40

御回答誠に有難う御座います。 私が勉強不足で恐縮ですが、こちらのスクリプトをvi(vim)で書いて保存し(ファイル名:A.sh)、A.txtがあるダイレクトリにて $ bash A.sh のコマンドで実行したのですが、全く動きませんでした。私の操作に間違いはありますか。加えて御教授頂けたら幸いです。
otn

2017/07/28 12:04

全く動かないというのはどういう現象でしょうか? エラーメッセージすら出ずに、すぐに、プロンプト( $ ) が出たと言うことですか?
otn

2017/07/28 12:08

すいません。リダイレクトを付けるところを間違えてました。回答を修正しました。
退会済みユーザー

退会済みユーザー

2017/07/29 01:31

御修正誠に有難う御座います。 お陰様で実現できました。このスクリプトでは3000以上の数字についても100間隔毎に出力され、私が実現したかった以上の詳細な情報が得られますね。 私は経験が浅く、bashによるスクリプトを未だ書いたことがないので、いい勉強になりました、有難う御座いました。 余談ですが、パスの違いで他の言語でのシバンは大体「#!/usr/bin/言語名」ですが、bashの場合は「#!/bin/bash」なのですね。注意しなくては・・・
otn

2017/07/29 02:47

パス名は、which コマンドで調べます。/usr/local/bin/~ の事もあります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問