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

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

レス数が900を超えています。1000を超えると表示できなくなるよ。
0001名無しさん@お腹いっぱい。2006/01/21(土) 09:00:29
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。


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

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
0825名無しさん@お腹いっぱい。2006/03/20(月) 14:43:21
ほげ
0826名無しさん@お腹いっぱい。2006/03/20(月) 16:27:41
ぴよ
0827名無しさん@お腹いっぱい。2006/03/20(月) 16:36:01
>>824
アンカー先間違えてる?
818にそう言っても話が繋がらないのだが・・
0828名無しさん@お腹いっぱい。2006/03/20(月) 16:51:18
つながらなくて困るようなスレの流れじゃないし。
0829名無しさん@お腹いっぱい。2006/03/20(月) 21:22:48
質問です。

カレントディレクトリ以下(サブディレクトリ含)にある.c,.cc,.cppのファイル数を知りたいのですが、どうしたらよいのでしょうか。
find ./* -name *.c | wc -l
をそれぞれの拡張子で、では無く、一発で3種類のファイル数を求める方法を知りたいです。

後、
./script < inputfile
と入力した時、inputfileの中身をscript内で使うにはどうしたらよいでしょうか。
./script 1 2
とやると$1に1、というようになりますが、ファイルに
1
2
とあり、そのファイルを入力として渡す時はどのようにして1や2を得るのでしょうか。
0830名無しさん@お腹いっぱい。2006/03/20(月) 21:40:01
>>829
Q1 何故、findの機能を調べようとしないんだ?
Q2 何故、そのスクリプトエンジンの機能を調べようとしないんだ?
0831名無しさん@お腹いっぱい。2006/03/20(月) 22:28:06
またman読めよらしいな
0832名無しさん@お腹いっぱい。2006/03/20(月) 22:33:50
>>830,831
そういうお答えはご遠慮願います。
ちゃんとわかる方のみ、ご回答よろしくお願いします。
0833名無しさん@お腹いっぱい。2006/03/20(月) 22:38:06
>>829
一問目は、man shかman bashして、
パス名展開(Pathname Expantion) のところ読んでね。
0834名無しさん@お腹いっぱい。2006/03/20(月) 22:44:35
>>833
>>829 の1問目は、「一発で3種類のファイル数を(それぞれ)求める方法」
らしいから、それは shの「パス名展開」を読んでも解決にならないだろ。
0835名無しさん@お腹いっぱい。2006/03/20(月) 22:47:22
また「知ったかman厨」か。
0836名無しさん@お腹いっぱい。2006/03/20(月) 22:48:35
>>832
死ねよ。クズ。
08378292006/03/20(月) 22:49:10
>>830
忠告ありがとうございます。

findの方は -o -name の追加でなんとかなりました。
ファイル入力の方、ファイル名がスクリプト内で取得可能ならexecでどうこう出来る、
というのを見つけたのですが、肝心のファイル名をどうやって知ればいいのかわからんです。
なんか検索ヒント下さい。
0838名無しさん@お腹いっぱい。2006/03/20(月) 22:52:35
>>834
「それぞれ」で無くてもよかったのだけど、その場合一発で出来るんですかね。
0839名無しさん@お腹いっぱい。2006/03/20(月) 22:54:22
>>829
1問目:

「一発で」というならfindやシェルスクリプトでは無理。
3回もfindしたくないということなら、
近い方法として、
find . -name '*.c' -o -name '*.cpp' -or -name '*.cc'
の結果をシェル変数またはテンポラリファイルに一旦取り込み、
その内容を

grep '\.c$' | wc -l
grep '\.cc$' | wc -l
grep '\.cpp$' | wc -l
すればよい。


2問目:
./scriptの中で readコマンドで標準入力の内容が1行ずつ読み込める。
普通、while readみたいにして使う。
0840名無しさん@お腹いっぱい。2006/03/20(月) 22:57:06
>>838
「それぞれ」でなくていいなら、
find . -name '*.c' -o -name '*.cpp' -or -name '*.cc' | wc -l
で一発。
0841名無しさん@お腹いっぱい。2006/03/20(月) 22:59:19
このスレ的にはawkは邪道?
0842名無しさん@お腹いっぱい。2006/03/20(月) 23:02:07
スクリプト言語だからなあ。でも実際、シェルスクリプトの一部として
使われてるって現実もあるし。微妙な所か。
08438292006/03/20(月) 23:12:56
みなさんどうもありがと。

>>839
while read var
して$varを全部echoしてみたのですが、最初の値が0になっている。こういうものなの?
一つ目を無視すれば済むのだろうけど。
0844名無しさん@お腹いっぱい。2006/03/20(月) 23:18:14
>>843
おそらく、whileループの「外」でechoしてるんだろう、とエスパーしてみる。
while readする場合にはちょっと癖があって、
while文の部分がサブシェルで実行されるので、
varに値を入れても、
whileループを抜けると消えてしまう(←ちょっと不正確な表現)んだよ。
うまく工夫してそれを避けるしかない。
0845名無しさん@お腹いっぱい。2006/03/20(月) 23:19:32
じゃ、こんなのは?

find . \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' \) -exec basename {} \; | \
( c=0 ; cc=0 ; cpp=0 ; while read i; do case $i in *.c ) c=`expr $c + 1`;; *.cc) cc=`expr $cc + 1`;; *.cpp) cpp=`expr $cpp + 1`;; esac; done; printf '*.c = %d\n*.cc = %d\n*.cpp = %d\n' $c $cc $cpp )

長すぎたので途中で折り返してる。
てか1行で書く必要は無いのか?
0846名無しさん@お腹いっぱい。2006/03/20(月) 23:20:04
>>843
この場合は while readを使わずに、
set `cat`
で読み込め。
これで、引数で起動したのと同じように
そのまま $1 $2 ... に代入されるよ。
08478452006/03/20(月) 23:20:14
名前消えたけど845=841です。
08488292006/03/21(火) 00:06:34
>>844
なんかよく分からないけど0が消えました。
さっき全く同じコードの筈なんだけどな。
入力ファイルの頭が0だった、なんて事は無いです。
while read var
do
echo $var
done
で0無しで動きました。不安なので再現狙ってみます。

>>845
長いからスクリプト書いた方が とか
でも一行で書けるものなんだと驚いたのも確か

>>846
うまいこと行きました。便利ですねこれ。さんくすです。


みなさんありがとうございました 
0849名無しさん@お腹いっぱい。2006/03/21(火) 00:10:20
>>829
ちょっと作ってみた

--
find . -type f | egrep '\.(c|cc|cpp)$' | \
  rev | cut -d. -f1 | rev | sort | uniq -c | sort -nr
--

egrepの部分に集計したい拡張子追加してね。
0850名無しさん@お腹いっぱい。2006/03/21(火) 00:37:22
>>849
rev | cut -d. -f1 | rev
の部分、面白いと思うけど、
プロセス3つも使うの無駄っぽいから、俺なら、

sed 's/.*\.\(.*\)$/\1/'
にするかな。
0851名無しさん@お腹いっぱい。2006/03/21(火) 00:49:35
>>850
それならもっと簡単に書ける。
sed 's/.*\.//'
0852名無しさん@お腹いっぱい。2006/03/21(火) 00:55:46
なるほどー。「man嫁」じゃなくて、ちゃんと具体例で解答すると
アイデアが膨らんで、スレのレベルが上がるねぇー。
0853名無しさん@お腹いっぱい。2006/03/21(火) 01:07:00
質問者のフォローが良かったんだな
訊き捨ての香具師にはman嫁でじゅーぶん
0854名無しさん@お腹いっぱい。2006/03/21(火) 01:41:26
スレのレベルが上がる…プッwwww
0855名無しさん@お腹いっぱい。2006/03/21(火) 01:45:48
>>849
egrep のところは find -regex を使った方がお手軽だと思う。

>>850-851 のアイディアも加えるとこんな感じ?

find . -type f -regex '.*\.\(c\|cc\|cpp\)' | sed 's/.*\.//' | sort | uniq -c | sort -nr
0856名無しさん@お腹いっぱい。2006/03/21(火) 02:41:54
-regex って、OS 依存だから、ポータブルなシェルスクリプトに
したいんだったら、egrep 使った方がいいよ。
OS 依存でいいなら構わんが。
0857名無しさん@お腹いっぱい。2006/03/21(火) 02:53:14
>>856
egrepってOS非依存か?
0858名無しさん@お腹いっぱい。2006/03/21(火) 03:35:45
もちろん非依存だよ。まあ当然 UNIX 系 OS に限るけどね。
0859名無しさん@お腹いっぱい。2006/03/21(火) 03:47:17
>>856
-regex って GNU 拡張だったんだ。
憶えておくよ。

egrep と grep -E ってどっちがポータブルなの?
0860名無しさん@お腹いっぱい。2006/03/21(火) 03:50:09
-regex は 4.4BSD 系 find にもあるから、GNU 拡張というよりは
もう少しポータブルだけどね。4.4BSD 系 OS のマニュアルには、
拡張機能だと明記してあるんだが。

egrep と grep -E では、egrep の方がポータブル。
0861名無しさん@お腹いっぱい。2006/03/21(火) 07:38:29
相変わらずラベル低いなw
0862名無しさん@お腹いっぱい。2006/03/21(火) 09:39:23
>>855,856
findの -regexがダメというなら、パイプで egrepするよりは、
find自身で -name '*.c' -o -name '*.cc' -o -name '*.cpp'
でいいと思う。ちゃんと書き直すと、

find . -type f \( -name '*.c' -o -name '*.cc' -o -name '*.cpp' \) \
| sed 's/.*\.//' | sort | uniq -c | sort -nr
かな。

findの -type fを省略していいなら、その後の \( \) も省略できる。
0863名無しさん@お腹いっぱい。2006/03/21(火) 11:19:30
ここの馬鹿どもはPOSIXとか知らんのか?
0864名無しさん@お腹いっぱい。2006/03/21(火) 11:25:04
>>863
よし、存分に語れ。
0865名無しさん@お腹いっぱい。2006/03/21(火) 11:29:26
>>863
それはそれは…是非ご教授願いたい。
0866名無しさん@お腹いっぱい。2006/03/21(火) 11:40:07
>>863
POSIX!何ですかそれは!是非ご啓示ください!!
0867名無しさん@お腹いっぱい。2006/03/21(火) 11:46:58
POSIXを読むのは有料だし、
実際の各種OSで使われているシェルやコマンドは、
POSIXと同じではない。
だから、そもそもPOSIXと同じではない各種OS間のポータビリティを
考えるなら、POSIX云々ではなく、実際に各種OSでの状況を調べて
対応するのが実践的で現実的。
0868名無しさん@お腹いっぱい。2006/03/21(火) 13:34:46
opengroup.org キタ━━━━━━(゚∀゚)━━━━━━ !!!!!
0869名無しさん@お腹いっぱい。2006/03/21(火) 14:09:32
> POSIXを読むのは有料だし、

登録は必要だけど、無料だよ。
ttp://www.unix.org/version3/online.html
0870名無しさん@お腹いっぱい。2006/03/21(火) 14:38:19
>>867
POSIX新聞?うちは取らないよ。
0871名無しさん@お腹いっぱい。2006/03/21(火) 15:47:04
>□お約束
>・特記なき場合はbourne shがデフォルトです。

今どき、bourne shをデフォルトにしているのなんて、
Solarisくらいしかないじゃん。
0872名無しさん@お腹いっぱい。2006/03/21(火) 15:54:56
>>871 Linux板に帰れ
0873名無しさん@お腹いっぱい。2006/03/21(火) 16:04:46
いや、ゴミが帰ってきても困るんだが。
0874名無しさん@お腹いっぱい。2006/03/21(火) 16:08:57
>>860
> egrep と grep -E では、egrep の方がポータブル。

嘘おっしゃい。
0875名無しさん@お腹いっぱい。2006/03/21(火) 16:09:18
du -a と find . -type f だと、やっぱり find の方が速い?
0876名無しさん@お腹いっぱい。2006/03/21(火) 16:30:18
スクリプトでは難しいけど、カレントディレクトリにあるディレクトリ数分のthreadを作ってパラレルにfind
するようなプログラム作るとめっさ速そうなんだけど。無理?
0877名無しさん@お腹いっぱい。2006/03/21(火) 16:41:16
> 嘘おっしゃい。

Linux とか POSIX の仕様しか知らない最近の人だと、そう思うかも
しれないね。SUSv3 を見ると egrep は載ってなくて grep -E だけ
が書いてあるし。

でも、もともと egrep と grep は別のコマンドで、使っているアル
ゴリズムも egrep は DFA、grep は NFA で異なっていた。10年くらい
前だと、grep に -E オプションがない OS も沢山あったよ。
これに対し、egrep はベル研 UNIX 時代から存在する由緒あるコマンド
で、事実上すべての UNIX に存在するはず。

ttp://www.bookshelf.jp/texi/autoconf-ja/autoconf-ja_10.html
> POSIX 1003.1-2001では,もはやegrepを要求していませんが,より古いホスト
> の多くはまだPOSIXのgrep -Eでの置換をサポートしていません.この問題を回
> 避するため,AC_PROG_EGREP を呼び出し,$EGREPを使用してください
0878名無しさん@お腹いっぱい。2006/03/21(火) 16:48:05
>>877
Solarisだと/usr/xpg4/bin/grepにしか-Eオプションは無くて/usr/bin/grepでは-Eは使えない。
他のOSでも使えるようにgrep -Eをスクリプトに書くのはちょいめんどくさいな。
0879名無しさん@お腹いっぱい。2006/03/21(火) 16:54:26
>>867
まずはPOSIXを読めな? ごたくはそれからだ。
0880名無しさん@お腹いっぱい。2006/03/21(火) 17:01:07
>>876
pthread使ったファイル検索プログラムがButenhofのpthread本に
載ってたような。
0881名無しさん@お腹いっぱい。2006/03/21(火) 18:53:18
POSIXの仕様に合わせると、現実の仕様に合わない罠。
>>877 見ても、POSIXよりも autoconfの方がよほど現実的というところか。
0882名無しさん@お腹いっぱい。2006/03/21(火) 21:15:57





              相変わらず

0883名無しさん@お腹いっぱい。2006/03/21(火) 21:27:27
>>882



        鬱ですねぇ。
08848822006/03/21(火) 22:48:52
>>883
鬱で引きこもりですけど何か?
僕のクラッキング武勇伝でも聞くかい?
0885名無しさん@お腹いっぱい。2006/03/22(水) 02:14:10
スクリプトキディってやつか。語ってみる?
0886名無しさん@お腹いっぱい。2006/03/22(水) 09:40:58
よ、よし、俺のハッキングデビューはWinNuke。
その後は究極のProxy★ガブリエナイで優雅にproxy生活だったさ!!
0887名無しさん@お腹いっぱい。2006/03/22(水) 18:01:04
読み方 : スクリプトキディ
分野 : セキュリティ > ネットワーク


 インターネット上で公開されている操作が簡単なクラックツールを利用して、興味
本位の不正アクセスを試みる「幼稚な」クラッカー。
クラックツールは既に広く知られているセキュリティホールを悪用するように作成されているため、
セキュリティパッチを確実に適用することで、ほとんどのスクリプトキディによる攻撃は防止できる。
クラックツールを使えば深い知識や高度な技術がなくても簡単に攻撃を行なうことができるため、
数の上ではクラッカーのほとんどはスクリプトキディであると言われる。
0888名無しさん@お腹いっぱい。2006/03/23(木) 15:38:21
一番汎用性があるシェルスクリプトは Bourne Shell で書かれたもの
という理解でよろしいでしょうか?
0889名無しさん@お腹いっぱい。2006/03/23(木) 15:39:59
>>884 何気聞きたい
0890名無しさん@お腹いっぱい。2006/03/24(金) 02:30:15
>>888
いえ Korn Shell です。
0891名無しさん@お腹いっぱい。2006/03/24(金) 07:37:06
Debianだと checkbashisms なんてコマンドがあったりするな。
まあそんなに汎用性気にするならPerl使えという気もするが。
08927742006/03/24(金) 07:55:17
【日韓・野球】「ホームラン記録等には八百長疑惑もある王貞治(ワン・ジョンチ)、監督として成功」…韓国紙 ★4 [03/21]
http://news18.2ch.net/test/read.cgi/news4plus/1143149170/
0893名無しさん@お腹いっぱい。2006/03/24(金) 08:08:44
>>888
一番移植性が高いのはBourne Shellということで合ってる。
当たり前過ぎて誰も答えなかっただけ。

>>890
初心者が本気にするかも知れないから、そういう嘘書くのやめろ。
0894名無しさん@お腹いっぱい。2006/03/24(金) 09:31:20
>>893
では移植性の高さを定量的に比較し提示してください。
0895名無しさん@お腹いっぱい。2006/03/24(金) 09:42:42
>>894
誰もが常識として知っていることをあなたに説明して教える筋合いはない。
知りたければ自分で知ろうとする努力をしなさい。
0896名無しさん@お腹いっぱい。2006/03/24(金) 09:45:05
>>895
つまり根拠なき妄言てことですな。自白乙。
0897名無しさん@お腹いっぱい。2006/03/24(金) 09:48:12
>>896
大丈夫。みんな妄想してるから。
0898名無しさん@お腹いっぱい。2006/03/24(金) 10:42:36
まあ、釣りだろうけど、
「kshが移植性が一番高い」などとマジで言ってるなら重症だぞ。
ヨソでそんなこと言って恥かくなよ。
0899名無しさん@お腹いっぱい。2006/03/24(金) 10:50:45
罵り合いで盛り上がっているところ申し訳無いが、
汎用性と移植性は違う気がする。

汎用性は用途の広さだよね。
それならどのシェルもほとんど変わらない気がする。
0900名無しさん@お腹いっぱい。2006/03/24(金) 10:53:40
>>894
$ ssh freebsd-host
freebsd$ ksh
ksh: not found
freebsd$ exit
$ ssh linux-host
linux$ ksh
ksh: not found
linux$ exit

....noway, what more can I say ?
0901名無しさん@お腹いっぱい。2006/03/24(金) 11:18:12
おぃおぃ
お前のマシンに当該シェルがあるかどうかなんて聞いちゃいねー
0902名無しさん@お腹いっぱい。2006/03/24(金) 11:25:36
>>901
そのとおりだが、漏れもpdkshなんて使わんからアンインストールしてるよ。
0903名無しさん@お腹いっぱい。2006/03/24(金) 11:29:27
>>901
はぁ?
どんなホストでも、誰のホストでも、
デフォで動くというのが「移植性」の必須条件なわけだが。
0904名無しさん@お腹いっぱい。2006/03/24(金) 11:31:39
んなこたーない
0905名無しさん@お腹いっぱい。2006/03/24(金) 11:34:37
>>903
そういう標準化の為に色々大人が事情をつくるのよ
どんなUNIX95のホストでもとか
POSIXに準拠したホストでもとか

0906名無しさん@お腹いっぱい。2006/03/24(金) 11:50:29
>>905
だからPOSIXって実際には使えないわけですね。
0907名無しさん@お腹いっぱい。2006/03/24(金) 13:38:49
準拠ってことばを知らないなら辞書でしらべなよ(^_^;)
0908名無しさん@お腹いっぱい。2006/03/24(金) 13:57:13
>>890
たくさん釣れましたね。
確かに、本当にKorn Shellが移植性が高かったら良かったかも知れませんね。
でも現実にはもう遅いですね。
0909名無しさん@お腹いっぱい。2006/03/24(金) 14:24:02
腎虚
0910名無しさん@お腹いっぱい。2006/03/24(金) 21:56:42
言葉遊び乙
0911名無しさん@お腹いっぱい。2006/03/24(金) 22:03:57
打倒米帝
0912名無しさん@お腹いっぱい。2006/03/24(金) 22:21:31
【設問1】
次の各項目を、その可能性が高い順番に並べよ。(10点)

(1) IPv6が普及する
(2) UNIX環境においてUTF8がEUCよりも普及する
(3) kshが最も移植性の高いシェルとして普及する
0913名無しさん@お腹いっぱい。2006/03/24(金) 22:45:38
(2)>>>>>>>>>>>>>>>>(1)>(3)
0914名無しさん@お腹いっぱい。2006/03/24(金) 22:48:19
(4) 俺が童貞を卒業する
0915名無しさん@お腹いっぱい。2006/03/24(金) 22:57:20
>>914
本当にやる気が有ればいつでも捨てれるはずだ
0916名無しさん@お腹いっぱい。2006/03/24(金) 22:58:53
>>912
どれも可能性ほぼゼロ。
よって、どの順に並べても正解。


UTF8は、全角記号の横幅問題が解決しない限り、実際問題使えない。
0917名無しさん@お腹いっぱい。2006/03/24(金) 23:08:27
φ=(2)>>>>>>>>(1)>(3)>>>>>>(4)

でFA?
0918名無しさん@お腹いっぱい。2006/03/24(金) 23:16:50
xterm -cjk_witdh じゃ駄目なの?
0919名無しさん@お腹いっぱい。2006/03/24(金) 23:32:06
そりゃ一番機能が低いのが一番移植性が高いだろ。CPM-80のcommand.comの移植性が一番高いでFA。
0920名無しさん@お腹いっぱい。2006/03/24(金) 23:43:22
それこそがunix philosophyだという話もある
0921名無しさん@お腹いっぱい。2006/03/24(金) 23:55:22
>>919
いい加減なことぬかすな、CP/Mにはcommand.comなど無い。
0922名無しさん@お腹いっぱい。2006/03/25(土) 00:24:05
そういうことなら自動販売機が一番移植性高い。
0923名無しさん@お腹いっぱい。2006/03/25(土) 00:24:49
オナホでもおでんでも売れるものな
0924名無しさん@お腹いっぱい。2006/03/25(土) 00:27:59
今こそS-OS復権
レス数が900を超えています。1000を超えると表示できなくなるよ。