シェルスクリプト総合 その9

このエントリーをはてなブックマークに追加
952945:2008/02/11(月) 18:52:59
tmp]$ dd if=/dev/random bs=1024k count=1 > tmp_r

tmp]$ cat tmp_r | LANG=C wc -l
0
tmp]$ cat tmp_r | perl -e 'while(<>){} print "$.\n"'
1
tmp]$ cat tmp_r | awk 'END{print NR}'
1
tmp]$ cat tmp_r | perl -lne 'END{print$.}'
1


ものすごい影響されてるが…。
953名無しさん@お腹いっぱい。:2008/02/11(月) 18:53:37
以降、>>945 がいつまで自分の無知をさらけだすか見守りたいと思います。
954名無しさん@お腹いっぱい。:2008/02/11(月) 18:55:43
>>952
ワロタwwwwww
>>951は自分の発言すら試してなかったのか?w
それともたまたまうまくいっただけか
955名無しさん@お腹いっぱい。:2008/02/11(月) 19:00:40
>>952 では別の問題が発生してるみたいだね。
/dev/randomじゃなくて /dev/urandomでやるべき。
/dev/randomを ddで吸い出すと、十分なエントロピーがなくて
ほとんどがゼロで埋まってるものと思われ。

それとは別に、wc -lでは、最後の改行がない行を数えないが、
awk 'END{print NR}'では数えるから、行数が1ずれる。

その点は、>>945 が最初指摘していたコントロールコードの問題とは違うので、
勘違いしないように。
956名無しさん@お腹いっぱい。:2008/02/11(月) 19:04:10
>>952
だいたい、1MBも乱数で取ったのに '\n' が1つしかない時点で
その実験自体がおかしいことに気づけww 乱数になってない。
957名無しさん@お腹いっぱい。:2008/02/11(月) 19:06:04
952の人気はすばらしい
958名無しさん@お腹いっぱい。:2008/02/11(月) 19:06:49
乱数なんだから1個でどこがおかしいんだよ。
しかもファイルがおかしいにしても、今回はwcが扱えないことはわかったでしょ。
959名無しさん@お腹いっぱい。:2008/02/11(月) 19:06:53
改行コード(\n) = 1行
ということなら、この場合やはり LANG=C wc -l の計数表示が正しいということになる。
awk 'END{print NR}' では、最後の不完全な行までカウントしてしまう。

そういう意味で、やはり LANG=C wc -l が最適ということになるな。
960名無しさん@お腹いっぱい。:2008/02/11(月) 19:09:54
実験してみた。

$ echo -n a > file
$ LANG=C wc -l < file
0
$ awk 'END{print NR}' < file
1

ということだ。LANG=C wc -l の方が正しいな。
961名無しさん@お腹いっぱい。:2008/02/11(月) 19:10:33
では、>>914は自信満々だったけど正しくなかったのか。
最適とか言ってたのに残念。
962名無しさん@お腹いっぱい。:2008/02/11(月) 19:12:19
>>959
違うだろ
改行がある限り2行
963名無しさん@お腹いっぱい。:2008/02/11(月) 19:13:10
>>961
>>914 は wcを使わないという時点では最適だろ。
で、あとでwcを使わなかった理由が質問者から示されたから、
それならLANG=Cでということで、wcが最適になっただけのこと。
964名無しさん@お腹いっぱい。:2008/02/11(月) 19:13:51
定義問題だな
wcのmanではああなっているから
965名無しさん@お腹いっぱい。:2008/02/11(月) 19:14:30
では、結局新しい情報がでてきてもそれに答えられなかった>>914は最適じゃないでしょ。
次々に新しい解を出すのが>>914の言う最適な解なんだから。
966名無しさん@お腹いっぱい。:2008/02/11(月) 19:15:26
最適最適って言ってるけどさ,最適ってどういうこと?タイプ数が最小なものってこと?
967名無しさん@お腹いっぱい。:2008/02/11(月) 19:15:50
>>914に聞いてくれ。
968名無しさん@お腹いっぱい。:2008/02/11(月) 19:16:20
いいからそろそろ次スレよろ
969名無しさん@お腹いっぱい。:2008/02/11(月) 19:18:13
じゃあ>>970が次スレを立てる
970名無しさん@お腹いっぱい。:2008/02/11(月) 19:19:33
立ててきます
971名無しさん@お腹いっぱい。:2008/02/11(月) 19:25:06
シェルスクリプト総合 その10
http://pc11.2ch.net/test/read.cgi/unix/1202725267/
972名無しさん@お腹いっぱい。:2008/02/11(月) 20:25:21
このスレでダメだという指摘が出来ないものが最適。
973名無しさん@お腹いっぱい。:2008/02/11(月) 21:55:14
なんかいいスレだな。wktk
974名無しさん@お腹いっぱい。:2008/02/11(月) 22:31:36
というか、awkはスレ違い。
シェルならシェルだけでやれ。
975名無しさん@お腹いっぱい。:2008/02/11(月) 22:52:08
シェルだけでやる場合の最適解

n=0; while read dummy; do ((n++)); done < file ; echo $n
976名無しさん@お腹いっぱい。:2008/02/11(月) 23:06:41
>>975
bash依存。失格。
977名無しさん@お腹いっぱい。:2008/02/11(月) 23:33:04
じゃあこれでどう?
シェルだけということで、exprすら使わないようにしたよ

set --; while read dummy; do set "$@" a; done < file ; echo $#
978名無しさん@お腹いっぱい。:2008/02/11(月) 23:46:18
>>977
set -- はシェル実装依存。shift $# の方が確実だな。
979名無しさん@お腹いっぱい。:2008/02/12(火) 00:10:10
/bin/sh
だけでできるようにしてくれや。
980名無しさん@お腹いっぱい。:2008/02/12(火) 01:22:43
祭りに乗り遅れた。。
981名無しさん@お腹いっぱい。:2008/02/12(火) 07:24:15
>>979
>>977 は /bin/shだけでできる。
982名無しさん@お腹いっぱい。:2008/02/12(火) 07:46:07
>>977の動作のしくみがわからない俺わろた
983名無しさん@お腹いっぱい。:2008/02/12(火) 21:26:24
読むたびに位置パラメータ(知らなければコマンドライン引数みたいなものと思え)
にaという文字を追加。
最後に位置パラメータの「個数」(=aを追加した回数=行数)を表示。

984名無しさん@お腹いっぱい。:2008/02/12(火) 21:50:09
>>977
行末に \ がある行があると計数ミスするなぁ
985名無しさん@お腹いっぱい。:2008/02/13(水) 16:33:50
というか、wc (オプションなし)だと確かに LANG=C以外の時エラーが出るが、
wc -l とか wc -c だと、そもそも単語に分ける必要ないから文字コードも見ないし、
LANG=C にする必要ないぞ。
wc -l オプション付けてるのに LANG=C が必要なのって、どこの wcコマンド?
986名無しさん@お腹いっぱい。:2008/02/14(木) 22:16:07
>>977
それ、1万行とか10万行とかあってもちゃんと動作するんだろうか?
というか、$#の上限ってどこかで決まってるんだろうか?
987名無しさん@お腹いっぱい。:2008/02/14(木) 22:25:48
とりあえず上限調べて、予想するとかソース読むとか
988名無しさん@お腹いっぱい。:2008/02/14(木) 22:32:48
ボーンでは9が上限
989名無しさん@お腹いっぱい。:2008/02/15(金) 02:42:56
${10}
990名無しさん@お腹いっぱい。:2008/02/15(金) 07:27:00
>>989
だからぁ、ボーンでは ${10} は使えないんだよ。
991名無しさん@お腹いっぱい。:2008/02/15(金) 08:19:41
>>989

$ /bin/sh
$ uname -sr
SunOS 5.10
$ echo ${10}
bad substitution


知らないくせに余計な突っ込みするなよw
992名無しさん@お腹いっぱい。:2008/02/15(金) 08:31:15
shiftしても引数を9個以上とれないってこと!?
993名無しさん@お腹いっぱい。:2008/02/15(金) 08:44:59
shiftすれば行けるだろ。${10}は行けないけど。
994名無しさん@お腹いっぱい。:2008/02/15(金) 22:14:21
ash 0.3.8で
while :; do
set -- "${@}" a
echo $#
done
の出力が15000越えるところまでは見た。
これ以上元祖に近いシェルは手元にないので勘弁。

別に$10とかに直接アクセスできる必要はないんだよな。

995名無しさん@お腹いっぱい。:2008/02/15(金) 22:39:28
たしかに$1から$9をとばして$10だけが必要になる場面が想像できない
俺は極端には$1とshiftだけでもやっていけるな
996名無しさん@お腹いっぱい。:2008/02/15(金) 23:04:11
位置パラメータをコマンド引数として解釈する場合は ${10}とか要らないが、
set を配列代わりに使う用法では、${10}以上の要素に直接アクセスできないとな。
でも、結局Bourneでは使えない方法だから用途は限られる。
997名無しさん@お腹いっぱい。:2008/02/15(金) 23:15:51
今回は数を数えるためだけに使ってるからいいよね。
998名無しさん@お腹いっぱい。:2008/02/16(土) 01:42:35
行カウントコードの別案出してみる:

 $ (IFS='
 > '; IFS= set -- `cat foo`; echo $#)

どんな状況でも機能するのかはちょっとあれだが・・・
999名無しさん@お腹いっぱい。:2008/02/16(土) 06:58:04
h
1000小倉優子 ◆YUKOH0W58Q :2008/02/16(土) 06:58:38
1000ならジュースでも飲むか
10011001
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。