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

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

■ このスレッドは過去ログ倉庫に格納されています
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/
0384名無しさん@お腹いっぱい。2007/10/29(月) 23:01:04
代入方法ならさすがに>>382を脳がウニになるまで読んで欲しいかと・・・
学生は答ではなく原理や方法を考える手間を惜しんじゃいけないでしょ。

ていうかシェルスクリプトを書く中学生とは一体??
(最近は高校生でカーネルメンテナとかいるから普通なのか・・・)
0385名無しさん@お腹いっぱい。2007/10/30(火) 00:40:34
本当に中学生だとしたら、かなりダメすぎ。
今後年食って頭悪くなる一方だから。
0386名無しさん@お腹いっぱい。2007/10/30(火) 01:02:00
寝る前のおまけ。22バイト縮めた:

 $ M=255.255.255.255
 $ echo obase=2.$M|tr . \;|bc|tr -d 0\\n|wc -c

さすがに限界?段々ゴルフになってきたな。
0387名無しさん@お腹いっぱい。2007/10/30(火) 08:51:55
夢で見たので逆バージョンもなんとなくチラ裏してみる:

#!/usr/bin/ruby
n=$*[0].to_i;puts [24,16,8,0].map{|i|~(~0<<n)<<32-n>>i&255}.join(".")
0388名無しさん@お腹いっぱい。2007/10/30(火) 18:12:45
改行コード無視のdiffってできますか?
0389名無しさん@お腹いっぱい。2007/10/30(火) 21:29:26
つ -w とか --strip-trailing-cr ? # 実装によるかも

0390初心者です2007/11/01(木) 02:00:47
正規表現について質問
abcで始まり、数字で終わる文字列を取得したいと思ってます

例)MOJI='abc123onegaisimasu'
この場合「abc123」を取得したい
0391名無しさん@お腹いっぱい。2007/11/01(木) 02:18:07
ほれ。始まる、が行頭の意味なら微妙に要修正。
つ $ echo hogehogeabc123hogehoge | sed -ne 's/.*\(abc[0-9]*\).*/\1/p'
0392初心者です2007/11/01(木) 02:29:58
>>391
ありがとうございます!
0393名無しさん@お腹いっぱい。2007/11/01(木) 08:20:55
exprの方がそのものだと思うけどね
0394名無しさん@お腹いっぱい。2007/11/01(木) 13:18:41
検索と置換、grepとsedで、ともに正規表現の複数行(perlの「mオプション」)対応できますか?
0395名無しさん@お腹いっぱい。2007/11/01(木) 13:56:20
>>394

grepによる検索やsedでの置換で、正規表現を使って
複数行に渉る任意の文字列を対象にすることが出来ますか?

・・・って意味ですか?

日本語は難しいので、詳しく書いてもらえないと分からないです。(perl知らないし)

ちなみに上記の意味ならば、sedである程度対応出来るのは知ってるけど、grepは知らね。
(perl知ってるなら、そっちを使えばいいと思う。awkでも条件満たせるだろうけど、わざわざ使う意味無)
0396名無しさん@お腹いっぱい。2007/11/01(木) 15:33:41
変数を局所化する local は sh ですか? それとも bash ですか?
0397名無しさん@お腹いっぱい。2007/11/01(木) 16:42:55
>>396
テンプレにあるPOSIXのリンクを参照。
0398名無しさん@お腹いっぱい。2007/11/01(木) 17:05:26
>>395
すみません。その通りです。
sedでどのようにしてできるのでしょうか?
03993962007/11/01(木) 19:38:47
>>397
アドバイスありがとです。ざっと読みましたが言及されていないので
bash 拡張のようですね。man bash もしてみましたが・・・
04003952007/11/02(金) 10:26:30
>>398

Nで次行追加読み込みするので。正規表現で\nを使うと複数行中の改行にマッチする。
置換対象文字列に改行を使用するときは、\の後ろで実際に改行する。
:の後ろにラベル名を書く(末尾に空白や区切り文字が有ってはいけない)
bで処理の流れを変える(下の場合最終行意外「$!」は最後に出力する前に先頭に戻る)

$ cat a.txt
aaaa
bbbb
cccc
dddd
$ sed ':loop
N;s/\(^.*\)\n\(.*$\)/\2\
\1/;$!b loop' a.txt
dddd
cccc
bbbb
aaaa
0401名無しさん@お腹いっぱい。2007/11/02(金) 20:37:21
質問です。
resultやrvalをみなさんはなんと読んでいますか?
0402名無しさん@お腹いっぱい。2007/11/02(金) 20:38:09
>>401
UNIXに関する言葉のひらがな読みスレッド
http://pc11.2ch.net/test/read.cgi/unix/1001358861/
0403名無しさん@お腹いっぱい。2007/11/03(土) 16:32:39
長文質問です。スマソ

ファイル名がフルパスで5,000行位書かれている$LISTから、キーになるリスト$KEY_LISTから一行ずつ取り出し
ひとつにマッチした物を$okそれ以外を$ngにカウントして結果を表示するスクリプトを作っています。

LIST="/home/share/list"
[1] aaa/bbb/ccc/ddd/eee/A社ボツ/商品A企画書/hoge.txt
[2] aaa/bbb/ccc/ddd/eee/A社/商品B企画書/hoge.txt
[3] 営業部終了分/iii/jjj/kkk/lll/mmm/nnn/page.txt
[4] 営業部/xxx/jjj/kkk/lll/mmm/nnn/page.txt

KEY_LIST="/home/share/key_list"
[1] aaa/bbb/ccc/ddd/eee/A社/商品A企画書/hoge.txt
[2] 営業部/iii/jjj/kkk/lll/mmm/nnn/page.txt

だだ上記のように親ディレクトリの名前が変更されているのと、違う親ディレクトリ名で同じファイル名が存在するので
単純にgrepするのではうまくいかないのでこんなかんじで作ってみました。
04044032007/11/03(土) 16:33:23
続きです。
for i in `cat $KEY_LIST`
do
key=`echo "$i" | awk -F/ '{print$NF}'` #処理A
much=`grep "/$key$" $LIST | wc -l`
if [ "$much" -eq 1 ] ; then
((ok++))
else
key=`echo "$i" | awk -F/ '{b=NF-1} {print$b"/"$NF}'` #処理B
much=`grep "/$key$" $LIST | wc -l`
if [ "$much" -eq 1 ] ; then
((ok++))
else
((ng++))
fi
fi
done
echo "OK $ok"
echo "NG $ng"

処理Aでは、$KEY_LIST[1]行目の「hoge.txt」で$LISTをgrep すると$LIST[1],[2]マッチするので else
処理Bでは、$KEY_LIST[1]行目の「商品A企画書/hoge.txt」でgrepすると$LIST[1]のみにマッチするので、okになります。

しかし、$KEY_LIST[2]と$LIST[3]は同じファイルなのですが、$LIST[4]ともマッチしてしまいngになります。

さらに処理C〜処理Gを追加すればokになるのですが、実際のリストは20階層くらいあり
うまくループで作れないものかと思っています。よろしくお願いします。
0405名無しさん@お腹いっぱい。2007/11/03(土) 19:29:48
>>403
こんなので使えますか?

#!/bin/sh -
LIST="/home/share/list"
KEY_LIST="/home/share/key_list"

awk -F/ '
{
for(i = NF; i >= 1; --i) {
for(j = i; j <= NF; ++j) {
if(j == 1) {
sizeOfArray = split($j,array," ")
result = array[sizeOfArray]
}
else if(j == i) result = $j
else result = result"/"$j
}
count = system ("grep -c " result" ""'$LIST'"" >/dev/null 2>&1")
result = ""
if(count == 1) {
ok++
break
}

}
ng++
}
END {
printf("%04d\n%04d\n", ok, ng)
}
04064052007/11/03(土) 19:32:45
すまん、最後が切れた

' $KEY_LIST
04074052007/11/03(土) 19:47:13
すいません、間違っていた。
忘れてください。
0408名無しさん@お腹いっぱい。2007/11/03(土) 20:19:57
>>403
どうもよくわからん。行いたい処理じゃなくて、目的から説明できる?
同一ファイルの重複検査ならmd5sumとってsort+uniqとか、不可思議な
パス名の切り貼り検索以外の解決策があるのではないかという気がする。
04094052007/11/03(土) 22:10:30
>>408
私は純粋に頭の体操と思ってチャレンジさせてもらってます。

で、>>403 の解釈だけど、
key_list の各行に対して ok または ng の判定をするということでよいですか?
だったら(一行全部マッチする可能性も有るので)一行読む毎に一度ゼロを入れて、
ゼロになる直前のマッチ数が1で有ったら、おkって解釈でいいよね?
で ok と ng の合計が、key_list と一致するという考え方でいいですか?
ならば以下で再挑戦です。

#!/bin/sh -
LIST="/home/share/list"
KEY_LIST="/home/share/key_list"
A="` echo | tr '\012' '\001' `"

COUNT=`awk -F/ '
{
 for(i = NF; i >= 1; --i) {
  for(j = i; j <= NF; ++j) {
   if(j == 1) {
    sizeOfArray = split($j,array," ")
    result = array[sizeOfArray]
   }
   else if(j == i) result = $j
   else result = result"/"$j
  }
   system("grep -c " result" ""'$LIST'")
   result = ""
 }
  system("grep -c ""'$A'"" ""'$LIST'") # 全部が一致する可能性も有るので無理やりゼロになるぐれっぷを実行
} ' $KEY_LIST`
続く。
04104052007/11/03(土) 22:14:14
続き
echo $COUNT | awk 'BEGIN {RS = " "}
{
 if($0 == 0) {
  if(tmp == 1) ok++ # ゼロになる直前の検索ヒットが一つだけならok
   else if(tmp > 1) ng++
}
 tmp = $0
}
END {
 printf("%04d\n%04d\n", ok, ng)
}'
04114032007/11/03(土) 22:52:55
>>405
おお!ありがとうございます。

>>408
すみません、これでは意味が分からないですよね。説明しづらいので>>403は例として書きました。

目的は、rsyncで毎日サーバのバックアップをインターネット越しにとっているのですが、親ディレクトリ
の名前を変えるとそのディレクトリ以下のすべてのファイルを一度消して、再コピーする動作をするために
ディレクトリの容量がでかいと1日でバックアップが終わらなくなってしまいます。

そこで、rsyncの機能(-n)で実際には動作せず結果だけを出力できるので、それを$LISTに書き出します。
削除されたファイルは頭に「deleting」がつくので grep "^deleting" $LIST > $KEY_LIST に書き出します。

>>403とは条件分岐が変わってしまいますが、親ディレクトリの名前が変わったファイルは、頭が「deleting」で
始まる行とそれがつかないコピーを表す行の2つにマッチするので、そのカウント数が多ければ親ディレクトリの
名前が変更されたと判断して、あとは人力で$LISTを確認してバックアップ側のディレクトリ名をサーバ側と同じに
すれば、消去してしまう事をふせぎます。

実際は、毎日crontabでバックアップのスクリプトを走らせているのですが、一定以上カウントされたらバックアップを
やめて、メールで通知する機能をついかしたいなあとおもっています。
04124052007/11/03(土) 23:24:34
>>411

>>>>405
>>おお!ありがとうございます。

そいつは間違いです。
awk の system 関数の戻り値を取り違えているし、
ng++ の位置も根本的におかしいです。

>>409 の解釈が妥当かどうかはともかく、
考え方として、はこっちの方がマシでしょう。
0413名無しさん@お腹いっぱい。2007/11/04(日) 18:24:36
>>403 なんか良く分からんが、おもしろそうなので作った。
#!/bin/sh
for i in `cat $KEY_LIST`
do
key=`basename $i`
while echo ${i} | grep "/" > /dev/nill
do
much=`grep "/$key$" $LIST | wc -l`
if [ "$much" -eq 1 ] ; then
((ok++)); break
else
i=`dirname $i`; x=`basename $i` key=`echo $x"/"$key`
fi
done
if [ "$much" -ne 0 ] ; then
((ng++))
fi
done
echo "OK $ok"
echo "NG $ng"
0414名無しさん@お腹いっぱい。2007/11/04(日) 18:28:39
くわ途中で送信しちまった、whileの条件を"/"にしてるけどいまいちだと思うので、適当に変えてくれ。
0415名無しさん@お腹いっぱい。2007/11/04(日) 19:00:34
>>403
あっ、あとファイル名とかにスペース入ってるとまずいから
IFS="
"
とかした方がいいよ。
0416名無しさん@お腹いっぱい。2007/11/04(日) 23:03:51
>>411
1. ローカルのファイル構成をリモートのファイル構成と同じにしたい
2. できる限りローカルのファイルの再配置で転送量を削減したい
ってことだよね。別解でこんなのどう?
#!/usr/bin/ruby
# Usage: treesync this.lst that.list
# - this.lst のファイル構成を that.lst の構成に work/ 以下で再構成するシーケンスを出力する
# - this.lst/that.lst は共に find ... -type f -print | xargs md5sum > this.lst などと生成
src_p2h = Hash[*open(ARGV.shift).read.split.reverse]
dst_p2h = Hash[*open(ARGV.shift).read.split.reverse]
src_h2p = Hash[*src_p2h.to_a.flatten.reverse]
dst_p2h.each do |path, hash|
 puts "mkdir -p `dirname work/#{path}`"
 if src_h2p[hash]
   puts "ln #{src_h2p[hash]} work/#{path}"
 else
   puts "remote-get #{path} work/#{path}"
 end
end
これでローカルのa/ツリーを元に、work/フォルダ以下に最小転送量で
リモートのb/ツリーに同期したフォルダを再構成する。remote-getコマンドは自分で用意。
0417名無しさん@お腹いっぱい。2007/11/05(月) 05:07:01
md5かよ……。ちと牛刀すぎないか。
しかも内容同じだとみなlnだから、同期と言い難い。

同期ごとにls -iR吐いておいて、rsyncの前段として前回と比較して
lnかmvするとしておけばいいのでは。
04184052007/11/05(月) 13:01:19
>>411
後から読んだら、その>>405ってのは私を指していて、
特に405のレスの事ではないみたいですね。スマソ

>>413
おお!素晴らしい。シェルスクリプトらしい構文ですね。

ちょっと気になったのは、whileループ中に$muchの値が2以上から一気に0に
変化する場合も(つまりファイル名から同じだけ遡ったパスが一致する複数ファイルが、
もう一階層上にあがると全て一致しなくなるケース)あり得るので、
その場合[ "$much" -ne 0 ] が偽の場合でもngを加算するべきだと思うのですが、
如何でしょうか?

>>403 を読むと、そもそも初めのファイル名が一致しない場合に関して触れられていないので、
$much の値が最初っからずっと0というのは除外して考えて良いんじゃないでしょうか?

つまりwhileループを抜けた時点で無条件に((ng++))で良い様な気がします。
04194052007/11/05(月) 14:25:36
追記
>>413は、そのままではウチの環境では動きませんでした。
修正して試していると[ "$much" -ne 0 ]の意味が理解できました。
[1]や[2]対策ですね。
しかし、上記の問題が有ると思うので、forループに入った所で$muchを1に初期化しておき、
((ng++)) の前の条件判断を、if [ "$much" -eq 1 ] ; then continue ; fi
とかにするのはどうでしょうか?
でもそんなことするんだったら、catの代わりにsed使った方が分かりやすいかも。
0420名無しさん@お腹いっぱい。2007/11/05(月) 15:40:35
>>413
>#!/bin/sh

>#!/bin/ksh
にする。
04214032007/11/06(火) 00:16:00
>>405
色々とありがとうございます。こちらこそ失礼しました。
>>413の解説ほんとにありがたいです。半分理解するまで2時間かかった、、

>>413 >>416
ありがとうございます。いろんなやり方がありそうですね。

0422名無しさん@お腹いっぱい。2007/11/06(火) 15:55:08
.で始まるファイルを指定したい時はどうするのがよい?

echo .*

だと今いるディレクトリと親ディレクトリにもマッチしてしまう。
zshだとドットファイルのみ展開してくれるけど、shだとどうなの
0423名無しさん@お腹いっぱい。2007/11/06(火) 16:00:47
>>422
http://www.nurs.or.jp/~asada/FAQ/UNIX/section2.11.html

環境によっては、ls -A とか。
0424名無しさん@お腹いっぱい。2007/11/06(火) 16:02:58
あるファイル(例えばa.txt)の特定の行(例えばN行目)に
文字列を書き込むにはどのようにすればよいのでしょうか?
0425名無しさん@お腹いっぱい。2007/11/06(火) 16:09:11
>>424
環境によっては
sed -i 'Nihoge' a.txt
0426名無しさん@お腹いっぱい。2007/11/06(火) 16:21:52
>>423
ありがとう。FAQでしたか
0427名無しさん@お腹いっぱい。2007/11/07(水) 18:02:48
ディレクトリにファイルがあるかどうかの分岐ってどうしてます?
いろいろやり方はあると思いますが、何か定番ってあるのでしょうか?
0428名無しさん@お腹いっぱい。2007/11/07(水) 18:32:09
if [ -f "$dir/$file" ] とかじゃなくってですか?
0429名無しさん@お腹いっぱい。2007/11/07(水) 19:49:25
>>428

それだと、特定ディレクトリの特定ファイルの有無。
>>427は、多分任意のディレクトリに何らかのファイルが有るかどうかと言うこと。
0430名無しさん@お腹いっぱい。2007/11/07(水) 19:56:42
エスパーさんあらわる
0431名無しさん@お腹いっぱい。2007/11/07(水) 20:11:38
>>430

普通に日本語を解すればエスパーでも何でもない。

>>ディレクトリにファイルがあるかどうかの分岐

財布にお金が有るかどうかの分岐。

>>if [ -f "$dir/$file" ]

if [ -f "$my_saifu/$hyakuenndama" ]

これくらいの違いを何故理解できない?
0432名無しさん@お腹いっぱい。2007/11/07(水) 20:15:24
つーかエスパーに任せないで質問者本人が説明しろよ。
0433名無しさん@お腹いっぱい。2007/11/07(水) 20:17:37
if [ `ls -A "$dir" | wc -c` -ne 0 ]; then

ってことじゃないのか?
0434名無しさん@お腹いっぱい。2007/11/07(水) 22:38:56
>>431はあたま大丈夫なのだろうか……
04354282007/11/08(木) 00:18:45
じゃあこうしよう。
if [ `find "$dir" -maxdepth 1 -type f | wc -l` ]; then
04364282007/11/08(木) 00:22:04
あ、右辺を入れ忘れました。適当に補完お願いします。
0437名無しさん@お腹いっぱい。2007/11/08(木) 00:24:04
サブディレクトリの有無は定番あるけど、ファイルの有無は
結局readdirして見るしかないだろうなぁ。

とりあえず別案。たぶんちょっとだけ速い:

 $ test "`echo .* *`" = ".* *" && echo empty

何かあれば展開元パターンと違う文字列になるから条件成立しない。
0438名無しさん@お腹いっぱい。2007/11/08(木) 00:33:23
rmdirして成功すれば空
0439名無しさん@お腹いっぱい。2007/11/08(木) 00:52:33
>438
お前頭いいな
0440名無しさん@お腹いっぱい。2007/11/08(木) 06:29:55
>>438

諸手を挙げて賛成したい気分だが、なぜか躊躇する。

何でだろう?
0441名無しさん@お腹いっぱい。2007/11/08(木) 07:43:15
>>437
それ間違い。空のディレクトリでも . と .. は必ず存在するので、
echo .* * の結果は .. . になる。
0442名無しさん@お腹いっぱい。2007/11/08(木) 10:53:24
>>441
しまった、bashismに染まってしまった。今は反省している。
rmdirがいちばんエレガントだね。そのフォルダにプロセスがいたら
根無し草になるというのが躊躇の原因だろうけど。
0443名無しさん@お腹いっぱい。2007/11/08(木) 12:28:01
rmdir() 側ではどうやって判断してるんだろ
0444名無しさん@お腹いっぱい。2007/11/08(木) 13:09:57
if rmdir --dry-run "$dir" 2> /dev/null; then
0445名無しさん@お腹いっぱい。2007/11/08(木) 13:15:38
おバカな質問ですみません。

test1.shに echo 100
test2.shに echo $1 
と書いて
sh test1.sh | sh test2.sh

として、100が表示されることを期待してるんですが、何も表示されません。。
根本がわかってないと思うのですが、このあたり、ご教示頂ければ幸いに思います。
あるいは、こういった部分に触れているサイトがありましたら、リンクを頂く形でも
幸いです。。よろしくお願い致します。
04464452007/11/08(木) 13:31:06
すみません、引数とか標準入力とかが把握できてませんでした。。
ttp://oshiete1.goo.ne.jp/kotaeru.php3?q=1508581
を見てわかりました。先のtest2.shは
read line
echo $line
などとすればいいんですね。お騒がせしました。
0447名無しさん@お腹いっぱい。2007/11/08(木) 15:56:50
rmdirないしrmではディレクトリを空の場合に削除してしまうだろ。
0448名無しさん@お腹いっぱい。2007/11/08(木) 16:04:47
そんなことは当然わかってて、
消えたら作ればいいと思いつつも>>440が出てきている。

あと、>>444で。
0449名無しさん@お腹いっぱい。2007/11/08(木) 19:13:21
>>448
権限なかったら、ダメじゃないの?
0450名無しさん@お腹いっぱい。2007/11/08(木) 19:33:32
権限なかったら、そもそも消せん
ということは、判定ができんということになるな
0451名無しさん@お腹いっぱい。2007/11/08(木) 22:49:43
権限については、読み出し権限なければreaddirな判定だってできないから
rmdirの減点にはならないかと。
0452名無しさん@お腹いっぱい。2007/11/08(木) 23:02:28
ファイル有無の判定にはrがありさえすればいいのに、
親のwがないといかんというのは厳しいだろ
04534272007/11/10(土) 04:04:04
みなさんありがとうです。
私は [ -z "$(ls dir/)" ] としてましたが、これだと何か問題はあるでしょうか?
しかし、定番って無いのですね。
0454名無しさん@お腹いっぱい。2007/11/10(土) 04:25:29
ドットで始まるものが出てこない。
if ! /bin/ls -a "$dir" | egrep -qv '^\.\.?$'; then
  echo 空っぽ
end
0455名無しさん@お腹いっぱい。2007/11/10(土) 10:20:35
>>453
ドットファイルがあると判定を誤る。

[ $(ls -a) != 2 ]
0456名無しさん@お腹いっぱい。2007/11/10(土) 10:50:15
find dir -maxdepth 0 -empty
ってだめなんだっけ
0457名無しさん@お腹いっぱい。2007/11/10(土) 12:53:48
環境依存
0458名無しさん@お腹いっぱい。2007/11/10(土) 20:14:03
ドットの問題は ls -A でいいじゃん。
ls -a なんてするから . と .. を除外する余分な処理が増える。
0459名無しさん@お腹いっぱい。2007/11/10(土) 21:23:19
case `ls -A "$dir"` in '') echo 空ディレクトリ;; esac

↑が、モストエレガント
0460名無しさん@お腹いっぱい。2007/11/11(日) 00:49:49
ps の結果を 1 分置きにくり一行のコマンドで返し表示させたいのですが
 tcsh の場合どう記述すればいいんでしょうか?

bash の場合は分かるのですが。。
while true; do  ; ps -ef ; sleep 60 ; done

ヒントだけでも良いのでアドバイスお願いします。
0461名無しさん@お腹いっぱい。2007/11/11(日) 01:35:13
ヒント: >>1 ・csh/tcshのシェルスクリプトは推奨されません。
0462名無しさん@お腹いっぱい。2007/11/11(日) 01:49:37
>>460
確か一行じゃできんかったような.
sh -c "while true; do ; ps -ef ; sleep 60 ; done"
じゃ駄目かw
0463名無しさん@お腹いっぱい。2007/11/11(日) 04:00:30
>>460
 シェルはBournシェル(sh)で書け。(昔、cshで書いて苦労した)
 クォートできないケースが多々存在するわ、
 標準エラーはパイプに流し込めないわ、
 最悪なのが、ファイルを閉じることができないこと。

あと、コンソール入力が一行入力 $< 以外、つかいものにならんから、ユーザ入力が必要なときに苦労するぞ
0464名無しさん@お腹いっぱい。2007/11/11(日) 08:06:24
Csh Programming Considered Harmful でぐぐれ。
0465名無しさん@お腹いっぱい。2007/11/11(日) 09:24:02
>>462
do のあとに ; いらんけどな。
0466名無しさん@お腹いっぱい。2007/11/14(水) 10:50:21
質問させて下さい

#!/bin/bash
num="1
2
3
4
5"
num2=3

while true ; do
echo "$num" | while read line; do
if [ "$line" -eq "$num2" ]; then
echo $line
break 2
fi
done
done

このスクリプトがbreakできないのですが、どこに間違いがあるのでしょうか?
/bin/bash を zsh に変えれれば動きます。
0467名無しさん@お腹いっぱい。2007/11/14(水) 11:23:34
内側の while がサブシェルで実行されてるから。親シェルから見たら、
break 2 ではなくふつーにサブシェルが終了したようにしか見えない。
0468名無しさん@お腹いっぱい。2007/11/14(水) 11:48:18
>>467
シェルの実装違い。

似たものに
while read〜do〜done < FILE
これについても各種シェルで動きが違う。
0469名無しさん@お腹いっぱい。2007/11/14(水) 22:54:11
>>466
↓ここも参照しる。
http://blog.goo.ne.jp/cars-kitahefu/e/4190a337427d7a8cfcb5a62f515c6936
04704662007/11/15(木) 02:30:33
ありがとうーーーーー
なんじゃそりゃという話でした…
0471名無しさん@お腹いっぱい。2007/11/15(木) 18:33:38
とあるファイル(XXX.txt)を元に、AAAからZZZまでの
連番のファイルを作りたいんだけど、
なんかいい手ある?

for i in ${ABC}
do
cp XXX.txt ${i}.txt
done

個人的には、↑みたいなので簡単に出来るかと思ったけど
${ABC}にハメるAAA,AAB,AAC〜ZZZのリストが
作れなくて。
助けてエロい人。
0472名無しさん@お腹いっぱい。2007/11/15(木) 18:49:30
>>471
for in in {A..Z}{A..Z}{A..Z}
do
:
04734712007/11/15(木) 18:55:57
>>472
スマソ、言葉足らずだった。
ウチのシステムsolaris8でbash-2.03なんだ。うん。
{A..Z}って、bash-3.0からの拡張機能だったような。
0474名無しさん@お腹いっぱい。2007/11/15(木) 18:57:49
for i in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
を3回まわせばいいじゃん。
04754712007/11/15(木) 19:54:07
>>474
言わんとしてることがイマイチ汲み取れなんだ。ごめん。
アホな俺にも分かるようにもうちょいとkwsk説明してくれん?

for i in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
do
cp XXX.txt ${i}.txt
for i in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
do
cp XXX.txt ${i}.txt
for i in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
do
cp XXX.txt ${i}.txt
done
done
done

こう、ネストしろとか…じゃないんだよな。
0476名無しさん@お腹いっぱい。2007/11/15(木) 20:32:50
for i in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
do
for j in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
do
for k in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
do
cp XXX.txt $i$j$k.txt
done
done
done
04774712007/11/15(木) 20:39:19
>>476
本気でありがとう神様
0478名無しさん@お腹いっぱい。2007/11/18(日) 03:10:54
<a href="http://xxx";>
http://xxx だけ抜き出したいのですが、ズバッと一つのコマンドで
できないでしょうか?
0479名無しさん@お腹いっぱい。2007/11/18(日) 07:07:46
echo '<a href="http://xxx";>' | gawk '{gsub("^.*< *a +href *= *\"", "");gsub("\" *>.*$",""); print}'
0480名無しさん@お腹いっぱい。2007/11/18(日) 08:09:36
echo '<a href="http://xxx";>' | cut '-d"' -f 2
0481名無しさん@お腹いっぱい。2007/11/18(日) 11:18:48
expr '<a href="http://xxx";>' : '.*"\(.*\)".*'
0482名無しさん@お腹いっぱい。2007/11/18(日) 17:37:56
>>479-481
478がどういうのを求めているか知らんが、それだと汎用性がなくて使えないのでは?
というかexprって計算以外にも使えるんだ
0483無名2007/11/18(日) 20:05:48
汎用性?

echo '<a href="http://xxx";>' | sed 's/[^"]*"\(.*\)".*/\1/'
■ このスレッドは過去ログ倉庫に格納されています