シェルスクリプト相談 ..
[2ch|▼Menu]
348:デフォルトの名無しさん
06/10/12 15:54:09
申し訳ありません。
cshで@引数が、空であるかどうかと、A引数が、数字(何桁でも可)のみ受けとる
という条件文を書きたいのですが、
@は、if ( $# -eq )や if(x$name =x)とやってもうまくいきません。
Aは、ダイレクトにif(0<=#1<=9) というやりかた?しかわかりません。

もうしわけないのですが、ご教授願えませんか?
ヒントや参考文献でもかまいません。宜しくお願いします。

349:デフォルトの名無しさん
06/10/12 23:34:19
cshやめたらいいんじゃない

350:デフォルトの名無しさん
06/10/13 17:12:45
>>348
1. 引数が空

if ( $#argv == 0 ) then
echo 空
else
echo なんかある。
endif

2. 数値かどうか

わかんねえ。こんな風にでもすれば?

set n = `echo "$argv[1]" | sed 's/[0-9][0-9]*//g'`
if ( '' == "$n" ) then
echo "$argv[1] は数値だ。"
else
echo "$argv[1] は数値ではない。"
endif


351:デフォルトの名無しさん
06/10/13 18:56:57
>>350
ありがとうございます。大変助かります。
やはり、sedコマンド使うんですね。
sedとawkを使うべきかなと思いながら、
あまりよく分かっていなかったんです。

これから試してみます。

352:デフォルトの名無しさん
06/10/13 20:31:27
>>351
本当は何か別の方法あるかも知れないけど、俺は知らない。

あと、その sed の使い方だとマイナス記号や小数点や数字と数字の途中にスペースが
あった場合とかが考慮されていないので、その辺は自分でなんとかして。


353:デフォルトの名無しさん
06/10/19 10:01:09
cshの環境で、アプリケーションログを
/backup/apl -mtime +6 -exec rm {} \;
上記のようい週次バックアップしています。

これを、直近のデータのみリストアする場合、
(最新のデータのみで、あとはいらない)
どのような表現を使えばいいのでしょうか?



354:デフォルトの名無しさん
06/10/19 21:09:43
日本語でおk

355:デフォルトの名無しさん
06/10/20 22:47:35
rshについて質問させて頂きます。
ある書籍に以下の記述がありました。

$ STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`

\マークが1個多いと思うのですが・・・。
正誤表には記載がありませんでした。
分かる方がいましたら是非回答をお願い致します。

356:デフォルトの名無しさん
06/10/21 00:09:39
>>355
引数が二回展開されるから。

まず local のシェルが引数を展開して rsh に
(hostname) と (sh -c 'ls; echo \$?') を渡す。

で、rsh が hostname のシェルで (sh -c 'ls; echo \$?') を実行する。
この時にもう一度展開される。


357:デフォルトの名無しさん
06/10/21 11:56:53
>>356
早速のご回答ありがとうございます。

>で、rsh が hostname のシェルで (sh -c 'ls; echo \$?') を実行する。
>この時にもう一度展開される。
ダブルクォーテーションで囲まれた中の$は、
シェルによってメタキャラクタと認識されてしまうので
\マークでクォートしなくてはいけないのですが、
シングルクォーテーションで囲まれた$は
メタキャラクタとは認識されないので、
\マークでクォートする必要はない、
というのが私の認識です。

よって、hostnameのシェルで実行される
(sh -c 'ls; echo \$?')の$はメタキャラクタとは
認識されないので、\マークは不要であると
思っています。

ご指摘の程よろしくお願い致します。

ちなみに今回の質問は、
書籍「入門UNIXシェルプログラミング 改訂第2版」
のP.132についてです。

358:デフォルトの名無しさん
06/10/21 19:23:38
>>357
csh 系や zsh の挙動は良く知らないが
bash のクォート除去はそこまで賢くない。

ダブルクォートの中にシングルクォートがあっても
その中身は保護されない。

例)
$ echo "$SHELL" '$SHELL' "'$SHELL'"
/bin/bash $SHELL '/bin/bash'



359:デフォルトの名無しさん
06/10/21 20:31:06
cshなんですが、
ヒアドキュメントの内容を変数に格納するのはどうやったらいいんでしょうか

360:デフォルトの名無しさん
06/10/22 04:00:06
負の遺産を量産するな。shか最悪kshで書き直せ。
(t)cshが許されるのはログインシェルまで。

361:359
06/10/25 13:13:03
古いsoralisのメンテしてる上に周りがcshしか理解できないんで仕方なく・・・
本当はbash使いたいんですけどね



362:デフォルトの名無しさん
06/10/29 15:43:34
別に仕方ないことないだろに。


363:デフォルトの名無しさん
06/10/29 18:22:40
>>356
エスケープの処理はバッククォートとダブルクォートのときじゃないか?
rshが受け取る文字列は(sh -c 'ls; echo $?')だと思うんだけど。

(STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`)
ローカルのシェルが、バッククォートとして実行する文字を解釈 -> (rsh hostname "sh -c 'ls; echo \$?'")
バッククォートが、rshを呼び出す為に引数を展開 -> (hostname) (sh -c 'ls; echo $?')
rshがhostnameに入って、ホストのシェルで第二引数を実行 -> (sh -c 'ls; echo $?')
sh -c の処理 -> (ls; echo $?)

>ダブルクォートの中にシングルクォートがあっても
>その中身は保護されない。
ダブルクォートの中のシングルクォートは単なる文字なのでこれはこれで合ってるけど。



364:デフォルトの名無しさん
06/10/29 23:14:19
>>363
bash の man を参照するとわかるがクォートの除去は
各種展開が終わってから行われる。
冗長に処理の流れを書くとこうなる。

1. コマンド実行 -> (STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`)
2. ローカルのシェルがコマンド置換(バッククォートの処理)を行う -> (rsh hostname "sh -c 'ls; echo \\$?'")
3. サブシェルが起動してバッククォートの中身を展開する -> (rsh) (hostname) (sh -c 'ls; echo \$?')
4. サブシェルが rsh に引数 (hostname) (sh -c 'ls; echo \$?') を渡す
5. rsh が hostname のシェルに (sh -c 'ls; echo \$?') を渡す
6. hostname のシェルが引数を展開する -> (sh) (-c) (ls; echo \$?)
7. hostname のシェルが sh に (-c) (ls; echo \$?) を渡す
8. sh が引数を展開、実行する -> (ls; echo $?)
9. sh -> hostname のシェル -> rsh -> サブシェルの順に返り値が渡り、コマンド置換が終了
10. STAT に返り値が代入される

365:デフォルトの名無しさん
06/10/30 02:27:55
>>364
> bash の man を参照するとわかるがクォートの除去は
> 各種展開が終わってから行われる。
EXPANTIONSのとこにあるこれ?
The order of expansions is: brace expansion, tilde expansion, parameter, variable and arithmetic expansion and
command substitution (done in a left-to-right fashion), word splitting, and pathname expansion.

ここにあるのは、どの順で実行されていくかの説明で、クォートの解釈は別の段階だぞ。
Expansion is performed on the command line after it has been split into words.
ってあるとおり、(1)シェルが一行読み込まれる → (2)単語への分割 → (3)各要素を展開する
のうち(2)の話だ。(3)にある単語分割とは別物
#1行じゃない場合はちょっとおいといてくれ


> 2. ローカルのシェルがコマンド置換(バッククォートの処理)を行う -> (rsh hostname "sh -c 'ls; echo \\$?'")
これの前に単語への分割があって、バッククォートを使っているとバックスラッシュの前にあるバックスラッシュはエスケープとして扱われるから、
(STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`) -> (STAT) (=) (`rsh hostname "sh -c 'ls; echo \$?'"`)
この段階でバックスラッシュは一個になる。
(っていうか、そうじゃないと入れ子になったバッククォートの範囲を確定できないし)

コマンド置換の展開が実行されると、サブシェルがまた単語への分割を実施して、
今回はダブルクォートのルールに従ってバックスラッシュは$に対するエスケープ文字になる。
(rsh hostname "sh -c 'ls; echo \$?'") -> (rsh) (hostname) ("sh -c 'ls; echo $?'")


「bash -v -x」してから「echo `echo "'\\$abc'"`」ってやってみ。
読み込んだ文字と、展開結果が出てくる。
サブシェルが読み込んだ文字列は
echo "'\$abc'"
になってて、すでに一回バックスラッシュが処理されてる。

366:デフォルトの名無しさん
06/10/30 03:36:14
>>365
ほー、そうだったのか。
やっぱりこういう事は自分で検証しないとダメだな。
的確な突っ込み感謝。

367:デフォルトの名無しさん
06/10/30 12:33:25
>366
そういや、肝心の355はどこいったんだ?

368:デフォルトの名無しさん
06/11/02 23:45:43
355です。

はっ!、と思って只今本スレを確認しました。
しばらくの間に様々な回答を頂き、本当にありがとうございます。
これからじっくり読ませて頂きます!

369:デフォルトの名無しさん
06/11/04 20:27:36
微妙にスレ違いかもですが

あるファイルに対する処理をパイプで繋げて、
最終的に同名のファイルに書くのはアリなんでしょうか

cat hoge.txt | grep "foo" | uniq | sort > hoge.txt

現状動いてはいるんですが・・・

ちなみにbashです


370:デフォルトの名無しさん
06/11/04 21:33:13
>>369
途中のコマンドがエラーを吐くと空になるが、いいのか?

期待通りに動いているのなら、アリではあるが
どこの環境でも動くという保証は無い。

俺ならいったん変数に入れてから書き出すかな。

a=`grep "foo" hoge.txt | sort -u`

if [ -n "$a" ] ; then
echo "$a" > hoge.txt
fi

371:デフォルトの名無しさん
06/11/04 21:35:18
あ、よく考えたら uniq | sort と sort -u は違うな。
適当に読み替えてくれ。

372:デフォルトの名無しさん
06/11/04 21:37:33
>>369
>最終的に同名のファイルに書くのはアリなんでしょうか
ダメ。


373:デフォルトの名無しさん
06/11/04 23:26:40
特定の時間帯のログだけ抽出したい場合ってどうしたらいいんでしょうか?


374:デフォルトの名無しさん
06/11/04 23:29:03
awk

375:デフォルトの名無しさん
06/11/05 04:29:12
PM18::00からAM1:00までの場合はどうすれば?

376:デフォルトの名無しさん
06/11/05 04:31:11
ログファイルの仕様は?

377:デフォルトの名無しさん
06/11/05 04:34:07
やりかたはログによる

378:デフォルトの名無しさん
06/11/05 04:46:30
2006/11/04,01:37:33,xxxxxxxxxxxxxxxxxxxxxxx
2006/11/04,02:37:33,xxxxxxxxxxxxxxxxxxxxxxx
2006/11/04,03:37:33,xxxxxxxxxxxxxxxxxxxxxxx
2006/11/04,04:37:33,xxxxxxxxxxxxxxxxxxxxxxx
2006/11/04,16:37:33,xxxxxxxxxxxxxxxxxxxxxxx
2006/11/04,21:37:33,xxxxxxxxxxxxxxxxxxxxxxx

こんなかんじ

379:デフォルトの名無しさん
06/11/05 04:52:32
ぱっと思い付かないけど、俺ならperl使うかな。

ログをとる時間とタイミングが決まってるなら検討付けて
timeコマンドで1:00にtail -10とかでがばっと適当にログを切り出して保存する。

380:デフォルトの名無しさん
06/11/05 04:56:47
>>378のフォーマットなら1行野郎でできる

awk -F '[,:]' '$2>=18||$2<1' logfile

381:379
06/11/05 05:24:52
>>380
お前マジ頭いいな

382:デフォルトの名無しさん
06/11/05 10:47:41
>>375
>PM18::00
それは一体何時なんだ?
もし、18時のことを書きたいなら6PMと書かないと意味が通じないわけだが。

383:デフォルトの名無しさん
06/11/05 10:48:59
通じなくてよし

384:デフォルトの名無しさん
06/11/05 14:16:24
なんか、awkの話になってるんで便乗で質問ですが

シェルスクリプトから

awk -f 手続きファイル 参照ファイル

とやって、-vでawkスクリプトに引数を渡してawk内で使用するのって具体的にはどうやればいいんですかね?



385:デフォルトの名無しさん
06/11/05 14:28:58
・・・・・<dateAndTime>20061101130655</dateAndTime>・・・・・・・・・・・・・・・・・
・・<dateAndTime>20061101160213</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・・・・<dateAndTime>20061101180159</dateAndTime>・・・・・・・・・・・・・・・・・
・・・<dateAndTime>20061102200159</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・・・・・・・・・・・<dateAndTime>20061103210159</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・<dateAndTime>20061104220159</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・・・・<dateAndTime>20061104131259</dateAndTime>・・・・・・・・・・・・・・・・・
・・<dateAndTime>20061104011359</dateAndTime>・・・・・・・・・・・・・・・・・
・・<dateAndTime>20061104052359</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・・・・<dateAndTime>20061105062059</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・<dateAndTime>20061106072159</dateAndTime>・・・・・・・・・・・・・・・・・
・・・<dateAndTime>20061106114359</dateAndTime>・・・・・・・・・・・・・・・・・
・・・<dateAndTime>20061107221359</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・<dateAndTime>20061108230559</dateAndTime>・・・・・・・・・・・・・・・・・

ログがタグ形式で、こんな感じだったらawkではどうする?

386:明日まで
06/11/05 14:36:03

こういうシェルを私みたいな女の子にも理解できるように解説してよ


引数付(1〜5)で実行したshellが何を引数として入力
  したかを,switch文を使って表示させたい。。

【その1】引数無し、もしくは引数が1〜5以外の場合
% ./test.sh
Invalid number.
%

【その2】引数が1〜5の場合
(5を入力した場合)
% ./test.sh 5
You have imput 5.

387:デフォルトの名無しさん
06/11/05 14:52:33
>>384
たぶん勉強すればどうにかなるんだろうけど、
awkで引数に関することでごにょごにょするのがめんどくなったのでPerlに移った。
awkは短い命令やパイプラインで使ったりはするけど、引数でごにょごにょするのは
Perlでやることにした。

>>

388:デフォルトの名無しさん
06/11/05 14:55:02
>>386
case文でnull,$1〜$5までのケース書いて、その他は(*にでも書けば良いじゃん

389:デフォルトの名無しさん
06/11/05 15:30:16
>>384
別にawkに限った話じゃないので、普通に引き数で渡せば宜しい。
後は、awkかnawkかgawkか、変数定義かARGVを使うかの違いがあるだけ。

>>385
外部プロセスでsedを呼んで処理するか、awkを呼び出すシェルスクリプト側でsedを呼んで処理する。

390:デフォルトの名無しさん
06/11/05 20:52:42
誰かこのシェル作って
今日中にやらないといけないんです、お願いします。

引数付(1〜5)で実行したshellが何を引数として入力
  したかを,switch文を使って表示させたい。。

【その1】引数無し、もしくは引数が1〜5以外の場合
% ./test.sh
Invalid number.
%

【その2】引数が1〜5の場合
(5を入力した場合)
% ./test.sh 5
You have imput 5.


391:デフォルトの名無しさん
06/11/05 22:22:18
シェルスクリプトの中身↓

awk -f xxx.awk -v awkNoHensu=${shellNoHensu} aaa.txt


xxx.awkの中身↓

{
print ${awkNoHensu}
}

awkってよくわかんないけど引数ってこんなかんじでいけるのかな?
横レスですが、外部プロセスでsedを呼ぶってひょっとしてsystemコマンド(system関数)?

392:デフォルトの名無しさん
06/11/05 23:29:32
awkはCのpopen()相当をかなり変態的かつシンプルな形で表現できる。
Ex.
--
#!awk -f
BEGIN {
if (ARGC > 1) {
cmd = "wc -l " ARGV[1];
cmd | getline fileLineCnt;
close(cmd);
}
}
{
if (fileLineCnt) {
printf("%d/%d %s\n", NR, fileLineCnt, $0);
}
}
--
sedで前処理するのも、これと同じ要領。

393:392
06/11/05 23:33:02
おっと、折角だから最後のブロックを訂正。
--
{
if (fileLineCnt) {
printf("%d/%d:", NR, fileLineCnt);
}
print;
}
--
これでコマンドライン引き数がないときはただのフィルターになる。
#>392のは引き数がないと何もしなかった。

394:デフォルトの名無しさん
06/11/06 02:23:46
>>391

awkスクリプトの中で参照するときに$つけなくてもよい。つかつけちゃダメ。
$つけたらフィールド参照になっちゃうから。

awk -v foo=ほげほげ ...

で渡したのなら、単に foo で参照できる。


395:デフォルトの名無しさん
06/11/06 17:18:33
grepでは1行が2048バイトの制限がありますが、
awkやsedの制限はどうなっているのかどなたか教えてください


396:デフォルトの名無しさん
06/11/06 20:23:22
知らない。不安なら perl 使っとけ。メモリの続く限り無制限だから。


397:デフォルトの名無しさん
06/11/06 22:09:24
2048バイト制限のあるgrepって、どのgrepのこと?


398:デフォルトの名無しさん
06/11/07 00:30:09
>>392
それはawk -v で引数を渡せばいいですか?

399:392
06/11/07 03:18:46
めんどくさい香具師だなぁ。
>393のスクリプトにfooとでも名づけて実行ビット立てたら foo foo とでもして味噌。

400:デフォルトの名無しさん
06/11/07 23:31:42
>>395
sedにも制限あったはず。それでperlにしたことがある。
てか試せ

401:デフォルトの名無しさん
06/11/07 23:49:35
>>391
awkに-vでシェルの変数を引数で渡す場合、BEGIN内でしか参照できないからあんまり意味ないですよー
嘘言ってたらごめんなさい

402:デフォルトの名無しさん
06/11/08 00:30:45
>>401
ぇ…(´Д`υ)
% awk -v foo=hello 'END { print foo }'
^Dhello
%

403:デフォルトの名無しさん
06/11/08 01:25:16
−−−−−−−−−−−−−−−
BEGIN{}

/○○/{

print$1



END{}
−−−−−−−−−−−−−−−


○○のところにシェルから持ってきた変数って使えますかね?
使えたら変数によって検索条件を変えられるんでawk最強って話になるんですが。

404:デフォルトの名無しさん
06/11/08 01:41:35
例えば,↓のようにできる

% cat emp.data
Beth 4.00 0
Dan 3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
% awk -v name=Kathy '$1 ~ name { print $2 }' emp.data
4.00
%

405:デフォルトの名無しさん
06/11/08 01:50:47
>>395

GNU sed とか gawkなら多分制限はない(メモリの許す限り)。
SUSv3をみたところ、OSごとに一行の最大の長さを定義している
LINE_MAX という定数があって、そこまでは使えることが保証
されているだけみたい。

で、FreeBSDとSolarisはこのLINE_MAXは2048バイトのようだ。


406:403
06/11/08 02:00:33
テキストをawkでカンマ区切りなどに成型した後ならそれはかなり使えそう技ですね。
しばし感心してしまいました。

でも、仮に以下のような感じのデータだったらやっぱできないんでしょうかね?
行にある、特定の文字列だけにヒットするような感じで。
たとえば/○○/のところに、BOOという引数を与えて、BOOを含む行だけ検索して特定の処理をするみたいな?

TXT
−−−−−−−−−−−−−−−
AAAAADSLADLAS
UEJNDNKA
KDJSALJDLKSA
HHHHHBOOA+aDSA
DSKAJDKASL
DSKLA+KDAS
−−−−−−−−−−−−−−−

AWK
−−−−−−−−−−−−−−−
BEGIN{}

/○○/{

何かしらの処理



END{}
−−−−−−−−−−−−−−−




407:デフォルトの名無しさん
06/11/08 02:07:10
>>406
awk -v pattern=BOO '$0 ~ pattern { print }'

408:デフォルトの名無しさん
06/11/08 13:59:33
>>403
そんなもんこうやって無理矢理やってしまえばできる。

awk '/'"$x"'/{ ... }'


409:デフォルトの名無しさん
06/11/08 21:08:39
つうかもうちょっとawkを勉強して、試した上で聞けよな・・

410:デフォルトの名無しさん
06/11/09 22:19:29
>>409
でも、Awk神がいるからか、
最近のこのスレの話の流れはなかなか為になってるよ。
まあ、シェルはある程度分かるが、
長年Awkを馬鹿にして敬遠してきた俺から言わせてもらえばだけどね。
んで、このスレ読んでAwkでも勉強してみようと思い立ち
オライリーの書籍を注文してしまったw
今思えば、俺が今まで仕事でやってきた案件なんぞ
PerlやRuby使うまでもないことばっかりってことが判明してちと鬱だがね・・・orz...

411:デフォルトの名無しさん
06/11/09 22:25:23
ファイル処理に便利だしね
シェルスクリプト作ってた筈なのに
気がつくとawkとsedの処理が8割だった事がある


412:デフォルトの名無しさん
06/11/10 00:34:43
下手な文字列処理なんかだと、Cで書くよりよっぽど早いしメンテナンスしやすいからな。

413:デフォルトの名無しさん
06/11/10 13:50:16
うちの高専で半年くらいawkばっかりやらせてた測量学の教官がいた

414:デフォルトの名無しさん
06/11/10 13:53:17

授業で

415:デフォルトの名無しさん
06/11/10 15:36:22
ときどきでいいのでawkスレのことも思い出してあげてください。

スレリンク(tech板)

416:デフォルトの名無しさん
06/11/12 16:23:26
>>410
「一寸、微笑ましい」という本心をコメントする。

417:デフォルトの名無しさん
06/11/13 17:30:40
>>380
23:15〜03:15とか
04:30〜9:30とか
分の単位がある場合でも
一行で簡潔にかけたりする?


418:デフォルトの名無しさん
06/11/13 19:14:24
>>417
awk -F '[,:]' '$2$3>="2315"||$2$3<"0315"' logfile

awk -F '[,:]' '$2$3>="0430"&&$2$3<"0930"' logfile

419:デフォルトの名無しさん
06/11/13 21:42:59
>>417
$2>=23&&$3>=15||$2<2||$2<3&&$3<15
こんな感じの書き方をすりゃいいんでないの?とアドバイスをしようと思ったら
>>418がなんかすごい技を繰り出してて…恥ずかしくなってきた罠。

420:デフォルトの名無しさん
06/11/13 21:59:53
>>412
AWKの文字列処理ってCより速いの?

421:デフォルトの名無しさん
06/11/13 22:18:38
>418
-F ×
-f ○


422:デフォルトの名無しさん
06/11/13 22:56:55
>>421
been opened if it were a file name. The option -v followed by var=value is
an assignment to be done before prog is executed; any number of -v options
may be present. The -F fs option defines the input field separator to be
the regular expression fs.
/usr/share/man/cat1/awk.1 line 26/250 (11%)

423:デフォルトの名無しさん
06/11/13 23:05:47
>>421
コマンドラインで FS の設定をしてるから間違っとらんよ。

424:デフォルトの名無しさん
06/11/13 23:38:44
リストファイルから一行ずつパターンを読み込ませて
テキストファイルを一行ずつパターン検索したいんですが
awkでファイルから入力する方法ってありますか?


425:デフォルトの名無しさん
06/11/13 23:51:26
getline関数は現在の入力ファイルから次の入力レコードを $0 に代入する。
getline < file は file から次の入力レコードを $0 に代入する。
getline x は変数 x に代入する。
cmd | getline は cmd の出力を getline にパイプする。
getline は入力が成功すると1,ファイルの末尾で 0,エラーで -1 を返す。

426:412
06/11/13 23:56:23
>>420
「速い」じゃなくて「早い」だ。つまり、どっちが早くプログラミングできるかってこと。

427:デフォルトの名無しさん
06/11/13 23:57:53
変数を受け取って、一連の処理を行うようにしたコマンドの羅列だろ。
ひとつずつコマンドを打ち込んで処理するのが面倒くさいから
判定とか分岐とか呼び出しとかを使って、処理自体を複雑・多様化するようにしたんだろ。
更に、ひとくくりの処理を名前を付けて登録できるから、コマンドはそれひとつで
自分で組んだ複数の処理をしてくれる。

基本的に古臭いものだし、フロントエンドを設けてGUI化したのを
使うのが最適だと思うのに、何故に今更ながらのコマンドシェルなんだ?

馬鹿?

428:デフォルトの名無しさん
06/11/14 00:08:47

〃∩ ∧_∧
⊂⌒( ・ω・)
 `ヽ_っ⌒/⌒c   はいはいわろすわろす
    ⌒ ⌒

429:デフォルトの名無しさん
06/11/14 07:07:15
>>424
同じファイルの次行レコードをgetlineで読めるはずだけど
処理中に別ファイルは読めないんじゃないかな
fopenとかないし引数とらせるとかなら方法あるかもな

430:デフォルトの名無しさん
06/11/14 07:37:30
>>429
>425

431:デフォルトの名無しさん
06/11/14 19:44:15

パターンファイルに一致するレコードを削除したいのですが、どうやったら実現できるでしょうか?
シェルでもアークでも構いません。御指南下さい。

テキストファイル(テキスト.txt)
20061110,AAA
20061111,BBB
20061112,CCC
20061113,DDD







パターンファイル(パターン.ptn)
AAA
CCC
GGG

432:デフォルトの名無しさん
06/11/14 19:45:09
>シェル
失せろ

>アーク
消えろ

433:デフォルトの名無しさん
06/11/14 20:35:18
% cat foo.awk
BEGIN {
    while (getline < ptn == 1)
        pattern[n++] = $0
}

{
    for (i = 0; i < n; i++)
        if ($0 ~ pattern[i])
            break
    if (i == n)
        print
}
% awk -f foo.awk -v ptn=pattern.ptn text.txt
20061111,BBB
20061113,DDD
20061114,EEE
……

434:デフォルトの名無しさん
06/11/14 20:51:08
grep -v -f パターン.ptn テキスト.txt

435:デフォルトの名無しさん
06/11/14 21:52:58
>431
アークじゃないよ。
オークって読むよ。


>433
awkって何でもできるんだな。

436:デフォルトの名無しさん
06/11/14 22:07:46
>>415にも書いてるけどawkスレも使ってやってください。
awkについて語るスレ
スレリンク(tech板)

437:デフォルトの名無しさん
06/11/14 23:03:02
>>433
オークってよむんですか。
ありがとうございます。

438:デフォルトの名無しさん
06/11/15 00:37:29
bashなんですが、daemonの起動スクリプトとかで
変数にブレースがついてたり、ついてなかったりするのは
どういう意図があるの?

439:デフォルトの名無しさん
06/11/15 00:58:40
>>438
1. 変数と文字列を明示的に区切りたいから
ex) ${foo}bar

2. ブレース展開を使っている
ex) ${foo%.*}

3. ただの気まぐれ

440:デフォルトの名無しさん
06/11/16 00:52:32
getline 変数 で、次のレコードを読んで変数に代入になると思いますが、
更にgetline 変数を使うと更に次の行が読み込まれるのでしょうか?
そのあとawk処理を終えて次のレコードをawkが読みに行ったとき、getlineの影響を受けて読んでいる行が進んでしまいますか?

AWKスクリプト

getline A
PRINT A
getline A
PRINT A


読み込みファイル
AAAAA
BBBBB
CCCCC
DDDDD

出力結果はこう?
AAAAA
BBBBB
CCCCC
DDDDD

出力結果はこう?
AAAAA
BBBBB
BBBBB
CCCCC
CCCCC
DDDDD

441:デフォルトの名無しさん
06/11/16 00:57:16
やってみればいいじゃん。
つーか、シェルからの起動も絡まないawkの話はawkのスレでやれよ。

442:デフォルトの名無しさん
06/11/16 01:02:20
スレ名変えればいいだろ、

【シェルって】サーバ用途のスクリプト【貝殻?】

443:デフォルトの名無しさん
06/11/16 01:07:00
sedなんかを使って特定のタグで囲まれたところを出力することって可能ですか?

sdak;dkslakdas;das<TAG>dkalkdlas;kdsla;kds;akdsal;dkslad;</TAG>dlaskldkalsfocmdcsdlc,ds



444:デフォルトの名無しさん
06/11/16 01:12:20
行内に開始タグ終了タグが1セットだけあるなら、
sed -ne 's/<TAG>\(.*\)<\/TAG>/\1/p'

445:デフォルトの名無しさん
06/11/16 01:14:40
>>441
たとえば>433のawkスクリプトでやってることをシェルスクリプトで実現したらどうなるかとかってのを
>441自身が率先してレスしてやるとかすればこのスレももっと進歩するんじゃないの?
絡まない話と切って捨てるのではなく絡める努力なんてこともしてみたらいかがか?

446:デフォルトの名無しさん
06/11/16 01:20:07
AwkにはSYSTEM関数もあるし
UNIXのコマンドも使えちゃうので
必ずしも無関係とは言えないか

447:デフォルトの名無しさん
06/11/17 00:46:21
寂しいスレになったね。

448:デフォルトの名無しさん
06/11/28 00:16:29
あるファイルの一部(何行もある)を違うファイルに書き換えるのはどうやるの?
例えば、

aaa aaa aaa
aaa aaa aaa
abc 1 2
abc 3 4
bbb bbb bbb

というファイルを

abc 1 10
abc 3 20

と言うファイルを使って

aaa aaa aaa
aaa aaa aaa
abc 1 2 10
abc 3 4 20
bbb bbb bbb

にしたいんだけど。。
どえらく行があって普通にsedの置換する行を書かせて実行したら
一日で終わらないくらい時間がかかってしまって。。。
もしくは、行単位で置換じゃなくて、数行単位で置換は出来ないのでしょうか?

偉い人教えてください。

449:デフォルトの名無しさん
06/11/28 02:05:01
>>448
正直説明が分かりづらいです。
というか全くわかんない。
ちゃんと質問した方が良い。
その質問じゃ法則がいまいちわからない。

ファイルの一部を違うファイルに書き換える??
catとか使って結合したらいかが?

450:デフォルトの名無しさん
06/11/28 02:11:28
マルチ乙

451:デフォルトの名無しさん
06/11/28 11:34:00
>>448
それはスペース区切りで先頭の項目をキーにして残りのデータは重複なしで
マージするという処理をしたいということか? あれ? でも、 aaa とかは
元から重複してるな。

駄目だ。やっぱ法則が分からん。


452:デフォルトの名無しさん
06/11/28 14:02:55
>>448

二つのファイルを第1フィールドと第2フィールドを“,”とかでくっつけて
(それぞれ test1.txt, test2.txt とする)、join(1) する:

 join -a1 test1.txt test2.txt

最後に“,”を削る。

それか、awk の連想配列を使って join する。

453:デフォルトの名無しさん
06/11/28 23:56:25
回答ありがとうございました。
分かりずらかったかと思いますので再度書き込ませてください。

一連の序列が混ざったファイルがあります。
例えば、
aaa bbb ccc ddd
.
ccc ddd eee fff
.
こんな感じの序列が続いた後に
linux 123 987 786 0
linux 123 903 673
linux 123 876 986 0
.
linux 234 983 934 0
linux 234 073 345 0
.
linux 345 093 945 0
linux 345 495 384
.
xyz abc def ghi
xyz ade dfe sdg
.
となっていて変えたいところはlinux〜です。

454:デフォルトの名無しさん
06/11/28 23:57:11
ここの行を
linux 123 987 786 22
linux 123 903 673 22
.
linux 234 983 934 85
linux 234 073 345 85
.
linux 345 093 945 45
linux 345 495 384 45

としたいのです。
最後の0はあったりなかったします。
最後の行に各々の22,85,45を追加(または0を置換)したいのです。
2列目は123,234,345のようにまとまりがあります。
あとはランダムです。
存在するファイルは
123 22
234 85
345 45
.
というファイルです。

455:デフォルトの名無しさん
06/11/28 23:59:27
自分は一行ずつ置換するためsedを作成するためのプログラムを作成しました。
ですが、数が一万行を超えるので、一日ではとても終わらないものになりました。
ファイルを分割してlinuxを含まない上下のファイルをとっておいて、
置換ではなくてlinux〜のファイルを作ってしまいcatで付けようとか考えていますが、
cutとかで分割する際にそんな指定って出来るんでしたっけ?
質問ばかりですいません。
宜しくお願いします。

456:デフォルトの名無しさん
06/11/29 00:10:55
追加ですが、
linux 123 987 786 22
linux 123 903 673 22
.
linux 234 983 934 85
linux 234 073 345 85
.
linux 345 093 945 45
linux 345 495 384 45
というファイルは作成出来るのですが、
これを元のファイルに反映させたいです。
手動でやるしかないですかね。。。

457:デフォルトの名無しさん
06/11/29 00:21:19
元ファイルをtest1.dat 参照ファイルをtest2.datとして
join -a1 -o 1.1 1.2 1.3 1.4 2.2 test1.dat test2.dat
とすればいいですかね。。。
joinは使ったことが無いので分かりませんが。。。

458:デフォルトの名無しさん
06/11/29 08:07:28
例示ばかりで、肝心の変換のための法則について
何も書かれちゃいねぇ!

「変えたいところは」「ここの行を…としたい」
「あったりなかったりします」

場所と結果だけ示されてもねぇ。。

459:デフォルトの名無しさん
06/11/29 08:12:43
ここはこうだから、これをこれと入れ換えます。
という説明はできないもんだろうか。

関係ないけど先日会社に面接に来た香具師。
「自己アピールは大切ですから」と言いつつ何ら具体的なことは何も言わないで帰った。
要は、客観視できていないし説明することもできないらしい。
#そのくせ、ランバ・ラルの台詞を語ってはいたのだが。

460:デフォルトの名無しさん
06/11/29 08:17:11
何か耳が痛いな。

461:デフォルトの名無しさん
06/11/29 08:23:42
言語機能の差が、スクリプト処理の決定的差ではないという事をおしえてやる

462:デフォルトの名無しさん
06/11/29 11:23:46
1万行の処理なんて一瞬で終わると思うんだが……
仮に行数Lに対して実行時間が O(L^2) だとしてもちょっと待てば終わるくらいだと思

463:デフォルトの名無しさん
06/11/29 12:06:13
すごい遅いマシン使ってるのかな?

464:デフォルトの名無しさん
06/11/29 17:32:54
シェルスクリプトじゃないけど。awkでやってみた。
BEGIN{
while(getline<ARGV[2]){
cv[$1]=$2;
}
ARGV[2]="";
}
$1=="linux"{
$5=cv[$2];
}
{
print;
}


465:デフォルトの名無しさん
06/12/05 21:39:41
csh で if($hoge == hoge) とかやったばあい、
$hoge が -f などの場合
ファイルに関する演算子の -f とみなされて
比較してくれません。
こういう場合、どうすればいいのでしょうか?

466:デフォルトの名無しさん
06/12/05 22:17:11
あ、適当な文字を両辺の先頭に付ければいけますね。
何か格好悪いので、もっといい解決法があればよろしくお願いします。

467:デフォルトの名無しさん
06/12/06 22:42:36
ファイル名の拡張子より前の名前を抽出するシェルを作っています。
例えばtest.shであれば

ls test.sh | awk -F '[.]' '{print $1}'
でtestと出力が得られるのですが、もしファイル名がtest_1.00.shの時は
test_1
のような出力になってしまいます。

awkの$NFで拡張子のshは得られるのですが、
$NF「以外全て」を出力を得るにはどのようにすればよいでしょうか?

468:デフォルトの名無しさん
06/12/06 22:48:02
>>467
man basenameでだめなんか。
それから、シェルスクリプトのことをシェル呼ぶなってば。

469:デフォルトの名無しさん
06/12/06 22:49:51
シェルスク?
シェクリ?
ルスクリ?

470:デフォルトの名無しさん
06/12/06 23:02:51
>>468
できますた。
ありがとうございました。

471:デフォルトの名無しさん
06/12/06 23:13:44
>>467
awkでやるなら
jgawk -F. "{print jsubstr($0,0,jlength($0)-jlength($NF)-1)}"
でどう?

472:デフォルトの名無しさん
06/12/06 23:28:06
>>471
試してみたのですが残念ながら、現在の環境ではjgawkというのが入ってないみたいです…
basenameはcaseで知ってる拡張子を洗いざらい場合分けするスクリプトかいて処理しました。
(txt f90 c c++ java shなど)

jgawkのインストールについて調べてみます

473:デフォルトの名無しさん
06/12/06 23:29:05
c++じゃなくてcppだった…

474:デフォルトの名無しさん
06/12/06 23:34:47
ちなみにローカルな目的は、
a2psを使ってpsファイルを作る事でした。

a2ps test1.00.sh -o test1.00.ps

拡張子を取り除いてpsの拡張子を付けるためのスクリプトを作る方法を考えていました。
basename&case文で対応はできたのですが、jgawkというのが使えるのであれば
より汎用性のあるスクリプトができそうですね。

475:デフォルトの名無しさん
06/12/06 23:40:59
ちなみに、gawkはありましたが
$ gawk -F. "{print jsubstr($0,0,jlength($0)-jlength($NF)-1)}" test1.00.sh
gawk: cmd. line:1: (FILENAME=test1.00.sh FNR=1) fatal: function `jsubstr' not defined
でした。

476:デフォルトの名無しさん
06/12/07 00:01:50
>>475
jgawkのjはJapanese(日本語)のj、
jlengthやjsubstrのjも同じ。
データーに日本語が入ってないならjは除けていいよ。


477:デフォルトの名無しさん
06/12/07 00:27:39
>>467
Solaris のawkみたいに腐ったやつだとわからないけど、gawkなら
NF--; print $0
で取れないか?


478:デフォルトの名無しさん
06/12/07 00:33:01
>>477
jgawkでやったら
aaa.bbb.ccc.dddが
aaa bbb cccになった。

479:デフォルトの名無しさん
06/12/08 01:05:00
NFってなに?
Systemコマンドの使い方教えて

480:477
06/12/08 01:21:03
>>478
スマソ。OFSを設定してクレイ。
gawk -F'[.]' -v OFS='.' '{NF--; print}
あたりでよろしこ。



481:デフォルトの名無しさん
06/12/13 21:04:58
shellってすごいね

482:デフォルトの名無しさん
06/12/22 23:27:33
#!/bin/sh
dump -0f /path/to/hda1.dump /dev/hda1
dump -0f /path/to/hda2.dump /dev/hda2

このスクリプトを実行して、hda1の実行途中でCtrl+Cを押したら
hda1は終了するけど次行のhda2のバックアップが開始されます。
スクリプト自体を終了するにはどうしますか?

483:デフォルトの名無しさん
06/12/24 10:47:11
>>482
dump は使ったことないので、勘ですが
dump -0f /path/to/hda1.dump /dev/hda1
if [ $? -ne 0 ]
then
dump -0f /path/to/hda2.dump /dev/hda2
fi
じゃ、だめですか?

484:デフォルトの名無しさん
06/12/24 12:55:55
#!/bin/sh -e
dump -0f /path/to/hda1.dump /dev/hda1
dump -0f /path/to/hda2.dump /dev/hda2


485:デフォルトの名無しさん
06/12/26 23:54:08
sedで-dオプションを使って、特定の文字列がヒットした時に、
その行を削除したいのですがうまくいきません。
manpageみても使い方がよくわからず、困り果てております。
どうやって使えばいいかご教授お願いします。

486:デフォルトの名無しさん
06/12/26 23:58:45
>>485
-dオプション???

単純に行削除だけなら例えば以下のように。
--
sed -e '1,5d' #最初の5行を削除
sed -e '/pattern/d' #patternを含む業を削除

487:デフォルトの名無しさん
06/12/27 06:42:35
>>486

使い方思いっきり間違ってました
ありがとうございます
助かりました

488:デフォルトの名無しさん
06/12/27 17:11:03
てか、パターンを含む行を削除したいだけなら grep -v でやれば良い。


489:デフォルトの名無しさん
06/12/28 01:09:04
きっとgrepでは業(カルマ)を削除できないのだろう。

490:デフォルトの名無しさん
06/12/29 16:00:50
sedでレコードのor検索やand検索ってできますか?


491:デフォルトの名無しさん
06/12/29 16:12:11
RDBでいうレコードの概念は、区切り文字とのパターンマッチでおおよそシミュレート可能。
その上で、パターン/X/と/Y/のandは/X/{/Y/}で、orは
/X/...
/Y/...
でシミュレート可能。

492:デフォルトの名無しさん
06/12/30 12:08:44
例えばレコードの100バイト目から105バイト目を置換したいんだけど、
全角・半角が不規則に混ざっているので、
s/(.{100,100})......)/\1abcdef/
とか正規表現でやってもうまくいかないんだよね。
良い方法あるかな?
ちなみにUNIX、sedでやるつもり。

493:デフォルトの名無しさん
06/12/30 15:00:03
>>492
多バイト文字を途中でぶった切ってもいいの?

$ LC_ALL=C sed -e 's/^\(.\{99\}\)\.\{6\}/\1abcdef/'
とか。LC_ALLは状況しだいでLANGとかLC_COLLATEあたりでもOK。
あとこの正規表現はGNU sed でないと多分食ってくれない。


494:492
06/12/30 23:40:41
うちはcshなので
env LC_ALL=C sed 〜
って感じですね!
ありがd!
後いい忘れたけど固定長ファイルで置換部分は必ず1バイト文字なのでぶった切られることはないです。


495:デフォルトの名無しさん
07/01/02 14:18:06
RDB=ラーメンデータベース

496:デフォルトの名無しさん
07/01/03 00:18:43
よく勘違いされてるんだけど、
ラーメン(Rahmen)というのはドイツ語で、
英語のframeに相当する単語なんだ。
だから「枠」とか「骨格」とか「軸組み」とかいうような
ニュアンスなんだよ、本来であれば。

497:デフォルトの名無しさん
07/01/03 09:39:49
ラーメン違い。本来も糞もない。


498:デフォルトの名無しさん
07/01/03 12:33:20
遅レス気味すまそ。
>>483
そういうの書くなら
dump -0f path/to/hda1.dump /dev/hda1 || exit 1
と || exit の方が、見やすくって良くないか。


499:デフォルトの名無しさん
07/01/05 01:26:49
質問があります。
Vine4.0を使用していまして

#!/bin/sh
declare -i MAX
MAX=10
while[ $MAX -lt $1 ]
do
echo $MAX
MAX=$MAX+1
done

というスクリプトを書いたのですがいざ実行してみると下記のようなエラー?がでてしまします。
command not foundということは何かがたりないのでしょうか?
アドバイスお願いします。

. a05.sh 12
bash: while[ 10 -lt 12 ]: command not found
bash: a05.sh: line 5: syntax error near unexpected token `do'
bash: a05.sh: line 5: `do'


500:デフォルトの名無しさん
07/01/05 02:35:36
whileの後ろに空白がないんじゃないか?>499

501:デフォルトの名無しさん
07/01/05 03:45:07
>>499
空白入りの引数を渡すとエラーを吐くから
$1 の所をクォートしておくと吉

502:499
07/01/06 02:58:14
>>500,501
whileの後ろに空白をいれたら無事に動作しました。
クォートとは''の事ですよね?参考になりました。
ありがとうございました。

新しい質問なんですけど

#!/bin/bash
while [ -f .count.lock ]; do
sleep 0.1
done
touch .count.lock
declare -i INTEG
INTEG='cat access_count.txt'
INTEG=$INTEG+1
echo $INTEG >| access_count.txt
echo "$INTEG"
rm -f .count.lock

を動作させると

bash: cat access_count.txt: syntax error in expression
(error token is "access_count.txt")
15 ←access_count.txtの内容を書き換えてもどんどんインデントされていきます。
の様に吐き出されてしまいます。
INTEG='cat access_count.txt'の部分が悪い様なのですがINTEGにcatを使って
ファイルの内容を代入することはできないのでしょうか?
access_count.txtの中身は 0 とだけ入っています。

よろしくお願いします。

503:デフォルトの名無しさん
07/01/06 03:33:25
コーテーションの向きを確認すべきかと

504:492
07/01/06 11:02:47
すいません、また来ました…

\{99\}使えんかったorz
.を99個書くしかないんかね〜


505:デフォルトの名無しさん
07/01/06 21:31:43
>>504
sedを使わない方法
(dd bs=1 count=99;dd bs=6 count=1 of=/dev/null; echo -n abcdef; cat)

506:デフォルトの名無しさん
07/01/07 02:48:47
>>504
使ってる sed がGNU sedでないとかない?

echo abcdefghijklmn | sed -e 's/^\(.\{5\}\).../\1XXX/'

abcdeXXXijklmn
になるよ(Fedora Core5)

あと、493は後ろのドットに余計な\がついてるからそれはとっておくんなまし。


507:デフォルトの名無しさん
07/01/10 15:39:41
>>504
awk '{print substr(1, 99, $0) "12345" substr($0, 105)}' hoge.txt


508:デフォルトの名無しさん
07/01/10 23:38:53
>>504
printf "%099d\n" |tr 0 \.

509:504
07/01/16 00:52:23
やっぱawkじゃね〜
サンクスコ


510:デフォルトの名無しさん
07/01/16 17:35:01
ちょいとawkスクリプトでお尋ねしたいんだが、
2つ以上のファイルから文字列の切り出しってできますかね?
色々試してみたのだけれど全然できなかったんで

hoge1.dat の$1,$3 と hoge2.dat の$5,$2 を 1行でhogehoge.datに出力という形

GMTっていうマイナーなツールで絵を描いてるんだけど、GMT内の計算スクリプトで出たデータのお尻に
別のデータを加えてそのまま描けないかなぁって試行錯誤してるんですが。

511:デフォルトの名無しさん
07/01/16 17:44:04
できます。しかし、残念ながらスレ違いにつきawkスクリプトは割愛。

512:デフォルトの名無しさん
07/01/16 18:08:10
>>511
スクリプトが複数行に渡らずにできるならなんとかサンプル探してやってみる

513:デフォルトの名無しさん
07/01/16 18:33:03
>>512
なぜにワンライナーにこだわるん?

514:512
07/01/16 19:44:23
スレ違いだけど一応
>>513
簡単に言えば頭の悪い素人だから。
マニュアルになりそうなもんは見たりするんだけど、大体そういうのって一行で処理終わらせるのが多くて。
専門用語がてんでダメだし、

何故処理できるのか?を理解してなくて、「こうやればこういうのができる」でしか認識してなく
自分自身、誰かが書いたソースの簡単な処理や変数を弄るだけしかできないって分かってる。
複数行に渡ると検索でHITしにくいし、「できる」て事さえ分かれば後は調べたらなんとかなるかな、と

スレ読んでたら組み合わせ次第でなんとかできそうだわ

515:デフォルトの名無しさん
07/01/16 19:55:53
カラム数が固定ならpasteとawkをパイプで繋ぐのが楽かな。

516:デフォルトの名無しさん
07/01/17 00:33:49
一応、書いてみたんだがな…、1行ぢゃないから駄目か

#!/usr/bin/gawk -f
BEGIN{
    while( (getline line1 < "hoge1.dat" ) > 0 && \
           (getline line2 < "hoge2.dat" ) > 0 ){
        split(line1,col1)
        split(line2,col2)
        print col1[1],col1[3],col2[5],col2[2]
    }
}

517:デフォルトの名無しさん
07/01/17 01:45:36
>>510
bash 限定かも

$ paste <( awk '{print $1,$3}' hoge1.dat ) <( awk '{print $5,$2}' hoge2.dat )


518:デフォルトの名無しさん
07/01/24 10:59:01
対話式のスクリプトを作っており、read で入力されたIPアドレスを
正規表現でIPアドレス規則が正しいかを判断さえたいのですが、
どうしたらいいですかね。

519:デフォルトの名無しさん
07/01/24 11:51:57
関数やサブシェルについての質問です。
まずサブルーチンの方ですが、以下のようにしました。
「Name_sub.sh」
#!/bin/sh

echo "What is your name and age ?"
read your_name your_age

CHECK_NAME () {
echo $1 $2
}

CHECK_NAME $your_name $your_age

これ単体で実行すると、正常に$your_name $your_ageが戻ってくることを確認しました。
これを他のmainスクリプトから呼び出して使おうとしました。

「Name_main.sh」
#!/bin/sh

var=(`./Name_sub.sh`)
echo '${var[@]} = ' ${var[@]}

ここで、Name_sub.shの戻り値を配列varに入れようとすると、
Name_sub.shの対話部分が表示されませんでした。
対話部分をプロンプトに表示して、関数のCHECK_NAMEの戻り値のみ
配列varに代入するにはどうすればよいのでしょうか?

520:デフォルトの名無しさん
07/01/24 12:29:27
とりあえずtmp.txtファイルに値を保存して、その値をmainで読み込むことにしました。

521:デフォルトの名無しさん
07/01/24 13:17:20
source を使うケースじゃないのかな。


522:デフォルトの名無しさん
07/01/25 15:51:10
>>518
sh や bash の場合 (ksh もこうだったかも知れない)
IFS=.
とすると set で指定した変数は '.' で区切られて $n に入るようになる。
たとえば ipaddr に 172.24.1.2 と入っているときに

IFS=.
set $ipaddr

とやると $1 に 172, $2 に 24, $3 に 1, $4 に 2 が入り、更に $# が
4になる(4つに分割されたということ)。

なのでまずはこの直後に
if [ $# -ne 4 ]; then echo Error ; exit 1 ; fi
のようなことをして4つでなければエラー扱いにしてしまえば良いと思う。

更に $1 から $4 に入っているので for でループさせることもできる。
なのでここで数値が 0 〜 255 になっていなければエラーにすれば良い。

# n に 172, 24, 1, 2 の順で代入されてループする。
for n
do
 if [ 0 -gt "$n" -o 255 -lt "$n" ]; then echo Error ; exit 1 ; fi
done

テストで数を先に書いている理由は n には何が入ってくるか分からないから。
('-' で始まるオプションのようなものを入れられてしまうとテストコマンドの
動作が変わってしまうかも知れないため)



次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5111日前に更新/248 KB
担当:undef