トップページunix
1001コメント327KB

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

レス数が1000を超えています。これ以上書き込みはできません。
0001名無しさん@お腹いっぱい。2007/08/15(水) 07:25:02
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。


□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashなので特に注意。
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
 manや参考リンクを見ましょう。
 aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。

前スレ
シェルスクリプト総合 その8
http://pc11.2ch.net/test/read.cgi/unix/1171517324/
0951名無しさん@お腹いっぱい。2008/02/11(月) 18:52:24
>>948
コントロールコードって、全部で32個(DELも入れると33個か?)だけって知ってる?
09529452008/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


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

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

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

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

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

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

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

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


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

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

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

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

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