シェルスクリプト相談室at TECH
シェルスクリプト相談室 - 暇つぶし2ch369:デフォルトの名無しさん
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 ~
って感じですね!
ありが㌧!
後いい忘れたけど固定長ファイルで置換部分は必ず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 には何が入ってくるか分からないから。
('-' で始まるオプションのようなものを入れられてしまうとテストコマンドの
動作が変わってしまうかも知れないため)


523:デフォルトの名無しさん
07/01/25 16:05:50
どうしても正規表現を使わないと我慢ならんという場合はこんな感じかな。
なんか無理があるが。

if perl -e '$_='\'"$ipaddr"\'';if(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/){if($1>=0&&$1<=255&&$2>=0&&$2<=255&&$3>=0&&$3<=255&&$4>=0&&$4<=255){exit 0}}exit 1;'
then
 echo ok
else
 echo ng
fi


524:デフォルトの名無しさん
07/01/25 17:38:15
正規表現の時は >=0 の判定はいらんと思う。
どちらにしろ面倒だけど。

525:デフォルトの名無しさん
07/01/25 22:03:14
あ、そうだね。いらないね。

526:デフォルトの名無しさん
07/02/07 22:53:33
[質問]
シェルスクリプト初心者です.

power 12.34 dBm
power 13.45 dBm
power 14.56 dBm

ある,power(電力) の変化を確認するのに

while true; do sleep 1 echo `command`; done

で 表示しているのですが

改行して新たな出力を出さないで,
前の出力を消し power 値 dBm の値のところだけが変わる

ようにしたいのですが,いい方法ありませんか?

clear は使わずにお願いします.

分かりにくい説明ですみませんがどうかよろしくお願いします.

527:デフォルトの名無しさん
07/02/07 23:09:16
>>526
キャリッジリターンを使うと吉。
command が複数行出力しているとこれでは上手くいかないけど。

while true; do sleep 1; echo -en "`command`\r" ; done

詳細は man printf かな?

528:デフォルトの名無しさん
07/02/11 11:20:30
シェルスクリプトって例外処理できます?
例えば一つ上の行でエラーが発生したときはそのシェルスクリプトの処理を終了するとか。

529:デフォルトの名無しさん
07/02/11 12:14:42
>>528
プロセスの終了ステータスを見て条件分岐することはできる。

530:デフォルトの名無しさん
07/02/11 13:13:06
>>528
普通は>>529の終了ステータスを使う。エラー時に終了するだけならこれで十分。
シグナルが飛ぶならtrapでシグナルハンドラを書くのもあり。

try/catch/throwに直接対応するものは、Bourne shell、csh、bashにはない。


531:デフォルトの名無しさん
07/02/11 20:02:45
set -eしとけば、(検査されていない)終了ステータスが0以外の場合は
スクリプトが終了する。終了処理はtrap "..." 0

532:デフォルトの名無しさん
07/02/12 08:56:55
どもですm(_ _)m

533:デフォルトの名無しさん
07/04/04 19:47:34
リダイレクトのことで質問なんですが
echo hoge > test
ls -l < test
とやるとlsは標準入力(つまりtest)の内容を読み込むのなら
普通にls -lとした場合はキーボードからの入力を読み込もうとすると思うんですが、
そうはならないのは何故なんでしょうか?

534:デフォルトの名無しさん
07/04/04 21:19:42
>>533
入力がリダイレクトされても、lsは何も読むわけではない。
つまり、ls -l < test と書いても ls -l と書いても同じ事。

535:デフォルトの名無しさん
07/04/04 21:42:01
たしかにls -l < testとやっても変わらないみたいです。
今、入門UNIXシェルプログラミングという本で勉強しているのですが、
その本の89ページには
echo abc nnn > xyz
ls -l < xyz
とするとls -l abc nnnとしたときと同じ結果になる。書いてあったのですが、
この本が書かれた時と今ではlsの動作が異なるということなんでしょうか?


536:デフォルトの名無しさん
07/04/04 21:55:46
いつの時代か知らんが、lsが標準入力から引数を貰うような作りになってる
という話は聞いたことがないな。

ls -l `cat xyz`とか xargs ls -l < xyz ならありえる。

xargsは、はしょって言うと、標準入力から受け取ったものを、自分に与えられ
た引数につなげたて、その全体を実行するコマンド。、


537:デフォルトの名無しさん
07/04/04 22:01:14
うーんサンプルコードを見ても特にxargsを使っているわけではないようです。
本のタイトル名で検索したらサポートページがあったので、後で
この件に関してメールを送ってみようかと思います。ありがとうございました。

538:デフォルトの名無しさん
07/04/04 22:12:21
>>537
物はこれか?
URLリンク(shop.sbcr.jp)
ここには載っていないようだな。
URLリンク(shop.sbcr.jp)

539:デフォルトの名無しさん
07/04/04 22:17:38
この本か。
会社に置きっぱなしだから明日確認してみる。

540:デフォルトの名無しさん
07/04/04 22:22:57
著者名のつづりのミスもみつけられんとこ信用するな

541:デフォルトの名無しさん
07/04/05 01:49:29
>>535
ls -l `< xyz` なら期待通りの結果になるよ。

bash 依存の記法だったと記憶しているけど。


542:539
07/04/05 10:21:44
入門UNIXシェルプログラミング(ソフトバンク株式会社、Bruce Blinn、初版)
の87ページに確かに載っているな

----------
$ cat xyz # xyzファイルの中身を確認
abc nnn
$ ls -l < xyz # xyzファイルを「標準入力」としてリダイレクトする
----------

ls (GNU coreutils) 5.97では動きませんでしたがええ。

543:デフォルトの名無しさん
07/04/05 12:53:34
リダイレクトのことで質問なんですが
中身がスペース一つのファイルsampleを
cat test | sed -e 's/ / /' > test2
とするとtest2にスペース10個が出力されるので
cat test | sed -e 's/ / /' > test
とするとtestの中にはスペースが10個入っていると思うんですが、
中身を見てみると空になってしまいます。
一つのコマンドの中で同じファイルに対して入出力のリダイレクトを行うと
空になってしまうのはわかるんですが、今回の場合はどうしてうまくいかないのでしょうか?

544:543
07/04/05 12:55:16
すいません、上の例でのtestはsampleの間違いですorz

545:543
07/04/05 12:57:52
何度もすいませんorz
どうやら連続した半角スペースは一つにまとめられてしまうみたいで、
上の例のs/ / /はs/スペース1個/スペース10個/ってことです。

546:デフォルトの名無しさん
07/04/05 13:50:57
>>545
一部のOSのようにパイプラインを非同期にしか実装してない環境ならいざ知らず、
まともなOSではパイプラインの前後のプロセスは同時に実行されるので、
パイプラインに接続する一つのファイルを読み書きしようとすれば当然そうなる。


547:デフォルトの名無しさん
07/04/05 14:50:40
つまり上の例だと
・最初に書き込み用にファイルを開く、当然ファイルの中身は空になる。
・catは空のファイルの中身を出力する
・空がsedに渡されるので当然空をファイルに書き込む
という順番で処理が行われるんでしょうか?

548:デフォルトの名無しさん
07/04/05 15:14:56
ちょっと違うな。
cat test | sed -e 's/ / /' > test
の場合、
シェルがtestを"w"で開いてからcatとsedを起動する筈だから、
catが起動された時点でtestは既に空の筈だ。
空の入力に対してcatは何も出力しないし、sedも同じように何も出力しない。
従って、空になるのはcatやsedが起動される前と言うことだ。

ちなみに、どうしても同じファイルに読み書きしたいなら
sed -e 's/ / /' < test | tee test
のようにしてしまえばいい。
これなら、シェルがtestを開いてからteeがtestを開こうとするので
(unixの開きっ放しのファイルは削除できたように見えてもそれは見掛けだけ仕様に基づき)
無事に処理される筈だ。

549:デフォルトの名無しさん
07/04/05 15:27:54
まず最優先でリダイレクトのための処理が行われて、それから
コマンドの処理が行われるんですね。わかりました。ありがとうございます。

550:デフォルトの名無しさん
07/04/05 17:02:21
なんか今一判っていない悪寒。

551:デフォルトの名無しさん
07/04/06 02:40:06
>>549
GNU sed 使ってるなら -i オプションつけとけ


552:デフォルトの名無しさん
07/04/07 19:35:57
シェルを初めて組みます。
Cシェルで、自分のグローバルIPを取得して、そのIPをメールで送信するようなプログラムを
組みたいと思っております。

で、グローバルIPの取得の仕方が分からないのですが、
どのようにかけばよいのでしょうか?

OSはRedHat10です。

553:デフォルトの名無しさん
07/04/07 20:07:14
シェルスクリプトのことをシェルゆーな。
Cシェルで書くな。

プライベートアドレス
10.x.x.x
172. {16-32} .x.x
192.168.x.x

割り当てられているIPアドレスは

LANG=C
/sbin/ifconfig |sed -n 's/inet addr:¥([^ ][^ ]*¥) .*/¥1/p'
で取れるから、あとはawkでも使って該当しないものを除外すれば
いいんじゃないか?

と書いてから気づいたが、家のダイアルアップルータに繋がっている
LinuxからグローバルIPアドレスを取ろうとするなら、Linuxにはプライ
ベートIPアドレスしか割り当てられてない。取るべきはルータに付いてる
グローバルIPアドレスになるから別の方法が必要だぞ。


554:デフォルトの名無しさん
07/04/07 22:25:30
>>553
すいません、ありがとうございます。
何もわかってないんで^^;
ずばり、そのとおりで、取得したいのはルータについてるグローバルIPです。。

555:デフォルトの名無しさん
07/04/07 22:42:16
>>554
ダイアルアップルータやモデムにはtelnetサーバが内蔵されていることがある。
叩くコマンドが分かれば、expectを使って取得できるかもしれない。

httpサーバを内蔵していることもあるが、こっちはずばりIPアドレスを確認する
ページを持ってるかもね。


556:デフォルトの名無しさん
07/04/07 23:00:35
>>554
誰もおまいのルータの仕様を知っているやつはいないからな・・・

うちのFLASHWAVE 2040 M1ならURLリンク(ID:PASS@)ルータのIP/doKeeping.htmlを
wgetで取得してvar sIpAddress="*.*.*.*";の場所を取得すればわかる。

557:デフォルトの名無しさん
07/04/08 00:37:43
何も考えずにメール出せば、大抵はReceived:にIPアドレスが自動的に書かれる。
書かれないならば、書いてくれるメールサーバを提供しているISPに乗り換える。


558:537
07/04/11 10:24:46
ソフトバンクさんからメールの返事が届きました。
正誤表も更新したみたいです。

559:デフォルトの名無しさん
07/04/11 12:36:15
alias定義で改行の前に入れる\にはどのような作用があるのでしょうか?
csh でいろいろと試してみたところ、下のようにwhile文などが使えるようになりますが、
一方で、引数を扱ったりwhile文のネストをしたりすると正常に動作しなくなってしまいます。

alias loop '\
set count = 1\
while ( $count <= 5 )\
echo hoge\
@ count++\
end\
'


560:デフォルトの名無しさん
07/04/11 12:45:23
未だだね。

561:デフォルトの名無しさん
07/04/11 12:46:29
あーいけね、>560は>558の話ね。

>>559
行末のバックスラッシュは改行文字をエスケープする。

562:デフォルトの名無しさん
07/04/11 13:19:26
>>561
「改行文字をエスケープする」の意味を具体的に教えて欲しいのです。
>>559のコードで\+改行を空白に置き換えると動かなくなります。
妙な副作用がなぜ出るのかも謎です。

563:デフォルトの名無しさん
07/04/11 22:34:26
>>552
診断君とかにアクセスしてIP抜いてもらって
それをパースするのはだめなんか?

564:デフォルトの名無しさん
07/04/11 22:36:33
ワンクリ詐欺サイトにアクセスすればIPアドレス教えてくれそうだな。



565:デフォルトの名無しさん
07/04/11 23:29:53
>>563
頻度にもよるけどあんま他人様のとこに頼るのもいかんと思う。
自前で取れるんならそうした方が優しいし確実。一応
URLリンク(info.ddo.jp)
とか使うとワンライナーでやれるけど。

566:デフォルトの名無しさん
07/04/12 12:59:30
>>562
シェルスクリプトにおける改行の意味を調べてみると良いよ。

alias loop 'set count = 1;while ( $count <= 5 );echo hoge;@ count++;end;'


567:デフォルトの名無しさん
07/04/13 05:02:58
>>566
while?

568:デフォルトの名無しさん
07/04/13 21:22:17
質問させてください。
以下のように、test-serverへ接続し、
date;hostname;whoamiを実行するスクリプトを書いてます。
date;hostname;whoamiの結果をリダイレクトし、
スクリプト本体があるサーバに保存したいのですが、
その場合、どう記述すれば良いでしょうか。

#/bin/bash
HOST=test-server
UNAME=root
PASSWD=***

expect -c "
set timeout 20
spawn telnet $HOST
expect login:\ ; send \"$UNAME\r\"
expect sword:\ ; send \"$PASSWD\r\"
expect \"$\" ; send \"ls\r\"
expect \"$\" ; send \"date;hostname;whoami\r\"
expect \"$\" ; send \"exit\r\"

569:デフォルトの名無しさん
07/04/16 11:40:37
そのスクリプトの出力をリダイレクトすればいいのではなくて?

570:568
07/04/17 21:48:16
その方法が分からないのです。expect内部でリダイレクトすると
接続先にファイルが出来てしまうんじゃ無いでしょうか

571:デフォルトの名無しさん
07/04/17 23:45:47
>>570
にほんごよめますか?

572:デフォルトの名無しさん
07/04/18 00:08:52
ラッパー側のスクリプトの出力をリダイレクトしようとしても、
expectの中で起動したプロセスの出力はexpectが全部食っちゃうん
じゃないの?


573:デフォルトの名無しさん
07/04/21 18:39:33
あるプログラムをバックグラウンド実行して、
そのプログラムが一定時間後に終了していなかったら終了させる、みたいなことはできますか?

こんなイメージです。

#!/bin/sh

/bin/hoge & # 数十分かかる。途中で固まるかもしれない。

sleep 3600 # 念のため一時間待ってみる

[ hoge が終了していなかったら hogeをkillする。終了していたら無視 ]

exit

574:デフォルトの名無しさん
07/04/21 18:41:17
あげ

575:デフォルトの名無しさん
07/04/21 18:50:35
>>573
こういう事?

#!/bin/sh -x
DURATION=3600

hoge &
PID=$!

echo ${PID}
sleep ${DURATION}

kill ${PID}
exit

576:デフォルトの名無しさん
07/04/21 18:51:49
>>573
pid控えておいて、atコマンドで終了スクリプトを仕込むとか。


577:デフォルトの名無しさん
07/04/21 19:30:31
一時間の間にpidが再利用されない保証があるなら。

578:デフォルトの名無しさん
07/04/21 19:44:35
kill する前に親プロセスの PID を確認すれば。

579:デフォルトの名無しさん
07/04/21 20:11:19
データを 1バイトだけ 読み込むコマンドってなんだっけ?

580:デフォルトの名無しさん
07/04/21 22:21:18
>>579
head -c 1 ?

581:573
07/04/21 22:39:07
>>575
こういうことです!ありがとうございます。

>>576
atd動いていないッス。。。

>>577
>>578
pidが再利用されない補償はもちろん無いです。
ググっていますがPPIDを確認をするコマンドが見あたらないorz
$!や$$でPIDが取れるようなのでpsコマンドの結果から何とかしてみます。


582:デフォルトの名無しさん
07/04/22 17:22:43
waitか何かで子プロセスの終了待てなかったっけ?

583:デフォルトの名無しさん
07/04/22 18:14:45
>>573

pid=$!
count=0
while [ $count -lt 60 ]; do
sleep 60
kill -0 $pid || break
count=`expr $count + 1`
done
[ $count -lt 60 ] || kill $pid

584:デフォルトの名無しさん
07/04/22 18:15:16
待つよ。

585:デフォルトの名無しさん
07/04/22 18:16:01
むぅ、30秒差で…

>>582
waitで待つよ。

586:デフォルトの名無しさん
07/04/23 11:19:01
>>583
kill -0 $pid
ってどういう意味?

587:デフォルトの名無しさん
07/04/23 20:32:55
kill -0 $pid 2>/dev/null || break
の方がベターだな。

>>586
man 2 kill
The kill() system call sends the signal given by sig to pid, a process or
a group of processes. The sig argument may be one of the signals speci-
fied in sigaction(2) or it may be 0, in which case error checking is per-
formed but no signal is actually sent. This can be used to check the
validity of pid.

プロセスが存在してそのプロセスにシグナルを送る権限があれば正常終了。
それ以外はエラー。つまり、プロセスの生存確認に使用できる。

588:デフォルトの名無しさん
07/04/23 20:58:56
>>587
なるほど。
日本語man読んでも意味がわかんなかったんだ

ありがとう

589:デフォルトの名無しさん
07/04/27 13:30:22
シェルブリッド

590:デフォルトの名無しさん
07/04/28 16:07:15

♪ア・ソ~レ

ア・チョン! ア・チョン!

ア・チョン! チョン! チョン! バカ!

591:デフォルトの名無しさん
07/05/04 00:27:06
a.txt
2
4
23
87
483
3
b.txt
89
34
111
8
3
97
とある場合
program a.txt b.txt
と打てば
以下のようにに表示されるシェルスクリプトってできませぬか?

2+89=91
4+34=38
23+111=134
87+8=95
483+3=486
3+97=100

592:デフォルトの名無しさん
07/05/04 00:35:51
>>591
スクリプトにするまでもないが、

#!/bin/sh
paste a.txt b.txt | awk '{ print $1 "+" $2 "=" $1 + $2}'


593:デフォルトの名無しさん
07/05/04 00:36:40
あああ、paste $* | awk 以下略

594:デフォルトの名無しさん
07/05/04 22:00:14
ああpasteって知らなんだサンキュー

595:デフォルトの名無しさん
07/05/10 19:24:42
自演さらしあげ

596:デフォルトの名無しさん
07/06/18 22:07:54
既存ファイルの一部のみ書き換える事ってできますか?
(ファイル名変えずに)

NHK,1
NTV,4
TBS,6
FTV,8
ANB,10

というテキストがあったとして
sed 's/N/X/g' という操作をして

XHK,1
XTV,4
TBS,6
FTV,8
AXB,10

としたいです。

597:デフォルトの名無しさん
07/06/18 22:23:39
別のファイルに出力した後で、mvかcp

598:デフォルトの名無しさん
07/06/18 22:34:19
-i オプションあるならそれ使え

599:デフォルトの名無しさん
07/06/19 06:36:31
(mv file file.bak&& sed -e 's/N/X/g' >file) <file

600:デフォルトの名無しさん
07/06/19 06:47:14
sed -i 's/N/X/g' file

601:デフォルトの名無しさん
07/06/19 10:04:16
sed -i ってどんな機能??

602:デフォルトの名無しさん
07/06/19 10:23:41
手元のsedにはないオプションだ。

603:デフォルトの名無しさん
07/06/19 10:47:04
なら perl 使っとけ。
perl -i -pe 's/N/X/g' file

604:デフォルトの名無しさん
07/06/19 23:36:49
edでいいんじゃね?

605:デフォルトの名無しさん
07/06/27 00:30:13
ファイルのある文字列を含む行と行の間を取得するにはどうしたらいいのでしょうか?
例えば「abc」「def」を含む行の間、2・3・4行目を取得をしたいです。
grepでやろうとしたのですが、どうしてもうまくいきません。。

abcaa
aaaaa
bbbbb
ccccc
defbb

606:デフォルトの名無しさん
07/06/27 00:36:36
>>605
sed -n '/abc/,/def/p' < text | sed '1d;$d'

なんか冗長なのと、該当箇所が複数あると駄目だな。


607:デフォルトの名無しさん
07/06/27 00:37:59
パイプの後段を sed '/abc/d;/def/d' にすれば該当箇所が複数あってもOKかも。


608:デフォルトの名無しさん
07/06/27 00:47:05
>>605
sed -n '1,/abc/b; /def/q; p'

609:605
07/06/27 01:12:46
レスありがとうございます。

無理やりawkで冗長なものを作ろうとしてました。
もっと修行して出直します。

610:デフォルトの名無しさん
07/06/27 01:37:53
>>609
別にawkでいいんじゃね。ラクだし
↓複数箇所でも大丈夫
awk '/aaa/{f=1;next} /bbb/{f=0} f{print}'

611:デフォルトの名無しさん
07/06/29 23:03:01
つーかやり無理一行で作らんでも、perlとかで普通に作ればいいんじゃね。
冗長だろうがなんだろうが。

612:デフォルトの名無しさん
07/07/01 12:04:28
awkでがんばって一行で作ったのの速度と
perlでシコシコださく書いたのの速度は
どっちが速いですかね

613:デフォルトの名無しさん
07/07/01 12:11:24
別に全然頑張ってない

614:デフォルトの名無しさん
07/07/01 12:19:38
awkで一行で書けるものがperlで一行で書けない理由は無い。

615:デフォルトの名無しさん
07/07/01 15:09:13
一行に納める必要はないです。
バックリファレンスなどの特殊な機能を使わなければ
遅延評価DFAで動くawkは行数が増えても遅くなりません。
逆に頑張って一行で書いてもあんまり高速化しません。

616:デフォルトの名無しさん
07/07/04 23:12:58
九九の表を作るスクリプトなんですけど
cshで@を使わないで書き直したらどうなりますか?

#!/bin/csh -f

echo " | 1 2 3 4 5 6 7 8 9"
echo "--|------------------"

foreach i (1 2 3 4 5 6 7 8 9)
eaco -n " $i|"
foreach j (1 2 3 4 5 6 7 8 9)
@ seki = $i
@ seki *= $j
printf "%3d" $seki
end
echo ""
end
echo "--|------------------"


617:デフォルトの名無しさん
07/07/04 23:21:45
@を使わないならBourne Shellでやるようにexprを使えば?


618:デフォルトの名無しさん
07/07/04 23:25:05
>>617
Borne shellで書き換えは出来るんですけど
課題としてcshで@を使わないで書き直すように指示されてるんです

619:デフォルトの名無しさん
07/07/04 23:35:33
ばか?

620:デフォルトの名無しさん
07/07/05 00:28:33
しつもん

スイッチのポートとその先のPCのMACをSNMPで対応付けたいのですが、

#!/bin/bash
while [MACアドレスがある限り];do

snmpwalk -c コミュ IP .1.3.6.1.2.1.17.4.3.1.1 >aa
snmpwalk -c コミュ IP .1.3.6.1.2.1.17.4.3.1.2 >bb
snmpwalk -c コミュ IP .1.3.6.1.2.1.17.1.4.1.2 >cc
snmpwalk -c コミュ IP .1.3.6.1.2.1.31.1.1.1.1 >dd

grep MAC aa > mib
grep mibの右側 bb >bridge
grep bridgeの右側 cc >ifindex
grep ifindexの右側 dd >port

paste MAC,port >output.txt
done <mac.txt

みたいなたらい回ししか出来ないんですか?


関係ないけどどうして演算結果を変数に入れるのがあんなに変な形式なんだろう?


621:デフォルトの名無しさん
07/07/05 00:40:18
>>618
#!/bin/csh -f

echo '
@を使わないことに何の意味があるの?'
echo 'あんた馬鹿じゃねーの?'

622:デフォルトの名無しさん
07/07/05 01:02:45
>>618
Bourne Shellでやる「ように」と書いたのが見えませんでしたか?
・cshでも``記法は使えるでしょ?
・exprはBourne Shellの内部コマンドじゃないでしょ?


623:デフォルトの名無しさん
07/07/05 01:37:06
>>620
コマンド置換を山ほどネストすれば一時ファイルはもっと減るんじゃね?
つかこの程度のことにbash使うな
で、変な形式って?


624:デフォルトの名無しさん
07/07/06 00:53:44
文字列+数値(たまに数値の無い行がある)の並んだファイルを置換したいです
○○○1
××××200
△△
□□66

とか並んでるのを、
○○○2
××××201
△△
□□67

みたいに。
sedで左 >file1
sedで右 | sed -e "s/\([0-9][0-9]*\)/&+1/" | bc >file2
paste file1 file2 > file3
で解決かと思ったら、△△の行がbcで勝手に詰められて結果がずれてしまう…
私の頭ではこれ以上思いつきませんでした。助けて


625:デフォルトの名無しさん
07/07/06 00:56:27
awkでいいじゃん。

626:赤帽勉強中
07/08/02 21:45:16
・lftpを使用してファイルアップロードと削除を行う(mirrorは使わない)
・アップロードと削除の対象ファイルはリストから読み込ませる

って機能のスクリプトを作ろうとしているんですけど、
ファイル名をリストから読み込ませてのアップロードと削除がどうやれば良いのか。。。
どなたかlftpに詳しい方、アドバイスを下さいませ。(-∧-;) ナムナム

627:デフォルトの名無しさん
07/08/02 22:19:08
lftp使ったことないのでmanを見てみたが、manの範囲でできる。

実行するコマンドをテキストファイルに羅列して
lftp -f そのファイル

標準出力からコマンドを食わせることができればきれいなんだけどな。

cat <<EOF > commands
user hoge pass
cd hoge
EOF
sed 's!^!put !' < put_file_names >> commands
sed 's!^!del !' < del_file_names >> commands
lftp -f commands

とかそんな感じじゃね?


628:赤帽勉強中
07/08/02 23:10:38
>>627
レスありがとうございます♪おかげで何とかなりそうですよ。
実はmanを見たりググったりしていたんですが何じゃこりゃ?って感じで理解できていませんでした(汗
まだまだ全然勉強が足りませんですね。。。ヾ(´▽`;)ゝアセアセ

629:デフォルトの名無しさん
07/08/03 00:52:33
ふつうrsync

630:デフォルトの名無しさん
07/08/03 12:59:17
ついでなので、ワタシの使っているコマンドライン公開
lftp -u USER,PASS HOST -e 'set ftp:passive-mode 0;set ftp:ssl-allow 0;mirror -Rev' 2>&1

>>629
ftp しか使えない環境でも、rsync って使えますか?


631:デフォルトの名無しさん
07/08/03 14:37:12
>>630
使えません

632:デフォルトの名無しさん
07/08/03 14:49:39
sshオーバーで耐えろ

633:デフォルトの名無しさん
07/08/13 00:26:07
シェルスクリプトでURLのリンク先を開くにはどうしたらいいでしょうか?

634:デフォルトの名無しさん
07/08/13 01:06:27
>>633
汎用的なのは telnet + expect
SSL や TLS を使用しているなら openssl
接続先が http なら wget とか curl とか
ftp なら ftp コマンド

635:デフォルトの名無しさん
07/08/14 04:04:17
UNIXパワーツールの92Pに
PS1='`date "+%D %T"` $PWD $ '
というカスタマイズが紹介されていたんですが
+%D %Tをダブルクォートで囲むのは何故なんでしょうか?

636:デフォルトの名無しさん
07/08/14 08:04:47
>>635
そのPS1への代入の段階で展開させず、PS1に%Dを引き渡すため。
勿論それは、プロンプト表示の段階で展開されることを期待している。

637:デフォルトの名無しさん
07/08/14 16:05:22
>>636
シングルクォートで囲んでいるので、ダブルクォートで囲まなくても
代入の時点ではdateコマンドは実行されないのではないでしょうか?

638:デフォルトの名無しさん
07/08/14 16:19:05
>>637
date +%D %T
と実行してみろ。話はそれからだ。

>>636
それでは"が必要な理由の説明になっていない。

639:デフォルトの名無しさん
07/08/18 22:55:46
>>635
論点とは違うが、

PS1='\d \t \w \$ '

これと大差ない気がする。

640:デフォルトの名無しさん
07/08/20 08:41:29
>>639
それ移植性ある?(PS1に移植性も何もないが、移植性のある.profileとか
一時期凝ってたんで)


641:デフォルトの名無しさん
07/08/21 01:16:48
>>640
移植性というか、依存するのはシェルのバージョンだから、

URLリンク(www.linux.or.jp)

bash なら上の「プロンプト」の項に載っている奴は
少なくとも bash 2.05b 以降で使えるはず。

ついでに bash 3.2.17 の info を確認したら、二つ新しいのがあった。
これには移植性が無いって事だな。w

`\D{FORMAT}'
The FORMAT is passed to `strftime'(3) and the result is inserted
into the prompt string; an empty FORMAT results in a
locale-specific time representation. The braces are required.

`\A'
The time, in 24-hour HH:MM format.

642:デフォルトの名無しさん
07/08/22 01:59:47
echo $
とすると$が出力されるのに
echo $"" や echo $''
とするとなにも出力されなくなるのはどうしてなんでしょうか?

643:デフォルトの名無しさん
07/08/22 02:15:52
>>642
後者は$が変数参照の一部と見做されるから。
抑止するには$を''で囲むか\でエスケープすればいい。

644:デフォルトの名無しさん
07/08/22 02:31:25
>>643
>>後者は$が変数参照の一部と見做されるから。

変数名が空の文字列の変数を参照しようとするってことなんでしょうか?

645:デフォルトの名無しさん
07/08/22 11:25:41
そんなようなもんじゃない?
その割には、そんな変数は定義できないと思ったけど。

646:デフォルトの名無しさん
07/08/22 15:26:44
bash の話だと、 $"" と $'' は特殊な quoting の構文になってる。
zsh にも $'' はあるみたいだね。

647:デフォルトの名無しさん
07/08/28 19:47:15
man hogeの結果に対してgrepをしたい場合、どのように書けばいいのでしょうか?

648:デフォルトの名無しさん
07/08/28 21:41:37
うちのMacではそのまま man man | grep -i optionとかできるんだけど、
これって特殊?


649:デフォルトの名無しさん
07/08/28 21:51:12
>>647
PAGERをcatにしたらどう?

650:デフォルトの名無しさん
07/08/28 22:04:53
>>648
いやそんなことはないと思う
linuxとかでもそうでしょ

んでも、grep前にcol -bとかはさんだほうがモアベターだと思う

651:647
07/08/28 22:18:05
今の環境はUbuntuなんですが
デフォルトの状態でman hoge | grep "文字"
をやるとエラーか文字化けか再フォーマットしてます~というメッセージが出て止まってしまう
みたいです。
言われたとおりPAGERをcatにしてみたら普通の文字はgrepできるようになったんですが、
man ls | grep -i
のように-iの行を見ようとすると

man: コマンドはステータス 13 で終了しました: /usr/bin/zsoelim /tmp/zman9mAoS0 | iconv -c -f EUC-JP -t UTF-8 | /usr/bin/tbl | /usr/bin/nroff -mandoc -Tutf8 | /usr/bin/col -b -p -x | /usr/bin/pager -s

このようなメッセージが出て終了してしまいます。

652:デフォルトの名無しさん
07/08/28 22:47:15
nroff -man manページのtroffソース | grep ...
はどう?


653:デフォルトの名無しさん
07/08/28 23:51:44
grep -e -i

654:647
07/08/29 09:18:30
>>652
実行してみると↓のようなエラーが出てきました。
普通にmanを実行するときちんと表示されるのに、それをリダイレクトしたりすると
文字化けするあたり、どこかがおかしいのだと思います。

653さんのようにやってみたところ日本語の部分が文字化けしてることを
除けばmanの情報をgrepできるようになりました。


655:デフォルトの名無しさん
07/08/29 10:30:44
>>654
grepで、オプション文字列と誤解されそうなキーワード(具体的には-で始まる)を検索する場合は、
-eなどでガードする必要があります。
なんてのは、シェルスクリプトと何にも関係ないマニュアルページを読めば済むことじゃないか。
鼬害だ、このすっとこどっこい。

656:デフォルトの名無しさん
07/08/29 12:51:20
おまいの選択している文字コードがmanファイルの文字コードと
違うんだから最初に LANG= で指定すると幸せになれるかもな。

657:647
07/08/29 15:05:01
>>655
すいません、すっとこどっこいでしたorz

>>656
ja_JP.UTF-8以外に設定するとmanが英語で表示されてしまうみたいです。
この際、英語中心で読むようにしていこうかと思います。



658:デフォルトの名無しさん
07/08/29 17:48:29
そうか。
ちなみに俺は euc.jp の文字コードを使っているので
普通にman manすると文字が化けるが
man -P cat man | grep man
で日本語の所もgrepでけたぞ。

659:デフォルトの名無しさん
07/09/02 21:33:33
bash並にファイル操作が簡単で普通に数値計算できる言語はないものかねえ

660:デフォルトの名無しさん
07/09/02 22:36:05
>>659
具体的にどんなものをイメージしている?
計算部分は別プログラムを呼ぶのじゃダメ?
awkでもperlでも、寧ろいっそ、octaveでも。

661:デフォルトの名無しさん
07/09/05 10:56:27
もう死にそうだからダメ元で助けてくれるえろい人頼ってみる

YYYYMMDDNNNN.hogeというバイナリファイルが山ほどあり、NNNN部分は連番ではなくばらばら
その中身を表示させるコマンドがある。表示内容が

--内容ここから
ヘッダ(ファイルにより行数ランダム)

1 : YYMMDD hhmm filesize
2 : YYMMDD hhmm filesize
--ここまで

YYYYMMDDNNNN.hogeのファイル名をYYMMDD.hhmmにリネームする
awkで頑張ってみたけどヘッダの行数が統一されてないせいでお手上げ
一つ一つ表示させてはcpでリネームしてるんだが死にそう。
空白行の次の行だけをテキストか何かに出力する方法というか書き方って無い?

662:デフォルトの名無しさん
07/09/05 11:20:04
>>661
sed -e '1,/^$d' -e q YYYYMMDDNNNN.hoge

663:デフォルトの名無しさん
07/09/05 11:20:56
訂正

sed -e '1,/^$/d' -e q YYYYMMDDNNNN.hoge

664:デフォルトの名無しさん
07/09/05 11:23:07
>>662-663
thx、やってみる

665:デフォルトの名無しさん
07/09/05 20:10:59
A="a\ta"
echo $A ってすると次のようにメタキャラクタが展開されちゃうんだけど
a[タブ]a
これをecho $A |コマンド で展開せずに使いたいの。

ノーミソたりなくてやり方がさっぱり!おしえてエロい人!
kshつかってます。

666:デフォルトの名無しさん
07/09/05 22:29:17
>>665
echo '$A' | こまんど
ってことか? シェルスクリプト以前の問題だと思うが。

667:デフォルトの名無しさん
07/09/05 22:39:13
>>665
板違い。エロイ人に聞きたいなら。
URLリンク(sakura01.bbspink.com)

668:デフォルトの名無しさん
07/09/05 23:14:51
>>665
sed 's/<tab>/\\t/g'
っていうことをしたいのだろうか


669:デフォルトの名無しさん
07/09/05 23:29:15
echo "${A}"

670:デフォルトの名無しさん
07/09/05 23:56:37
>>668
どうもありがとう!それです!
Winのディレクトリ表記が全部タブに変換されてこまってました。

671:デフォルトの名無しさん
07/09/21 16:39:07
とあるお気に入りのウェブサイトで、アドレスは一定のまま、
不定期に交換される画像(例えば URLリンク(www.example.com) ) を
毎日定時にチェックし、変更があったらそれをダウンロードし、
ファイル名にその日の日付を加えて保存する、という処理をさせたいです。
どのように書けばいいんでしょうか?

672:デフォルトの名無しさん
07/09/21 17:06:57
>>671
curl -I --header 'If-Modified-Since: Fri, 21 Sep 2007 09:00:00 GMT' URL

とかやって、HTTPステータスが 304 Not Modified かどうかを見る。



673:デフォルトの名無しさん
07/09/22 14:40:26
欧米エロサイトのサンプル画像取得か?

674:デフォルトの名無しさん
07/09/22 14:49:05
NASAのImage of the Dayとか。


675:デフォルトの名無しさん
07/09/22 17:02:35
>>672
別にHEADする必要なくね?更新確認と取得はHTTPならワンアクションで
できるわけで。

676:デフォルトの名無しさん
07/10/18 22:26:18
質問させてください。
main.shというシェルスクリプトがあり、
main.shの中で、sub.shを実行させています。
sub.shは、5秒くらいで処理が完了します。
その後に、last.shというシェルを実行させたいのですが、
シェルコマンドで、"○○秒待つ"といったコマンドはありますでしょうか。
環境はbashになります。よろしくお願いします。




677:デフォルトの名無しさん
07/10/18 22:33:10
sleep ミリ秒

678:デフォルトの名無しさん
07/10/18 22:35:13
そもそもsub.shは非同期なの?
終わるのを待てばいいだけの話だったりはしないんだよね?


679:デフォルトの名無しさん
07/10/18 22:37:01
>>676
sleep 5

あと、『シェルブリッド』 じゃなくて 『シェルブリット』 だから。
そこは絶対間違えないように。

680:675
07/10/18 22:44:34
>>677-679
ありがとうございます!
>>678
cronに登録したかったので
待つコマンドが無いかと思ってました。



681:デフォルトの名無しさん
07/10/18 22:47:19
ふと思ったんですが、sleepコマンド使うと、
PCのリソースを全て停止してしまうとかあるんでしょうか

682:デフォルトの名無しさん
07/10/18 23:29:41
ない

683:デフォルトの名無しさん
07/10/19 00:19:22
ふと思ったんですが、この方は自分で調べるとかないんでしょうか

sleepなんて基本中の基本じゃん。


684:デフォルトの名無しさん
07/10/19 01:02:09
main.sh
------------
#!/bin/bash
bash sub.sh
bash last.sh
------------

で、いいのではないかと思うのは気のせいか。


685:デフォルトの名無しさん
07/10/19 01:19:02
>>684
たぶん>>678も同じ疑問を持って書いたんだと思う。


686:デフォルトの名無しさん
07/10/19 09:31:43
>>683
sleep というコマンドを知らなかったとき、
この情報に辿り着くために必要な検索単語ってなんだ?

687:デフォルトの名無しさん
07/10/19 13:52:26
シェル 秒 待つ
URLリンク(www.google.co.jp)


688:デフォルトの名無しさん
07/10/20 00:00:31
シェルスクリプトの本くらい立ち読みでいいから流し読みしろよ。

流し読みで覚えられないなら買え。

それやった上でsleepなんぞ知らないって言うなら諦めろ。


689:デフォルトの名無しさん
07/10/20 08:04:10
usleep

690:デフォルトの名無しさん
07/10/20 12:16:49
usleepなんて無いだろw

691:デフォルトの名無しさん
07/10/20 17:44:38
何怒ってんのかね
気に入らなけりゃスルーすればいいのに


692:デフォルトの名無しさん
07/10/20 19:20:58
>>691
オマエモナーw


693:デフォルトの名無しさん
07/10/20 19:52:12
usleepのuがμのつもりだったと理解したときASCIIの世界に生きる人に同情した。


694:デフォルトの名無しさん
07/10/20 20:17:49
おいおい
そこまで意地張ったのになんでnanosleepなんだよ!!
かなり天邪鬼だ

695:デフォルトの名無しさん
07/10/21 22:04:14
>>693
マイクロは uC という表記方法もあるよ

696:デフォルトの名無しさん
07/10/21 23:15:22
>>695
結局それも「字形が似てるから代用」には違いないんでしょ?

697:デフォルトの名無しさん
07/10/21 23:46:50
μなんてDBCSローカルな文字つかって喜んでる椰子キモイ

698:デフォルトの名無しさん
07/10/21 23:50:13
μ(greek small letter mu)ならいいのか

699:デフォルトの名無しさん
07/10/22 10:48:43
技術系だと割と当たり前に使うけどなぁ。usecとかum、uFとか。或いは組み合わせでug/lとかも。

700:デフォルトの名無しさん
07/10/22 14:35:50
それだってu(ユー)にマイクロの意味があるわけじゃないだろ?
あくまでμの代用であることには違いないと思うが。



701:デフォルトの名無しさん
07/10/22 17:57:36
不毛だ

702:デフォルトの名無しさん
07/10/22 22:38:48
習慣

703:デフォルトの名無しさん
07/10/23 00:39:35
bashスクリプト中で
cmd echo "foo-san"
ってやると
echo "foo-san"
foo-san
って感じに、実行されるコマンドの内容が先に表示される関数って、定番なのありますか?
cmd() を echo $*;eval $* にしてみたけど、" とか ' とかの処理が旨くいかない。
DOS の echo on モードみたいのでもいいかも。

704:デフォルトの名無しさん
07/10/23 00:47:46
>>703
set -x

705:デフォルトの名無しさん
07/10/23 00:49:12
echo "." |xargs -t

706:デフォルトの名無しさん
07/10/23 09:52:26
>704
おーなるほど、そういうコマンドがあるのかー。勉強になりました。

>705
ありがとうございます。
でも echo つかうと、ダブルクォーテーションが表示されないのが、ちょっとかな、と。

707:デフォルトの名無しさん
07/10/23 11:10:16
>>706
set -v

708:デフォルトの名無しさん
07/10/24 21:03:29
親フォルダ内でシェルスクリプトを開いて、
Folder1に移動し、ABCを実行する。
1時間おきにプロセスABCがあるかチェックする。
終了したら、親フォルダに移動しFolder2でも同じことをする
というスクリプトを書いたんですけど、
whileのdoで文法エラーが出て困ってます。

#!/bin/sh

for i in 1 2
do
cd Folder$i
nohup ./ABC &

while[$isAlive -eq 1]
do 
sleep 1h
isAlive='ps -ef | grep " ABC " |\
grep -v grep | wc - |'
done

cd ..
done

709:デフォルトの名無しさん
07/10/24 21:18:40
while[$isAlive -eq 1]

while文の文法の一部ではない。
[というコマンドの最後に ] いう引数があるコマンド行(リスト)。
よって空白が必須。



710:708
07/10/24 21:31:41
>>709
whileのところはできました。
ありがとうございます。

今度は、forのdoがおかしいって出ました。
forのなかでwhile制御することってできないんでしょうか?


711:デフォルトの名無しさん
07/10/24 21:41:40
エラーメッセージ書いてー。

'(単一引用符)は`(逆向き単一引用符)の間違いだよな?
wc - |(マイナス、スペース、縦棒) は wc -l(マイナス、エル) の間違い?


712:708
07/10/24 22:21:55
10行目、doが、syntax error
です。って表示されました。

逆向き単一引用符で、wc -lエルです。
失礼しました。

713:708
07/10/24 22:24:03
連投すいません。
エラーは、forじゃなかったです。
whileのところでした。

714:デフォルトの名無しさん
07/10/24 23:01:32
もっかいきっちりコピペしろ

715:デフォルトの名無しさん
07/10/25 00:23:06
俺が同じマシン使ってたらABCという名前で永久に終了しないプログラムを動かしてやる。

716:708
07/10/25 03:03:38
>>714
ごめんなさい。もいっかい書き直します。
これの、whileのdoで文法エラーがでます。

>>715
永久に終了しない・・・作ってほしい

#!/bin/sh


for i in 1 2

do

cd Folder$i

nohup ./ppln &


while[ $isAlive -eq 1 ]

do

sleep 1h

isAlive=`ps -ef | grep " ppln " | grep -v grep | wc -l`

done

cd ..

done

717:デフォルトの名無しさん
07/10/25 04:58:38
>>716
while と [ の間にスペースが足りないのはコピペミスだよね?

最初の while のチェックの時に $isAlive が未定義。
で、 [ コマンドが引数が足りないってエラーを吐く。
だから [ コマンドに与える変数はクォートで括っておくが基本。

while [ "$isAlive" -eq 1 ]

あと pgrep があれば while の処理はもっと簡単に書けるよ。

718:デフォルトの名無しさん
07/10/25 08:21:46
ただ、>>715 がいうように、
既に誰かが同じ名前の無関係なプロセスを走らせていたらどうする?
「永久に」っていう細かいところでただの煽りとか思わずに、本質読み取らなきゃ。

719:708
07/10/25 16:02:00
>>717
ご指摘通りに作り直したら動きました。修正したものを張っときます。

>>718
おっしゃるとおりです。全然見えてませんでした。
実際に、スクリプトの名前を”ABC-sc.sh”としたら、
プロセスの出力が”2”とされてしまい、うまくいきませんでした。
もうちょっと改良について考えたいと思います。
プログラミングとかLinuxは初心者で、まだまだ勉強しないといけないって感じてます。


#!/bin/sh
for i in 1 2
do
cd Folder$i
nohup ./ABC &

sleep 20
isAlive=`ps -ef | grep "ABC" | grep -v grep | wc -l`

echo "$isAlive"
while [ "$isAlive" -eq 1 ]

do
sleep 1h
isAlive=`ps -ef | grep "ABC" | grep -v grep | wc -l`
echo "$isAlive"
done
cd ..
done

720:デフォルトの名無しさん
07/10/26 01:12:26
>>719
$! という変数は知ってる?

nohup ./ABC &
echo "$!" # ← ABC の PID が表示される

これなら >>718 の罠にはかからないよ

721:デフォルトの名無しさん
07/10/26 09:35:42
バックグラウンドで動かす意味なくね?

722:デフォルトの名無しさん
07/10/28 21:40:09
引数に対応した干支を表示するシェルスクリプトを
Bshellで作成したいのですが、作成方法を教えて頂けないでしょうか?

723:デフォルトの名無しさん
07/10/28 22:31:24
eto=`expr ¥( $1 + 8 ¥) % 12`
年は西暦。子年を0にしたかったので8を加えてある。


724:デフォルトの名無しさん
07/10/29 12:33:07
>>719
ps -efではなく、psのフォーマット指定を使えば混乱が減らせると思う。
# >720も手だけど。
ps -efだと、例えば引き数が"ABC"なプロセスでも混乱してしまうよ。

725:デフォルトの名無しさん
07/10/31 01:21:20
>>716
初心者のくせに我輩を煽るとはいい度胸してるな。おととい来やがれ。
度胸に免じて、厨房どもに一つテクを授けてやろう。

kill -0で生存確認しろ。

726:デフォルトの名無しさん
07/12/04 08:34:30
質問お願いします!
適当なファイルを作ってその中には数字を記述しておいて、キーボードからそのファイルを読み込んで、その記述してある数字に+2を行った結果を画面上に出力するというシェルを作りたいのですが、どのようにすればよいか教えていただけませんでしょうか?

readとループ文を使って作りたいんですが自分で調べてもあんまりわかったんでみなさんのお力をお貸しいただけないでしょうか?

727:デフォルトの名無しさん
07/12/04 10:07:29
#!/bin/sh

read num
while `test $num`
do
echo `expr $num + 2`
read num
done

ちょっと違うか。

728:デフォルトの名無しさん
07/12/04 11:34:29
awk使っていいなら凋落。
awk '{print $1 + 2;}' 適当なファイル

729:c
07/12/04 13:14:06
% cat x
100
% cat add2
#!/bin/sh
num=`cat $1`
expr $num + 2
% ./add2 x
102



730:デフォルトの名無しさん
07/12/04 13:18:06
ん? こっちか?
% cat x
100
200
500
% cat add2
#!/bin/sh
exec < "$1"
while read num
do
  expr $num + 2
done
% ./add2 x
102
202
502



731:>>726
07/12/04 14:04:57
>>727 >>728 >>729 >>730
回答サンクスです!
いろいろな考え方ができるのですね。勉強になりました。
ぜんぶやってみたいと思います。助かりました!ありがとうございます。

732:デフォルトの名無しさん
07/12/05 00:36:45
シェルってゆうな。クズ。

733:デフォルトの名無しさん
07/12/06 20:46:08
>>732
やっぱりフルネームで言わなきゃ駄目なのか?

734:デフォルトの名無しさん
07/12/06 21:02:25
まあそれ抜きにしてもアレだろ

735:login:Penguin
07/12/07 18:11:42
午前2時まで、pingを10秒ごとに打ちたいのですが
きれいな書き方おしえてください

736:デフォルトの名無しさん
07/12/07 18:29:03
# crontab
*/10 0-1 * * * ping toTarget

737:デフォルトの名無しさん
07/12/07 18:32:54
いけね、10分ごとにしちまったw おまけにpingが無期限実行だぜ。

つーことで訂正。
# crontab
0 0 * * * ping -i 10 -c 720 toTarget

738:735
07/12/07 18:35:34
>>737さま
ありがとう!

739:デフォルトの名無しさん
07/12/13 10:55:42
既にシェルスクリプトじゃなくてUNIXよろず相談室だな(w

740:デフォルトの名無しさん
07/12/22 18:52:32
Linuxのpasswdみたいにコマンドを打った後に出てくる質問に答えていく場合は
#!/bin/sh

passwd aaaa
pass
pass
とかじゃ無理みたいなのですが、どうすればいいのでしょうか?

741:デフォルトの名無しさん
07/12/22 20:04:22
ホントによろず相談室だなぁ……

>>740
リダイレクトでもしてみたら? passwdコマンドがリダイレクトを受け付けるとも思えないけど知っておいて損はないし。

742:デフォルトの名無しさん
07/12/22 20:19:44
>>740
対話的処理をしたいときは expect

743:デフォルトの名無しさん
07/12/22 21:11:49
>>740
Tclに嫌気が差したら Expect.pm (Perl)

744:740
07/12/23 00:02:58
>>742
で以下のようにしてみたのですが
#!/bin/sh

passwd testid
expect \"*:\"
send "test\n"
expect \"*:\"
send "test\n"

cronのメールで
useradd: user testid exists
New UNIX password: New UNIX password: New UNIX password: passwd: Authentication information cannot be recovered
Changing password for user testid.
aaaa: line 6: expect: command not found
aaaa: line 7: send: command not found
aaaa: line 8: expect: command not found
aaaa: line 9: send: command not found
といわれました。
expectが見つからない・・?何か入れる必要あるんでしょうか?

745:デフォルトの名無しさん
07/12/23 00:32:51
cronから起動されるときのPATHがどうなるかmanで勉強する。

which expectしてみる。
$PATHの値を見てみる。
locate expectしてみる。
パッケージ管理システムを使ってるならそれを使ってインストールされてるか見てみる。(rpm系Linuxのrpm -q expectみたく)
/usr/localや/optなどのそれっぽいディレクトリの下のどこかにあるのかもしれない。

あと、expectの使い方って

expect -c "
...
spawn passwd #パスワードコマンド起動
expect ログイン要求を待つ
send ログイン名
云々
"

じゃなかったっけ?


746:740
07/12/23 14:11:46
>>745
ズバリですね。yum install expectとしたらインストールされていないらしく入れますか?と。
expect -c "
spawn passwd id
expect \":\" ; send ~でできました。
大変参考になりました、ありがとうございます。

747:デフォルトの名無しさん
07/12/29 11:20:36
初心者的な質問で,申し訳ないです。
ヒアドキュメントで変数に代入する方法がわからなくて。

list=<<EOT
A
B
C
EOT
echo $list

としても$listには何も代入されなくって。

748:デフォルトの名無しさん
07/12/29 11:33:39
ヒアドキュメントは、PerlやらRubyやらでは変数への代入に使うけど、
シェルスクリプトでは、コマンドの標準入力をすげ替えるモノじゃないかな。


749:747
07/12/29 12:23:18
>>748
なるほど,標準入力のかわりだったのですか。
ということで

read list <<EOT #--> A

としたらという結果。あともう一歩というところまできました。


750:747
07/12/29 12:38:15
とりあえず
while read line; do list="$list $line";done <<EOS
A
B
C
EOS
echo $list


ん~,改行がなくなってしまう...

751:デフォルトの名無しさん
07/12/29 13:21:26
そりゃぁ、echoすれば改行は消えるね。

752:デフォルトの名無しさん
07/12/30 21:26:09
>>750
ダブルクォートをつけてみな。

echo "$list"


見た目がいまいちかもしれんが、こうやって代入する事もできるよ

list='A
B
C'


753:デフォルトの名無しさん
08/01/01 18:50:43
zshとbashじゃそこの挙動違うんだな

754:デフォルトの名無しさん
08/01/02 15:16:56
シェル初心者ですが
pingして反応が無かったらまたAにGOTOして
というのを書いているつもりなんですが
これをcronで実行させると
A:: not found となります。
GOTOさせる場合の正しい書き方を教えてください

#!/bin/sh
PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin
HOST=192.168.1.6
TIMEOUT=5

A:;
/sbin/ping -t $TIMEOUT -o $HOST
if [ $? != 0 ]; then
goto A;
else
/bin/echo "$HOST is Alive!"
fi


755:デフォルトの名無しさん
08/01/02 16:35:27
あっ、gotoでなくてもいいのか
こうすればいいてことですね

while [ $? != 0 ]
do
/sbin/ping -t $TIMEOUT -o $HOST
done


756:デフォルトの名無しさん
08/01/04 05:20:05
>>755
すでに解決しているようだが、こんな書き方もできる。

until /sbin/ping -t $TIMEOUT -o $HOST
do
:
done

757:デフォルトの名無しさん
08/02/09 17:00:30
自分に渡されたコマンドオプションをそのままほかのコマンドに渡したいのですが
うまくいきません

runruby.shに
cmd=ruby
${cmd}" $@"
と書いて
./runruby -e 'puts "Hello"'を実行すると
ruby: No such file or directory --  -e (LoadError)と言われてしまいます


758:デフォルトの名無しさん
08/02/09 17:11:50
>runruby.shに


>./runruby -e 'puts "Hello"'を実行すると
runruby.shはどこに行った?
それと、そのrunruby.shによるとrubyに" -e"を渡すことになるぞ。

759:757
08/02/09 17:18:29
>>758 申し訳ございません 間違いました
./runruby.sh -e 'puts "Hello"'でした

runruby.shの内容を
cmd=ruby
${cmd} ${@}
にしてみたらエラーメッセージはでなくなったのですがHelloも表示されず終了しましたorz

760:デフォルトの名無しさん
08/02/09 17:22:54
なんで"$@"にしないの?

761:757
08/02/09 17:31:24
>>760
できました!!
ありがとうございます

762:デフォルトの名無しさん
08/02/09 17:33:10
つまり、rubyコマンドはコマンドライン引き数の先頭が空白だとファイル名と看做すってことか。

763:デフォルトの名無しさん
08/02/09 17:39:39
bashでしか試してないけど、、、
${cmd}" $@" -> "ruby\ -e" "puts \"Hello\""
$cmd "$@" -> "ruby" "-e" "puts \"Hello\""
"${cmd} $@" -> "ruby -e" "puts \"Hello\""
"${cmd}" "$@" -> "ruby" "-e" "puts \"Hello\""

"$@" -> "$1" "$2" ...
"str$@" -> "str$1" "$2" ...
"str $@" -> "str $1" "$2" ...
って感じで展開されているのかな?

764:デフォルトの名無しさん
08/02/09 17:42:01
3つ目、
x "${cmd} $@" -> "ruby -e" "puts \"Hello\""
o "${cmd} $@" -> "ruby\ -e" "puts \"Hello\""

765:デフォルトの名無しさん
08/02/09 17:59:05
よく見たら、 "$@" じゃなくて " $@" なのかよ。


766:デフォルトの名無しさん
08/02/11 18:09:03
configureでif test x"$enable_shared" = xyes; thenっていうふうに
xを付け加えて比較してるのをよく見るのですがxはなんのためですか?

767:デフォルトの名無しさん
08/02/11 18:12:40
空文字列のときも大丈夫にするためかな
xつけないとtestで構文エラー出ちゃうでしょ?


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