シェルスクリプト総合 その15at UNIX
シェルスクリプト総合 その15 - 暇つぶし2ch426:名無しさん@お腹いっぱい。
09/09/12 10:24:59
器量良しの意味しか無いと思い込んでた馬鹿が悪い
>>363の事だが

427:名無しさん@お腹いっぱい。
09/09/12 10:25:51
>>423
その補足説明は「器量」という熟語自体の意味の説明にはなっていないよ。
補足説明は「器」と「量」の単漢字の意味の説明だから。
熟語になると意味が変わる。

428:名無しさん@お腹いっぱい。
09/09/12 10:26:30
>>425
器量の狭い小者乙

429:名無しさん@お腹いっぱい。
09/09/12 10:29:29
俺は器量が広く度量があり、そして器量良しの女房がいる。
お前らカスと一緒にすんな。

430:名無しさん@お腹いっぱい。
09/09/12 10:34:47
間違いを認められずに醜態を晒し続ける>>363,>>368,>>377は典型的な小丈夫だな。
スレ違いの話題を振って絡んでおきながら、大外しって惨め過ぎる。

大辞泉
URLリンク(dic.yahoo.co.jp)
しょう-じょうふ【小丈夫】
1 小柄な男。2 器量の狭い人物。小人物。

431:名無しさん@お腹いっぱい。
09/09/12 10:40:12
有識者諸兄殿
シェルスクリプトの勉強中で、教えていただきたい。

①while read AAA ; do ~ ; done < fileX
②for AAA in `cat fileX`; do ~ ; done

の違いを教えて下さい。
処理スピードや処理(do ~ )での柔軟性、fileXが小さい場合と大きい場合での違いなど。

よろしくお願いします。

432:名無しさん@お腹いっぱい。
09/09/12 10:43:09
普段から言葉を大事に使わないからイザとなったら慌てて辞書に頼り表面の意味だけを捉えて赤っ恥をかく。
>>363,368,377がその例だろう。

433:名無しさん@お腹いっぱい。
09/09/12 10:48:44
>>430
だれも「小丈夫」の話なんかしてないよ。的はずれな指摘。

「器量」の項目を引いて出直せ。

434:名無しさん@お腹いっぱい。
09/09/12 10:53:10
>>431
機種依存文字使うな。

whileの方は、1行毎にループ処理される。

forの方は、改行だけでなく、スペース・タブでも区切られて
それぞれに付いてループ処理される。

435:名無しさん@お腹いっぱい。
09/09/12 10:54:20
>>433
>慌てて辞書に頼り表面の意味だけを捉えて
一つ上のレスの意味すら理解できないんだな。
お前につける薬は無いな

436:名無しさん@お腹いっぱい。
09/09/12 10:57:53
>>431
シェルスクリプトスレで訊けよ
ひとこと言うなら、スペースの有無とかfileXの大きさとかより
(1)の do~doneがサブシェルになることが注意

437:名無しさん@お腹いっぱい。
09/09/12 11:02:18
>>368を書いた時点では、器量には容貌という意味しかないと信じ切っていたようだ。惨め過ぎる。

438:名無しさん@お腹いっぱい。
09/09/12 11:02:22
>>436
ダウト。

単なるファイル入力のリダイレクトだから、while read でも
サブシェルにはならない。

サブシェルになるのは、echo hoge | while read みたいな
パイプの場合。

439:名無しさん@お腹いっぱい。
09/09/12 11:03:53
>>437
違うよ。

容貌、才能、面目のすべての意味を知っていたが、
判例を挙げるにはひとつだけで十分だから、
一番意味がはっきり違う容貌を挙げただけ。

440:431
09/09/12 11:10:07
>>434
>>436
>>438

なるほど!
forはfileXの行にスペース・タブ(IFS?)がある場合、行単位にならないのですね。
行単位に処理させたい場合はwhileの方が確実ですね。
勉強になりました。

サブシェルになる場合とその注意点などまだ自分にはピンと来ませんので
ちょっと勉強してみます。

ありがとうございました。


441:名無しさん@お腹いっぱい。
09/09/12 11:11:42
>>439
もう分かったから失せろボケ

442:名無しさん@お腹いっぱい。
09/09/12 11:15:17
>>440
サブシェルで代入したシェル変数は親シェルには伝わらない。

443:名無しさん@お腹いっぱい。
09/09/12 11:26:32
>>434 の正解が出たあとで
間違ったことを書いてる >>436 はマヌケだなぁ。

444:名無しさん@お腹いっぱい。
09/09/12 11:31:23
>>439
残念ながら「狭い」という用法が*無い事*を示すためには、他の例をあげるだけ
では不十分なんだ。*有る*事をしめすなら一つだけ挙げればいいがな。

恥の上塗りまだ続けるのか? 惨め惨め惨め惨め。

445:名無しさん@お腹いっぱい。
09/09/12 11:33:12
いいかげんバカは放置しようよ

446:名無しさん@お腹いっぱい。
09/09/12 11:35:59
>>444
いや、>>360 が、「器量」を「懐」あたりの意味と取り違えていて、
「器量」にはその意味しかないと思い込んでいると思われたので、
その反例として>>368 で「器量」の意味のひとつを挙げた。
反例にはなっている。

447:名無しさん@お腹いっぱい。
09/09/12 11:39:42
>>446
お前が基地害だというのは充分判ったから
もういいだろ。どう足掻いてもお前に勝ち目は無いよ

448:名無しさん@お腹いっぱい。
09/09/12 11:43:59
>>363が責任を取って氏ねば解決

449:名無しさん@お腹いっぱい。
09/09/12 11:44:00
>>447
はためから見ると負けてるのは >>447 の方だがw

450:名無しさん@お腹いっぱい。
09/09/12 11:47:25
「器量が狭い」を認められない器量の狭さワロス

451:名無しさん@お腹いっぱい。
09/09/12 11:48:59
>>450
そういうのは「懐が狭い」って言うんだよ。覚えとけ。

452:名無しさん@お腹いっぱい。
09/09/12 11:49:33
>>445
>>439のような馬鹿は半端に叩くと粘着するから。「器量」を見ただけでPTSD起こす
くらいまで叩いて置かないといけない。

>>446
なってねーよ。馬鹿。たった、「1レスくらいどうってことないだろ。器量が狭いな」だけの
発言から
> 「器量」にはその意味しかないと思い込んでいると思われたので、
このように思うって、お前が馬鹿であるという証明にしかならない。

しかも、*無い*事を示すために他の例を挙げれば済むとか。
どんだけ低脳なんだよ。惨め惨め惨めの三重奏だぜ。

453:名無しさん@お腹いっぱい。
09/09/12 11:51:05
>>451
懐は深い/浅いだよ。覚えとけ。

454:名無しさん@お腹いっぱい。
09/09/12 11:53:51
>>451
恥の上塗り乙

455:名無しさん@お腹いっぱい。
09/09/12 11:55:06
>>453
あほか、
懐が深い/浅いだと意味が違う。反例になってない。

456:名無しさん@お腹いっぱい。
09/09/12 11:58:14
>>455
更に恥の上塗り乙

457:名無しさん@お腹いっぱい。
09/09/12 12:02:24
一般的に、>>454 >>456 みたいに「恥の上塗り」とかだけ書いて
具体的な反論を書かなくなった方が議論の負けなんだよ。

458:名無しさん@お腹いっぱい。
09/09/12 12:04:25
>>457
そのルールだとファビョったほうの勝ちか?
お前のように(笑)

459:名無しさん@お腹いっぱい。
09/09/12 12:20:17
まだ続くのか日本語講座

460:名無しさん@お腹いっぱい。
09/09/12 13:19:30
自作自演飽きた。

461:名無しさん@お腹いっぱい。
09/09/12 13:47:48
自演だと思うのは自分が自演してるからだ。

462:名無しさん@お腹いっぱい。
09/09/12 13:56:20
全部おれの自演でした

463:名無しさん@お腹いっぱい。
09/09/12 13:59:07
>>457が吊れば平和
とっとと逝け

464:名無しさん@お腹いっぱい。
09/09/12 14:12:22
>>438
Solarisの/bin/shだとファイルリダイレクトでもサブシェルになる。


465:名無しさん@お腹いっぱい。
09/09/12 14:22:06
>>464
「サブシェルになる」ことをどうやって確認した?

まさか、while read AAA の、ループを抜けた時、
AAAの内容が空になるのを見て「サブシェルだ」と思ってないだろな。

readは最後に EOF を読み込んで while を抜けるから、
ループを抜けた時 AAA は空になるが、サブシェルではない。

while read AAA
do
BBB=$AAA
done < file

echo $BBB

で試してみろ。

466:名無しさん@お腹いっぱい。
09/09/12 14:22:49
SunOS4 当時の /bin/sh はどう振舞うの?

467:名無しさん@お腹いっぱい。
09/09/12 14:34:53
>>465
試したけど Solarisの /bin/shだとやっぱりサブシェルだよ。

468:名無しさん@お腹いっぱい。
09/09/12 23:49:07
自信満々でダウトしといて外してるって恥ずかしくない? どんな気持ち?
>>363とか>>363とか>>363とか>>363とか>>438

469:名無しさん@お腹いっぱい。
09/09/13 01:00:33
シェルスクリプトの実行者に対しy/n等で確認を求めたい場合
通常readで止めて入力を促しているのですが
while read のループの中でそれをやろうとすると上手くいきません。

while read ~
echo "Y or N"
read YESNO ←ここで止まってくれない
~判定処理~
done < fileHoge


whileのreadと入力要求のreadが干渉しているのが原因のように思っています。
よい方法はありますでしょうか?
(ddやselectなども試しましたがダメでした)

470:名無しさん@お腹いっぱい。
09/09/13 01:03:39
read YESNO < /dev/tty
かな?

471:名無しさん@お腹いっぱい。
09/09/13 01:08:19
ありがとう
それやってみます!

472:名無しさん@お腹いっぱい。
09/09/13 17:59:13
よく 
commandA | tee LOGFILE
などのやり方で表示しつつログをとる事があると思いますが
commandAの終了ステータスを判断したい時、この場合だと$?がteeの結果になり
commandAの終了ステータスが分りません

bashなら環境変数${PIPESTATUS[パイプライン中のコマンド位置]}
で取れることを調べられたのですが、あいにく改造母体のファイルはkshなんです。

よい方法はありますでしょうか?



473:名無しさん@お腹いっぱい。
09/09/13 18:04:42
>>472

((commandA; echo $? 1>&3) | tee LOGFILE ) 3>&1

474:472
09/09/13 18:22:57
>>473
ありがとうございます!
明日試してみます!

475:名無しさん@お腹いっぱい。
09/09/13 19:39:39
>>473
この書き方すぐ忘れるんで、そんな時はcsh-whynotでググるんだ

476:名無しさん@お腹いっぱい。
09/09/13 20:03:38
csh(笑)

477:名無しさん@お腹いっぱい。
09/09/13 21:17:24
csh-whynotを知らずにcshを笑うとは…
爆笑だぜ。

478:名無しさん@お腹いっぱい。
09/09/14 08:13:40
ここだけ20世紀

479:名無しさん@お腹いっぱい。
09/09/20 15:13:01
コマンドの引数に別のコマンド実行結果を利用する時
commandA `commandB`
とやりますが、さらにその実行結果をコマンドの引数に利用したい場合、
変数にcommandA `commandB`を入れてcommandC $変数 などとやってるのですが、
変数を使わずに出来る手法はありますでしょうか。
イメージ的には「commandC `commandA `commandB``」みたいな感じ。


480:名無しさん@お腹いっぱい。
09/09/20 15:17:56
commandC $(commandA $(commandB))

純正シェルの人は苦行に耐えて頑張ってください。

481:名無しさん@お腹いっぱい。
09/09/20 15:34:01
commandC `commandA ¥`commandB¥``

482:名無しさん@お腹いっぱい。
09/09/20 15:40:06
>>480-481

ありがとう!試してみます!


483:名無しさん@お腹いっぱい。
09/09/20 18:46:17
あるフォルダの中の*.cというファイルを~/srcというフォルダにコピーするにはどうすればいいですかね?


484:名無しさん@お腹いっぱい。
09/09/20 18:47:47
スクリプト使わない質問はスレ違い

485:483
09/09/20 18:49:13
申し訳ありませんでした。。

486:名無しさん@お腹いっぱい。
09/09/20 18:56:39
cp *.c ~/src/

487:名無しさん@お腹いっぱい。
09/09/20 19:01:09
>>486
説明不足でした。。
いくつかの階層に分かれていたのでできなかったのです。
情報後出しとか氏んどけって話ですよね。。

mv `find -name *.c` ~/src/

上のレスみて何とかなりました
もう本当にスレ汚し失礼しました。

488:名無しさん@お腹いっぱい。
09/09/20 19:01:22
>>486
やってみましたが、どうもホームフォルダの下の/srcにコピーされるようです。
?/srcというフォルダにコピーしたいんですが。

489:名無しさん@お腹いっぱい。
09/09/20 19:14:59
>>487
それだと同じ名前ぶつかってると上書きされるぞ。

490:名無しさん@お腹いっぱい。
09/09/20 20:11:24
スクリプトの中で使う場合って~と$HOMEってどっちが一般的なんですか?

491:名無しさん@お腹いっぱい。
09/09/20 20:25:00
もちろん $HOME
チルダは純正では使えない

492:名無しさん@お腹いっぱい。
09/09/20 20:46:49
bash又はkshで長さが一定でないファイル名からある位置の文字を取り出したい。
具体的にはhogehoge~XX.txtのXXの2文字。後ろから5,6文字目。
前からの位置であればcutで簡単だったのだが後ろからで行き詰った。
考えた挙句、echo ファイル名 | wc -c等で長さを取って、
それをexprで6減算した値をcutの開始位置にしてやったりして出来たのだが
たかが2文字取り出すだけなのにスマートじゃない。
もっとシンプルに行かないものでしょうか?

493:名無しさん@お腹いっぱい。
09/09/20 21:00:31
>>492
expr 'hogehoge~XX.txt' : '.*¥(..¥).txt'

494:名無しさん@お腹いっぱい。
09/09/20 21:16:12
>>493

ありがとう今度やってみます
でもちょっと難しくて今時点でなんで期待の結果が得れるか把握しきれてないです。
exprのそういった使い方を勉強します。


495:名無しさん@お腹いっぱい。
09/09/20 23:18:27
revは環境依存?


496:名無しさん@お腹いっぱい。
09/09/21 10:57:39
>>492
fにファイル名が入っているとして
a=${f#${f%??.txt}}
echo ${a%.txt}
ではどうか。

497:名無しさん@お腹いっぱい。
09/09/21 13:03:33
bashでいいなら、
↓で一発じゃん (fileにファイル名が入っているとして)

echo ${file:$((${#file}-6)):2}

498:名無しさん@お腹いっぱい。
09/09/21 14:38:10
対話的なスクリプトが二つあって
それをスクリプト同士対話させたいのですが
どのように相手の出力をもう片方の入力につなげるのでしょうか?

499:名無しさん@お腹いっぱい。
09/09/21 14:40:43
>>498
fifo

500:名無しさん@お腹いっぱい。
09/09/21 14:46:33
>>5
> シェルの対話的な利用についての話やスクリプトと関係ないコマンドの
> 使い方の質問などはスレ違いなので無用に願います。

501:名無しさん@お腹いっぱい。
09/09/21 15:07:30
>>498
双頭バイブ

502:492
09/09/26 20:45:00
>>493
>>496
>>497

全て上手くできました。
ありがとう。
>>493のやつはshでもOKですね。


503:名無しさん@お腹いっぱい。
09/09/27 00:28:00
スクリプトの中で他ユーザにしか実行権の無い別のスクリプトを実行するため、
su - USER -c COMMAND
としたいのですが、パスワードを求められます。
今時点ではパスワード入力をスクリプトの実行者に入力させてますが
このパスワード入力をスクリプトの中で自動で出来る方法はありますか?
ご教授お願いします。

504:名無しさん@お腹いっぱい。
09/09/27 01:43:06
>>503
sudoかexpect

505:名無しさん@お腹いっぱい。
09/09/28 01:37:41
バッククォートで実行するコマンドの標準出力と標準エラーをそれぞれ
別の変数に入れることってできますか?

やりたいことは以下と等価なんだけど、一時ファイルを作らずにやりたいんです。
stdout=`command 2>stderr.tmp`
stderr=`cat stderr.tmp`


506:名無しさん@お腹いっぱい。
09/09/28 23:10:05
>>504

すみません、Solarisなので両方とも使えませんでした。


507:名無しさん@お腹いっぱい。
09/09/29 00:48:13
Solaris なら pfexec を使うのかな

URLリンク(www.itmedia.co.jp)

508:名無しさん@お腹いっぱい。
09/09/29 21:59:35
>>506
Solarisでsudoもexpectも使えないなんてことを書いてしまうとは・・・
ろくに調べもしないでコマンド入れ替えただけとしか思えん。


509:名無しさん@お腹いっぱい。
09/09/29 22:17:54
混ぜ物を一切していない純血Solaris

510:名無しさん@お腹いっぱい。
09/10/01 21:34:47
あるコマンドの標準出力を一行ずつ見ていって、それがある正規表現Xにマッチしてたら
コマンドAの標準入力にいれて、その標準出力を取得、それ以外なら、コマンドBの
標準入力に入れて、その標準出力を取得、その2つの標準出力を、標準入力の
順番と同じ順番でそろえて出力を得たいのですが、方法はありますでしょうか?

わかる方いたら教えていただけませんでしょうか。よろしくお願いいたします。。。

511:名無しさん@お腹いっぱい。
09/10/01 22:00:58
>>510


#!/bin/sh

while IFS= read line
do
if echo "$line" | grep -q XXX
then
a=`echo "$line" | command_A`
echo "$a"
else
a=`echo "$line" | command_B`
echo "$a"
fi
done

512:名無しさん@お腹いっぱい。
09/10/01 22:40:13
>>511
ありがとうございます。
でもこれだと、command_A、command_Bは毎入力行ごとに起動しなおすことに
なりませんでしょうか。
command_A, command_Bともに入力に応じて、内部で状態が変化するので、
ずっと起動しっぱなしにしたいのですが、そういうことはできますか?

513:名無しさん@お腹いっぱい。
09/10/01 22:43:20
後出し乙。

ハイ、次の方どうぞ


514:名無しさん@お腹いっぱい。
09/10/01 22:51:19
>>510

#!/bin/sh

(
(
while IFS= read line
do
if echo "$line" | grep -q XXX
then
echo "$line"
else
echo "$line" 1>&3
fi
done | command_A 1>&4
) 3>&1 | command_B
) 4>&1

515:名無しさん@お腹いっぱい。
09/10/01 23:03:55
command_A, command_Bに確実に一行ずつ出力させる事が出来なければ不可能。

516:名無しさん@お腹いっぱい。
09/10/01 23:18:02
>>514
素早い回答、ありがとうございます。
ファイルディスクリプタんの複製なんて、10年振りに見ました。
このスレは初探訪なのですが、スレ住人の方々はみな、このような
スクリプトを自在に操る変態さんばかりなのでしょうか。
まだまだ精進が足りないと痛切に思いました。
自在にこんなスクリプトが書けるまで、精進したいと思います....

ところで、この"grep -q" って、入力毎に起動しているようですが、
これはずっと起動しっぱなしに比べて、パフォーマンス的にはどうなんでしょう。
実はgrepのこういう多数回の起動(fork())ってそんなに大変なことではない??

517:名無しさん@お腹いっぱい。
09/10/01 23:24:12
>>515
うーむ、さきにcommand_Aの方が処理された後に、command_Bの方が
実行されるみたいですね。やっぱり無理かなぁ。

518:名無しさん@お腹いっぱい。
09/10/01 23:24:43
>>516
正規表現じゃなくて、単なるパターンマッチで良ければ、
grep -q の代わりに case文を使えば、
内部コマンドだけになるから速くなるよ。

519:名無しさん@お腹いっぱい。
09/10/02 01:29:03
シェルスクリプトを、別のシェルスクリプトの中からをバックグラウンドで実行すると
SIGINTが無視されてしまうんだけど、何とかSIGINTをトラップできる
ようにする方法ありませんか?

例えば以下のようなシェルスクリプト command.sh を作って、
#!/bin/sh
trap 'echo sigint' INT
trap -p

インタラクティブなシェルから command.sh & すれば期待通り動くんですが、
別のシェルスクリプトの中から command.sh & で呼び出すと SIGINT のハンドラが
設定されないんです。

この動作自体は一応 bsh 系の仕様っぽいですが…
Linux 上の bash 限定でも良いので、何か解決法があったら教えてください。


520:名無しさん@お腹いっぱい。
09/10/02 06:45:21
>>519
シェルスクリプトの中から、

sh -c 'set -m; command.sh &'

で呼び出す。

521:名無しさん@お腹いっぱい。
09/10/03 09:28:17
>>481のやり方ってネストは2個まで?

commandD `commandC \`commandA \`commandB\`\``
でやったら上手くいかなかったような。。。(bash)

522:名無しさん@お腹いっぱい。
09/10/03 09:42:57
あたりまえ。\もエスケープしなければダメ。

523:名無しさん@お腹いっぱい。
09/10/03 09:46:57
>521

commandD `commandC ¥`commandA ¥¥¥`commandB¥¥¥`¥``


524:名無しさん@お腹いっぱい。
09/10/03 09:48:20
>>521
3個でもできるよ。

commandD `commandC ¥`commandB ¥¥¥`commandA¥¥¥`¥``

525:名無しさん@お腹いっぱい。
09/10/03 09:50:21
>>522-523
お、言われて見ればその通りだ。
ありがとぅ。

526:名無しさん@お腹いっぱい。
09/10/03 09:51:31
>>524
ありがとぅ。


527:名無しさん@お腹いっぱい。
09/10/04 17:20:27
時々シェルスクリプトで簡単なツールを作ったりしてるのですが
perlを勉強してみたくなりました。

>>1
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。

とありますが、具体的にどのような観点でシェルスクリプトとperlを使い分けするのでしょうか?
このような処理ケースではperlを使う方が効果的みたいな例を教授
(もしくはそのような事が記載されているサイトに誘導)していただけたら幸いです。


528:名無しさん@お腹いっぱい。
09/10/04 17:26:53
現状でシェルスクリプトで問題なくやってるなら、
perlなんて覚えない方がいい。

529:527
09/10/04 17:27:13
少し調べてみてるのですがPerlは文字列処理等が得意であるというのを見ますが、
そうするとsedやawkを使う場面なんかがperlでやった方がよりよいでしょうか?

530:527
09/10/04 17:34:22
>>528

現状、何とか目的の機能は達成してるって感じですが、
同じ事がperlなら断然簡潔かつ高速処理で出来たりするのかな?なんて思うもので。。。

531:名無しさん@お腹いっぱい。
09/10/04 17:47:06
3項演算子は両方とも評価するのか?

532:名無しさん@お腹いっぱい。
09/10/04 18:05:40
>>529
例えば一行の処理毎に、シェルスクリプトでは外部コマンドを起動する必要がある、
perlでは不要。というような場合、データが大きくなればperlの方が速くなる。

533:529
09/10/04 18:31:28
>>532

それはテキストの一行に対して処理する事に対し、シェルスクリプトならその行数分外部コマンドが実行、
つまりシェルスクリプトでテキストの1行に1コマンド処理実行させてる場合、
100行なら100回外部コマンドが実行される事になるが
perlなら1コマンド?で処理が終了するので大きいテキストに対してだと
処理スピードに差がでるって事でしょうか?

534:名無しさん@お腹いっぱい。
09/10/04 18:45:38
テキストの一行じゃないんじゃないの。sedもawkも複数行を処理できるでしょ。
あとマルチコアプロセッサとかだと、プロセスが分かれていた方が処理が早く
終わったりもするね。

キッチンシンクアプローチとツールボックスアプローチを調べてみると良いと思うよ。

535:名無しさん@お腹いっぱい。
09/10/04 18:58:02
>>533
そう。プロセスの生成は非常にハイコスト。

536:529
09/10/04 19:12:23
>>534-535
ありがとう。
うーん、でも完全に理解し切れてない。
何かを実現させる時、シェルスクリプトの場合複数のコマンド発行(プロセス起動)が
perlなら少プロセスで可能な場合(主にテキスト処理などで)があるって事でしょうか?

>キッチンシンクアプローチとツールボックスアプローチを調べてみると良いと思うよ。

調べてみます。

537:名無しさん@お腹いっぱい。
09/10/05 00:38:28
python

538:名無しさん@お腹いっぱい。
09/10/05 02:27:03
オライリーのミニマルPerlって本があって、
sh&sed&awk の粗探しをして Perl への移行を薦めるような内容なんだが、
これ読むと逆に、とくに大規模でもないテキスト処理なら
シェルで無問題じゃんって感じなんだよね。
Perlが受けたのは、第一に実装が優秀で速かったのと、
あと Perl はベル研系の厳格な雰囲気がないというか、
何となく書いて動いちゃうとこがある。そのへんの寛容さが人気の秘密かと

539:名無しさん@お腹いっぱい。
09/10/05 15:57:27
結局適材適所と、それを判断出来る能力の問題だと思うよ。
シェルスクリプトで遅いなら、perlなりでやる。それでも遅いならCとか。


540:名無しさん@お腹いっぱい。
09/10/05 18:06:14
echoで最後に改行したくない場合、
echo -n "unko"
では期待通りに出力されるのですが、
echo "unko\c"
だとunko\cと改行して出力されてしまいます。
Cygwinで\cに対応させるにはどうしたらよいでしょうか。
よろしくお願いいたします。

541:名無しさん@お腹いっぱい。
09/10/05 18:15:13
>>541
CygwinということはGNU coreutilsのechoか。
-e オプション?


542:540
09/10/05 19:05:48
>>541
おおお、ありがとうございます。
$ echo -e "unko\c"
で期待通り
unko$
と出力ができました。

本番の環境はHP-UXを使用しておりまして、
逆に-eオプションが無い(?)ため、
$ echo -e "unko\c"
とした場合、
-e unko$
と出力されてしまいすが、とりあえず、
alias echo='echo -e'
で解決いたしました。

ありがとうございました!!!!

543:名無しさん@お腹いっぱい。
09/10/05 21:56:31
そのへんの移植性に関するバッドノウハウはGNU autotoolsに詰まってる。

544:名無しさん@お腹いっぱい。
09/10/21 12:16:25
RCSで、チェックイン済みの最新リビジョンと、そのひとつ前のリビジョンを比較
ということをよくやります。
今は、rlog -r fileで最新リビジョン番号を調べて、たとえば 1.123 だったとすると、
頭の中でリビジョンを1引いて、rcsdiff -r -r1.122 file みたいに実行しています。
これを1発でやるシェルはできませんか?

あ、sed/awk等でゴニョゴニョやる方法じゃなく(それしかないなら自分でやるので)、
奇麗にエレガントにやる方法を希望します。

545:名無しさん@お腹いっぱい。
09/10/21 18:10:19
よく知らないで申し訳ないが
current=`rlog -r file | grep 'なんとか'`
current=`expr $current - 0.001`
rcsdiff -r -$current file
空白とか改行とか考慮せずかなり適当に書いたけど。

exprでできないならbc使えばできるかもしれない。

546:名無しさん@お腹いっぱい。
09/10/21 18:32:38
それはエレガントじゃないらしいよ

547:名無しさん@お腹いっぱい。
09/10/21 20:25:10
シェルってゆうな。クズ。

548:名無しさん@お腹いっぱい。
09/10/21 22:12:01
エレガントさが求められていたのか
知らんかったよ、すまん

549:名無しさん@お腹いっぱい。
09/10/21 22:41:49
奇麗でエレガントな質問を募集します。

550:名無しさん@お腹いっぱい。
09/10/24 13:10:57
>>545
エレガント云々を除いてもそれじゃ駄目だよ。
リビジョン番号は、 1.8 1.9 1.10 1.11 ... 1.99 1.100 1.101 ...
って進むから、expr で 0.001 引くのは全然見当違い。

551:名無しさん@お腹いっぱい。
09/10/26 22:08:08
どうしてもわからないので質問させてください。

#!/bin/sh

DIR=`pwd`

cd $DIR/file
./play


のようにC言語で記述したplayファイルを実行しているのですが
play内では簡単に表すと以下のような処理をしています

while(true){
ファイルの読み込み処理
sleep(1);
}

このように1秒ごとにファイルを監視してるのですが
シェルスクリプトで実行すると1秒待たずにwhileループが回っているのですが
どうすればよいのでしょうか?

552:名無しさん@お腹いっぱい。
09/10/26 22:13:23
>>551
そのwhileループの具体的なスクリプトを出さずに質問したいなら、
エスパースレに池。

sleepコマンド自体が文法またはオプションエラーになってて
1秒待ててないんじゃないの?

553:名無しさん@お腹いっぱい。
09/10/26 22:15:27
問題点を人に伝える能力が欠けすぎ

554:名無しさん@お腹いっぱい。
09/10/26 22:17:39
>>552
whileループはC言語で書いてるんだろ。(プログラムは出てるじゃん)

コマンドラインで直接 ./play を実行すると1秒毎に処理されるのに、
>>551 のシェルスクリプト経由で ./play を実行すると1秒待たずにループする、
という話だろ。

555:名無しさん@お腹いっぱい。
09/10/26 22:20:28
で、答えは?

556:名無しさん@お腹いっぱい。
09/10/26 22:20:58
>>551
sleep()関数はシグナルで中断される可能性がある。
シグナルが到着すればsleep(1)は1秒未満で終了する。
代わりにnanosleep()使え。

たぶん、シェルスクリプト経由の時だけシグナルが発生するような
別の条件が加わってるんだろ。

557:名無しさん@お腹いっぱい。
09/10/26 22:36:54
>>551
play コマンド側は特に何もせずシェルスクリプト側で sleep 1; すればいいんじゃね?


558:名無しさん@お腹いっぱい。
09/10/26 22:58:35
>>556
ありがとうございます。
試してみましたが同じ状態になりました。

説明が不足していてすみません
GNU Chessを改造していたので、その部分のコードを切り抜いても分かりづらいので自分なりに説明したのですが、説明力がなくてすみません。

ファイルの読み込み部分の処理は

while(true){
sleep(1);
if(rlogfp=fopen("./black.log","r")){
fgets(inp, MAXSTR, rlogfp);
fclose(rlogfp);
remove("./black.log");
break;
}
}


black.logというのは次の手を指定した文字列が収められているファイルです。
C言語で書くのもうまくないので下手なコードですが、ご了承ください。

559:名無しさん@お腹いっぱい。
09/10/26 23:01:09
>>557
whileで監視しているのでsleep(1)がないとファイル作成時に読み込みが実行されるのか、うまくデータが受け取れないので
sleep(1)を追加している次第です。

560:名無しさん@お腹いっぱい。
09/10/26 23:39:32
後からこんなことを追加するのはすみませんが

どうやら監視しているファイルが存在しないのに、ファイルがあるように動いているみたいで、
ファイル読み込む→whileを抜け出す→間違った手だと解釈→whileに入りファイルを読み込む
を繰り返すようになっているみたいです。
シェルスクリプトではなくターム上で実行するとうまくいくのに
スクリプトだとこの現象がおこるのはどういったわけでしょうか?

561:名無しさん@お腹いっぱい。
09/10/26 23:56:55
>>560
シェルスクリプトの cd $DIR/file あたりがうまく行ってないとか。
別のディレクトリの black.logを読んでループしてるとか。

562:名無しさん@お腹いっぱい。
09/10/27 00:11:19
>>561 レスありがとうございます
他のディレクトリではblack.logは生成していないのでそのケースはないかと思います
ディレクトリの場所も間違いはないです

563:名無しさん@お腹いっぱい。
09/10/27 00:23:15
sleepはループの先頭なの?それなら確実に1秒待つでしょ?
説明に一貫性がないと回答者も混乱するし、いいことないよ。
あとは、fgets, fclose, removeの戻り値をちゃんとチェックしてみる。

564:名無しさん@お腹いっぱい。
09/10/27 00:30:07
ぱおーん

ってそれはエレファント

565:名無しさん@お腹いっぱい。
09/10/27 00:40:24
>>551
>シェルスクリプトで実行すると1秒待たずにwhileループが回っている

これはどうやって確認したの?

原因を切り分ける為に、問題を再現出来る最小限の
プログラムを作ってみると良いと思うよ。

566:名無しさん@お腹いっぱい。
09/10/27 00:46:46
>>563,565
アドバイス通り明日調べてみます。


567:名無しさん@お腹いっぱい。
09/10/27 08:05:15
>>559
> whileで監視しているのでsleep(1)がないと
> ファイル作成時に読み込みが実行されるのか、
> うまくデータが受け取れないので

busy waitになるだけでちゃんと動くはずだろ。
だから動かないのは、sleep()以外のところがおかしい。



568:名無しさん@お腹いっぱい。
09/10/27 11:08:26
そのファイル、NFS かなんかの領域に置いてないか?
おかしなキャッシュが効いてるような気がする。

569:名無しさん@お腹いっぱい。
09/10/27 11:38:40
>>568
特に変わった場所には置いてません。

とりあえずthreadやwhileループとファイルの読み込みの部分だけ同じ形でtestファイルを作ってみたのですが
直接実行、シェルスクリプトで実行で共に問題がなかったので、もっと別の場所だと分かりました。
もう少し試行錯誤してみたいと思います。

570:名無しさん@お腹いっぱい。
09/10/27 12:26:31
ちょっと説明が長くなるのでアップロードしてみました。
お手数をおかけしてもうしわけありません。
DLkey:unix

URLリンク(www1.axfc.net)

571:名無しさん@お腹いっぱい。
09/10/27 13:04:39
input_threadが動き出す前にwait_for_inputに入ると、
input_statusが初期値(INPUT_NONE)のままなので、whileを抜けてしまう。

572:名無しさん@お腹いっぱい。
09/10/27 21:14:09
test が表示されないという現象はウチでは一度も再現しませんでした。
Dual Core の Mac です。

外してたらスマソ。

test.sh を実行する
Ctrl-C で test.sh を止める
a.out のプロセスは残ったまま

とかじゃないよね?

まあそれでも test が表示されない理由にはなりませんけど。

573:名無しさん@お腹いっぱい。
09/10/27 21:50:45
一度目がその症状があって
もう一度試したら治っていました

>>571
どのように記述すれば回避できるのでしょうか?
丸投げのようですみません^^;

574:名無しさん@お腹いっぱい。
09/10/28 00:03:20
以前動作していたスクリプトが動かなくなってしまいました…
ここ最近kshのアップデートを行ったのが原因なのでしょうか…

何か情報をお持ちの方いらっしゃいましたらご教授願います。

<事象>
特に問題なく見えるkshがsyntax Error `(' unexpectedで異常終了
コメント内のスペースを1つ削除or2つ追加すると正常に動作する

<やったこと>
kshとbashのアップデート
ksh 20060214-1.4 → 20080202-14.el5
bash bash3.1-16.1 → bash3.2-21.el5

<環境>
redhat Linux 5.1
uname -a結果
Linuc 2.6.18-53.el5 #1 SMP Wed Oct 10 16:34:19 EDT 2007 x86_64 x86_64 x86_64 GNU/Linux

<備考>
ksh -nで構文チェックをかけると、構文エラー以外に「" quote may be missing」という警告が必ずついてきます。
コメントを弄ってエラーを抑止するとこの警告も発生しなくなります。

575:551
09/10/28 00:05:16
. play.shで実行したらうまく動きました。
結局原因はわかりませんでしたが、サブシェルだと何か環境とちがったのかな?と素人ながら思います。
お騒がせしてすみませんでした。

576:名無しさん@お腹いっぱい。
09/10/28 00:59:40
それたまたまだから

577:名無しさん@お腹いっぱい。
09/10/28 01:16:52
while(true)なんてしないで、openの返り値でなんとかならんの?

578:名無しさん@お腹いっぱい。
09/10/28 07:06:37
>>574
おいおい、redhat 5.1というのは10年くらい前のOSで、
カーネルは2.0の時代のもの。(libc5からやっとglibc2に変わった時代)
カーネル2.6で動くわけがない。

579:574
09/10/28 11:18:44
>>578
今確認したところ、redhat 5.1ではなく
RHEL 5.1でした

redhatLINUXとRHELを混同していました
申し訳ありません


580:名無しさん@お腹いっぱい。
09/10/28 11:43:19
>>574
スクリプト晒せ

581:名無しさん@お腹いっぱい。
09/10/28 11:44:15
libc5なつかしいな。
glibc2(libc6)になってようやくLANG関係がマトモになったんだっけ

582:名無しさん@お腹いっぱい。
09/10/28 11:44:22
どうせShift_JISのコメントだろ。

583:574
09/10/28 23:54:47
>>580
手元にスクリプトがない上に動く動かないの条件がよく分からないので再現できず…
申し訳ないです。

>>582
コメント等もう一度文字コードを見直しましたが、すべてUTF-8でした。

584:名無しさん@お腹いっぱい。
09/10/28 23:56:51
手元にスクリプトがないのにコメント等見直した?意味が分からんのだが

585:名無しさん@お腹いっぱい。
09/10/28 23:57:32
不思議な話だなw

586:名無しさん@お腹いっぱい。
09/10/29 22:50:29
LOTO6用の数字列を生成する

for x in $(seq 1 5); do echo $(seq 1 43 | shuf | head -6 | sort -n); done


587:名無しさん@お腹いっぱい。
09/10/30 23:17:20
>>586
for((i=0;i++<5;)){ echo `shuf -i 1-43 -n 6 | sort`; }

↑の方が簡単

588:名無しさん@お腹いっぱい。
09/11/10 09:10:20
質問です。記法1と2では違いがありますか?どちらが正しいとか…
doの後に改行入れるべきかどうなのか,ということですが。

記法1
for i in *
do
echo $i
done

記法2
for i in *
do \
echo $i
done


589:名無しさん@お腹いっぱい。
09/11/10 09:48:42
>>588
記法2は間違いではないがバックスラッシュが余分。
もともと do の直後には、空白、タブまたは改行の区切り文字があればなんでも良い。
「行の継続」をする必要はないので、バックスラッシュは不要。

590:588
09/11/10 11:02:41
>>589
ありがとうございました。

591:名無しさん@お腹いっぱい。
09/11/10 11:33:58
今のトレンドは↓の書き方。
bash依存じゃないぞ。純正シェルでもちゃんと動くから安心して使え。

for i in *
{
echo $i
}

592:名無しさん@お腹いっぱい。
09/11/10 11:37:50
どこのトレンドだよwwwww

593:名無しさん@お腹いっぱい。
09/11/10 11:43:46
for は { ... } でもいいけど、
while は do ... done じゃないといかんというのがアレ。


594:名無しさん@お腹いっぱい。
09/11/12 08:07:11
kshで標準出力と標準エラーをデフォルトでファイル&画面に出力するやり方はありますか?
毎行、| tee -a hoge.log を書くのが大変なので。

595:名無しさん@お腹いっぱい。
09/11/12 08:19:07
>>594

(
command1
command2
command3
:

) 2>&1 | tee -a hoge.log

596:名無しさん@お腹いっぱい。
09/11/12 08:41:02
>>594
scriptコマンドは?

597:名無しさん@お腹いっぱい。
09/11/12 08:58:07
俺はそういうとき
telnet localhost | tee hoge.log
ってやってる

598:名無しさん@お腹いっぱい。
09/11/12 09:27:34
正解(>>595)が出た後にボケ回答(>>596-597)が出てくる、の法則

599:名無しさん@お腹いっぱい。
09/11/13 19:18:09
自分よりいい答えが出たのがそんなに悔しかったのか

600:名無しさん@お腹いっぱい。
09/11/13 19:57:03
> 毎行、| tee -a hoge.log を書くのが大変なので。
毎行と言っているし、ここはシェルスクリプトスレなのでスクリプトの中での記述に
関しての質問だと言う事が容易に予想できる。

スクリプトに関しての質問にscript使えだの、telnetをリダイレクトしろだの、
ボケまくりの回答してる奴らは何なのだろう?
匿名掲示板だからボケ回答も恥ずかしくないのだろうか?

601:名無しさん@お腹いっぱい。
09/11/14 03:03:51
必死だなw

602:名無しさん@お腹いっぱい。
09/11/20 10:11:52
>>599
只の知ったかだろ
半角数字とか学生の分際で早くも理系気取りかよ

603:名無しさん@お腹いっぱい。
09/11/20 10:44:29
>>602
日本語で頼むわ……

604:名無しさん@お腹いっぱい。
09/11/20 20:00:12
> 半角数字とか学生の分際で早くも理系気取りかよ

これは新コピペになりそうな気がする

605:名無しさん@お腹いっぱい。
09/11/21 01:23:51
>>604
新コピペとか学生の分際で早くも理系気取りかよ
…こんな感じ?

606:名無しさん@お腹いっぱい。
09/11/21 02:02:27
bashを使用しています。
数字が入っている変数に3桁毎にカンマを入れる方法が分かりません。
どうやれば3桁毎にカンマを入れれるようになりますか?

607:名無しさん@お腹いっぱい。
09/11/21 12:27:50
>>606
printf "%'d" "$var"

608:名無しさん@お腹いっぱい。
09/11/21 22:05:46
>>607
これはいいことを聞いたと、試してみたができないぞ?
$ bash --version
GNU bash, version 4.0.28(2)-release (i686-pc-linux-gnu)

609:名無しさん@お腹いっぱい。
09/11/21 22:13:00
>>608
varの中にちゃんと数字入れてるか?

610:名無しさん@お腹いっぱい。
09/11/21 22:17:56
>>607 では printfの書式に改行が入ってないから、
シェルのプロンプト設定によってはprintfの出力をプロンプトが上書きしてしまう
とエスパー。

それとは別に、zshの内蔵printfでは動作しないね。

611:606
09/11/21 23:23:18
>>607さん
有難うございました。ウチの環境ではうまくいきました。

612:名無しさん@お腹いっぱい。
09/11/22 14:57:44
$ printf "%'d\n" "123456"
123456
$ var="12345667"
$ printf "%'d\n" "$var"
12345667

なにがいけないのかねー

613:名無しさん@お腹いっぱい。
09/11/22 17:20:06
$ printf "%aqd\n" "123456"

614:名無しさん@お腹いっぱい。
09/11/22 17:29:35
>>612
localeの設定じゃない?
printf(3)によると、

>>printf("%'.2f", 1234567.89);
>>results in '1234567.89' in the POSIX locale, in '1234567,89' in the nl_NL locale,
>>and in '1.234.567,89' in the da_DK locale.

615:名無しさん@お腹いっぱい。
09/11/23 00:52:46
>>614
ロケールの問題でした。ありがとう。
ちょっと気になるのは、printfコマンドする時に
LC_ALLを明示的に与えても上手く動作しなかったんですよね
組み込みコマンドだと伝わらないのかな?

$ locale
LANG=ja_JP.eucJP
LC_CTYPE="ja_JP.eucJP"
LC_NUMERIC=C
LC_TIME=C
LC_COLLATE="ja_JP.eucJP"
LC_MONETARY="ja_JP.eucJP"
LC_MESSAGES=C
LC_PAPER="ja_JP.eucJP"
LC_NAME="ja_JP.eucJP"
LC_ADDRESS="ja_JP.eucJP"
LC_TELEPHONE="ja_JP.eucJP"
LC_MEASUREMENT="ja_JP.eucJP"
LC_IDENTIFICATION="ja_JP.eucJP"
LC_ALL=
$ LC_ALL=da_DK printf "%'d\n" "123456789"
123456789
$ LC_ALL=da_DK bash
$ locale
LANG=ja_JP.eucJP
LC_CTYPE="da_DK"
(省略)
LC_ALL=da_DK
$ printf "%'d\n" "123456789"
123.456.789

616:名無しさん@お腹いっぱい。
09/11/23 06:55:47
$ printf "%'d" "123456789"
printf: %': invalid directive

617:名無しさん@お腹いっぱい。
09/11/23 13:08:26
>>615
>>$ LC_ALL=da_DK printf "%'d\n" "123456789"

LC_ALL を LC_NUMERIC にしてもダメ?

618:名無しさん@お腹いっぱい。
09/11/23 15:32:07
(優先される)強さは、
強 LC_ALL > LC_個別 > LANG 弱
のはずだから、LC_ALL があってダメなら LC_NUMERIC でもダメな希ガス。



619:名無しさん@お腹いっぱい。
09/11/23 15:44:54
>>617
ダメでした。
というかlocale(7)に書いてあるロケールの決定順序を見る限り
$ LC_ALL=da_DK printf "%'d\n" "123456789"
で動かなければ、LC_NUMERICを使っても同じなのではないかと。

ところで、
$ LC_ALL=da_DK locale
の結果は$ LC_ALL=da_DK bashで作ったシェル上でlocaleした
(参考>>615の2個目のlocale)のと同じ結果になります。
(つまりLC_ALLも、LC_NUMERICもda_DK)

その癖に、
$ LC_ALL=da_DK printf "%s\n" "$LC_NUMERIC" と
$ LC_ALL=da_DK echo "$LC_NUMERIC" はどちらも「C」が出力
(参考>>615の1個目のlocale)になるんですよね。LC_ALLはもちろん、改行のみです。
環境変数の伝わり方が変ですよね?

つまり、
localeだとLC_ALL(もしくはLC_NUMERIC)がexportされてて、
printfとechoはexportされない。

それと、
>>615で「組み込みコマンドだと・・・」といいましたが、
$ type -a echo したら、builtinと/bin/echoの2つのエントリがあったので、
どちらも試してみましたが、exportされませんでした。
どういうメカニズムでこうなっちゃうんでしょう。

620:名無しさん@お腹いっぱい。
09/11/23 15:54:16
>>618 とレスが一部被ってしまった

連レスですみませんが、
コマンドの前に環境変数定義をつけるシンタックスって
なんという名前で呼ばれていますか?

そもそもどういうものなのかを調べたいのですが、ググりづらくて。

621:名無しさん@お腹いっぱい。
09/11/23 16:04:31
>>620
shじゃなくてbashのマニュアルで申し訳ないが、
A simple command is a sequence of optional variable assignments
followed by blank-separated words and redirections, and terminated
by a control operator.
だそうな。
optional variable assignments (省略可能な変数代入)


622:608,612,615,619
09/11/23 18:22:28
>>621 ありがとう。man bash読みました。
組み込みコマンドでの、optional variable assignmentの挙動についてまとめてみました。

COMMAND EXECUTION ENVIRONMENT節に以下の記述があります。
When a simple command other than a builtin or shell function is to be
executed, it is invoked in a separate execution environment

つまり組み込みコマンドはseparate execution environmentで呼び出されない。
これは当たり前のことで、組み込みコマンドは別シェルで実行されないということですよね。
そして個人的に新たに知ったのは、optional variable assignmentは別シェルにしか
伝えられないということです。(現在のシェル変数には代入されない)
だから、>>615で $ LC_ALL=da_DK printf "%'d\n" "123456789"
がコンマ区切りにならなかったんですね。

だったら、敢えてシェル変数を伝えられた実行環境を作って、printfするとどうなるか。
#include <stdlib.h>
int main()
{
 system("printf \"%s\n\" \"$LC_NUMERIC\"");
 system("printf \"%'d\n\" \"123456789\"");
 return 0;
}
をコンパイルしたa.outに対して試してみました。
(a.outは組み込みコマンドではないので別シェルで実行され、
optional variable assignmentが伝えられる)

623:608,612,615,619,622
09/11/23 18:25:17
$ ./a.out
C
123456789
$ LC_NUMERIC=da_DK ./a.out
da_DK
123.456.789
$ LC_ALL=da_DK ./a.out
C
123.456.789
となりました。

>>615の後半のようにLC_ALL=da_DK bashで環境作ってからやる方が楽なので、
本末転倒になりましたが。。。


ところで、これで興味深いのは、LC_ALLはLC_NUMERICに影響を及ぼさないことです。
>>615では LC_ALL=da_DK bash 後にlocaleすると、LC_ALL=LC_NUMERIC=da_DKになりますが、
bashの初期化処理でLC_ALLの値をLC_NUMERICにコピーしているのかも?


最後に。619の訂正。
SIMPLE COMMAND EXPANSIONの節の 4.にあるように、
parameter expansionされてからコマンドが実行されるようなので、
$ LC_NUMERIC=da_DK printf "%s\n" "$LC_NUMERIC"
はコマンドが実行される前に引数の$LC_NUMERICが「C」(参考>>615)と展開される。
そのため、Cが表示される。


長文失礼しました。

624:名無しさん@お腹いっぱい。
09/11/23 18:52:34
組み込みコマンドがseparate execution environmentで呼び出されないのは
bashの場合の話。

kshでは組み込みコマンドでもseparate execution environmentで動作する。

625:名無しさん@お腹いっぱい。
09/11/23 19:12:34
やはり、sh系といえども、何を使っているかは明示すべきなんだな。


626:名無しさん@お腹いっぱい。
09/11/23 19:17:36
確かにその通りですね。
上は全部>>608の環境で試してた。

627:名無しさん@お腹いっぱい。
09/11/26 14:47:50
"aa-1125.txt" "aa-0001.txt"
"aa bb-1125.txt" "aa bb-0001.txt"
"aa bb cc-1125.txt" "aa bb cc-0001.txt"
同じディレクトリにこの6ファイルがあるとします。
この中から「aa bb-????.txt」の形式で且つ最も新しいファイルを
探したいんですが、
(当然のことですが)ls -ltr "aa bb-????.txt"|tail -1とやるとエラーになってしまいます。
どうすればいいでしょうか?シェルはbashです。

628:名無しさん@お腹いっぱい。
09/11/26 15:01:32
ls -ltr (ここに6個のファイル名を羅列)|tail -1

629:名無しさん@お腹いっぱい。
09/11/26 15:01:41
ls -lt aa\ bb-????.txt | head -1

630:名無しさん@お腹いっぱい。
09/11/26 15:14:14
bbの無いファイルもあるぞ

631:名無しさん@お腹いっぱい。
09/11/26 15:28:45
あるよ
だから?

632:名無しさん@お腹いっぱい。
09/11/26 15:49:56
申し遅れましたが、
実際にはファイル数、ハイフンより前の部分のファイル名は不定です。
>>627は単純化した例です。
>>627の時点で知りたかったことは自動でエスケイプする方法もしくはそのコマンドです。

633:名無しさん@お腹いっぱい。
09/11/26 16:00:11
一体何がしたいんだよ
何とマッチさせたいんだ?

634:名無しさん@お腹いっぱい。
09/11/26 16:07:04
>>627の下から2行めをエスケイプしたものが
>>629なわけですが、(実質的に)
そのようなことをスクリプト内で自動でおこないたいということです。
sed,awkを使うのかなと思いますが、インタラクティブだと[tab]キーを押すと
できるようなことなので、bash内部でも出来ないかなとも思います。

635:名無しさん@お腹いっぱい。
09/11/26 16:13:40
ハイフンより前にスペースが含まれていようがいまいが
*-????.txt で>>627の6ファイル全てにマッチするんだけど
それで何か困るのか

636:名無しさん@お腹いっぱい。
09/11/26 17:03:15
unix超ど素人です。
本を参照しても見つからないので、
質問させてください。
ちなみにここで推奨されてないcshを使っています。

例えば80.0というように小数点がある数字を
80といった整数に書き直すスクリプトをつくりたいのですが、
うまくいきません。

#!/bin/csh
set y_info = 80.0
echo int($y_info) > aaa.dat
どうすれば解決できますでしょうか?

637:名無しさん@お腹いっぱい。
09/11/26 17:23:05
解決の第一歩は、cshを捨てる事だ。

638:名無しさん@お腹いっぱい。
09/11/26 17:24:52
>>627
スペースだけをクォートすればいい。シングルクォートの方がお勧め

ls -ltr ??' '??-????.txt | tail -1

639:名無しさん@お腹いっぱい。
09/11/26 17:30:24
>>636
cshは捨てさせていただくので、shでどうぞ。

#!/bin/sh
y_info=80.0
printf '%.0f¥n' $y_info

640:名無しさん@お腹いっぱい。
09/11/26 20:10:12
>>636
cshなら拡張子を削る機能が組み込まれてるので、
悪くないチョイスだよ

#!/bin/csh
set y_info=80.0
echo $y_inf:r > aaa.dat

なんと :r を付けるだけで小数点以下を削れるんだぜ

641:名無しさん@お腹いっぱい。
09/11/26 20:11:11
echo $y_info:r > aaa.dat
のミス

642:名無しさん@お腹いっぱい。
09/11/26 20:13:04
あと、csh スクリプトは
#!/bin/csh -f
にした方がなにかと幸せ

643:名無しさん@お腹いっぱい。
09/11/26 20:30:51
>>640
それだと、 .5 みたいに頭の 0が省略されてる小数で誤動作する。

644:名無しさん@お腹いっぱい。
09/11/26 20:34:08
>>640
(数値じゃなく)拡張子とみなして削る方式なら shでもできる。

#!/bin/sh
y_info=80.0
echo ${y_info%.*}


csh(笑)の出番なし。

645:636
09/11/26 21:13:03
>>640
うまくいきました
トンクス

他の方もレスありがとうございます

シミュレーションで得られたデータを出力する際にスクリプトを使用しています。
周りがcsh使ってたので、それを使ってましたが、
shの方が問題点が少なそうなので、
そっちにシフトしてみようと思います。




646:名無しさん@お腹いっぱい。
09/11/26 21:16:33
半導体屋か? あいつら何でcsh好きなんだ?

647:名無しさん@お腹いっぱい。
09/11/26 21:19:13
>>640 だと四捨五入されない。>>639 がお勧め。

648:名無しさん@お腹いっぱい。
09/11/28 11:45:22
以前にcshで作って、それですんでりゃそうなるだろう。

649:名無しさん@お腹いっぱい。
09/11/28 12:14:17
tcsh以外に便利なインタラクティブシェルがなかった時代の負債といえようか

650:名無しさん@お腹いっぱい。
09/11/28 12:33:23
ちょっとしたスクリプトの場合、cshの方が書きやすい場合もある。
四則演算が出来るとか配列が使えるとか、要はケースバイケース

651:名無しさん@お腹いっぱい。
09/11/28 12:38:06
>>650
四則演算も配列も、今時のsh(系)でできる。

652:名無しさん@お腹いっぱい。
09/11/28 12:46:50
ケースバイケースでcshスクリプトなんて混ぜられちゃ迷惑だ

653:名無しさん@お腹いっぱい。
09/11/28 13:18:36
コピペで数千行を超えるのcshスクリプト作るんだぜ。
ちょっとしたを遥かに超越している。

654:名無しさん@お腹いっぱい。
09/11/28 13:23:31
実績があります、とか言ったりなんかしちゃったりして

655:名無しさん@お腹いっぱい。
09/11/28 17:21:38
UNIXド素人です。
手詰り状態なのでアドバイス頂けると幸いです。

◆処理内容
 Aディレクトリから、Bディレクトリにファイルをコピーする。
 (コピーオプション:-p -f)

◆コピー条件
 Bディレクトリのファイルの更新時間とAディレクトリのファイルの
 更新時間が異なる場合。

◆その他
 更新時間が異ならない場合は、エラーとし、1を戻り値とする。

上記のようなスクリプトを作成したいのですが
どのような処理にしたらよろしいのでしょうか?




656:名無しさん@お腹いっぱい。
09/11/28 18:05:43
書いてあるとおりに処理しよう

657:655
09/11/28 18:21:04
すいません。。
意味わからない質問になっていました。。

やり方がわからない処理は「更新時間を比較する」点です。
お互いの更新時間を変数に入れ、同じ場合と違う場合で処理を決めれば
いいことはわかるのですが、更新時間を比較することなどできるので
しょうか?

658:名無しさん@お腹いっぱい。
09/11/28 18:23:44
>>655
要点だけ書くよ。

if [ "$file1" -nt "$file2" ]; then
cp -pf "$file1" "$file2"
fi

659:655
09/11/28 18:43:33
>>658

ありがとうございます。
ファイルが更新された場合、サイズや更新時間で比較するしかないと思われるのですが
更新時間や、ファイルの詳細?を変数に格納することは可能なのでしょうか?

660:名無しさん@お腹いっぱい。
09/11/28 18:47:33
>>659
md5sumとかでハッシュ値を見たら?

661:名無しさん@お腹いっぱい。
09/11/28 18:54:17
>>659
せっかく回答もらってるのに意味をちゃんと理解しろよ。

[ A -nt B ]
ってやったら、これで更新時間を比較してるんだよ。
別に更新時間を変数に入れる必要なんかない。

-nt は、"newer than" ね。

662:655
09/11/28 19:16:35
>>658 >>661

そういうことですね!!
ファイルの更新時間ではなく、ファイル自体を比較すればいいのですね!!

理解力が無く、ご迷惑おかけいたしました・・・
アドバイスを参考にスクリプトを作成してみたいと思います。
ありがとうございました。

663:名無しさん@お腹いっぱい。
09/11/28 19:19:11
>>662
違うよ。

ファイル自体なんて比較してない。
更新時間を比較してるの。

if [ fileA -nt fileB ]; then ...

ってやると、fileA と fileBの更新時刻を比較して、
その結果で動作が決まるんだよ。
fileA/fileBの中身は読んでない。

664:名無しさん@お腹いっぱい。
09/11/28 19:23:46
URLリンク(hashinfo.com)

665:名無しさん@お腹いっぱい。
09/11/28 19:28:45
md5sumとかハッシュとか言ってる回答者の言うことはここでは無視しとけ。
単純にシェルスクリプトから [ ] (testコマンド)で時刻比較できるんだから。

666:名無しさん@お腹いっぱい。
09/11/28 19:33:06
>>662は日本語読解力からしてダメだな。

667:名無しさん@お腹いっぱい。
09/11/28 19:36:34
更新時刻が異なる場合、なのに、newer than だけでいいんだろうか

668:655
09/11/28 19:36:40
>>663

少し調べてみましたところ、ファイルのタイムスタンプ、つまり更新時間
を比較しているのですね。

ファイルの比較には -nt -ot の2種類があるようですが
"="や"!="で比較することは無理と理解してよろしいのでしょうか?

669:名無しさん@お腹いっぱい。
09/11/28 19:42:39
>>667
だから>>658 は「要点だけ」って言ってるんだよ。

せっかく >>668 が -nt と -ot を調べたんだから、
それを -o すれば 時刻の "!=" を条件を記述できることに気づくはず。

670:名無しさん@お腹いっぱい。
09/11/28 21:50:23
>>668
> ファイルの比較には -nt -ot の2種類があるようですが

>>663を読み直せ…



671:名無しさん@お腹いっぱい。
09/11/28 22:22:24
rsync 使え、で終わる気がする

672:名無しさん@お腹いっぱい。
09/11/29 00:01:55
>>668
> "="や"!="で比較することは無理と理解してよろしいのでしょうか?
そう考えていいよ。「異なる場合」って言ってるんだから、
「「新しい場合」または「古い場合」」
っていう条件が必要なんでしょ?
それぞれ>>663の書式を使って-ntと-otでできるよ。君の言うとおりだよ。
あとは二つをつなぐ「または」を調べてみてごらん。>>669もそう言ってるけどね。

>>671 俺もそう思う。

673:655
09/11/29 00:32:15
>>672

if [ FILE1 -nt FILE2 -o FILE1 -ot FILE2 ] ; then
cp -p -f …
exit 0
else
exit 1
fi
とすればいいのですね!

>>658 >>663 そこまで読み取ることができず、ご迷惑おかけいたしました。。


674:名無しさん@お腹いっぱい。
09/12/04 21:09:44
$ echo "URLリンク(aaa.kp)" | sed -e 's@//*@/@g' -e 's@http:/@URLリンク(@g)<)

一応目的の動作は達成しているのですが、sedがマヌケです。


もうちょっと素敵な方法はありますか?

675:名無しさん@お腹いっぱい。
09/12/04 21:32:24
>>674
echo 'URLリンク(aaa.kp)'

676:名無しさん@お腹いっぱい。
09/12/05 00:35:32
sed -e 's@\([^:]\)//*@\1/@g'

677:名無しさん@お腹いっぱい。
09/12/05 00:49:25
マジキチ

678:名無しさん@お腹いっぱい。
09/12/05 19:23:28
複雑多数のサブディレクトリを持つディレクトリAを複製したい
但し、いくつかのサブディレクトリについては複製対象外としたい。
現状以下のようにやってます。
cp -rp A B
rm -rf B/a/b/c
rm -rf B/bb/aa/cc
・・・消したい対象分ひたすら羅列。

サブディレクトリ内のサイズが大きく、cp,rmで余計な時間が掛かってしまいます。
AをBとして複製する場合に、「このサブディレクトリ以外すべてコピー」
またいな記述方法はありますでしょうか?
sh,bashでお願いします。

679:名無しさん@お腹いっぱい。
09/12/05 19:40:24
cd A
tar cf - . --exclude a/b/c --exclude bb/aa/cc | tar xf - -C /path/to/B

680:名無しさん@お腹いっぱい。
09/12/05 19:49:17
>>679

なるほど、tarのアーカイブファイルを経由させるのですね。
ありがとう。やってみます。

681:名無しさん@お腹いっぱい。
09/12/05 22:18:32
find . -print |egrep -f exlude-pattern-file |cpio -pumd destdir

さらに、コピーでなくてハードリンクで済ませられるなら、高速、省スペース。
find . -print |egrep -f exlude-pattern-file |cpio -pumdl destdir

682:名無しさん@お腹いっぱい。
09/12/05 23:09:18
ありがとう。一考してみます。

683:名無しさん@お腹いっぱい。
09/12/06 23:26:04

>>676
規制で書けかなった。ありがとう。

684:名無しさん@お腹いっぱい。
09/12/10 10:18:03
findの判別式を単独のファイルに適用して、真偽値だけほしいんだけど
どうしたらいい?

685:名無しさん@お腹いっぱい。
09/12/10 10:27:52
例えば

[ -n "`find /path/to/file -mtime 7 ...`" ]

みたいな感じか?

686:名無しさん@お腹いっぱい。
09/12/10 10:34:08
いや、

find /path/to/file -mtime 7 2> /dev/null; echo $?

だろ。

687:名無しさん@お腹いっぱい。
09/12/10 10:39:11
ファイルが正常に処理されれば、判定結果にかかわらず戻り値はいつも0だよ

688:名無しさん@お腹いっぱい。
09/12/10 10:42:01
>>686
マッチしてもしなくても$?は0なのよ

>>685
なるほど文字列の長さを見るのか
とりあえずこれでやってみるわ超サンクス

689:名無しさん@お腹いっぱい。
09/12/10 19:44:25
他サーバ上のtar.gzファイルを解凍する方法はないでしょうか?

690:名無しさん@お腹いっぱい。
09/12/10 20:28:24
sshとか可能なら普通に解凍できるから、そうじゃない質問だとして、
エスパー募集だな

691:名無しさん@お腹いっぱい。
09/12/10 20:55:52
>>690
たとえばftpで他サーバに接続して、gzip -cd | tar xvf -
のようなことはできないでしょうか?

692:名無しさん@お腹いっぱい。
09/12/10 20:59:06
>>691

wget fURLリンク(user:pass@)他サーバ/path/to/hoge.tar.gz -O - | tar zxvf -

693:名無しさん@お腹いっぱい。
09/12/10 21:08:14
>>692
ありがとうございます。
ちょっと試してみます。

694:名無しさん@お腹いっぱい。
09/12/12 13:37:48
URLリンク(v6shell.org)
にてるような、変わっているような。

695:名無しさん@お腹いっぱい。
09/12/20 13:17:58
すみません、スクリプト内で使用されている変数について教えてください。
使用しているOSはCentOS5.3です。

今、勉強がてら/etc/init.d/functionsを読んでいるのですが、
functions内で使用されている変数$LSBの意味がわかりません。

使用例 :[ "$BOOTUP" = "verbose" -a -z "${LSB:-}" ] のように記述されています。

例えば、上記例の$BOOTUPは、/etc/sysconfig/init内で定義されているのを確認できました。
しかし$LSBは/etc/sysconfigや、/etc内のファイルをざっと検索してみても大本の定義が発見できません。
setにもenvにもありません。

$LSBは、意味ありげに見えるだけで、単になんでもない、普通の変数なんでしょうか?
それとも、ちゃんとどこかで定義されているんでしょうか?
もしかしたら、変数ではなく別のものなんでしょうか?

しょうもない質問で申し訳ありませんが、ご教授ください。よろしくお願いします。

696:名無しさん@お腹いっぱい。
09/12/20 14:00:20
教授はあげません。

697:名無しさん@お腹いっぱい。
09/12/20 14:33:04
Linux Standard Base準拠なら定義しておく、ってやつかな?



698:名無しさん@お腹いっぱい。
09/12/20 15:05:57
「ご教授」で正しいんだよ。

699:名無しさん@お腹いっぱい。
09/12/20 15:28:33
そして、それに対する>>696の返しは絶妙だったな。

700:名無しさん@お腹いっぱい。
09/12/20 15:42:03
いや、正しくない。
「教授する」というのは体系だててきちんと教えるという意味なので、
どこの馬の骨かわからない匿名掲示板の単発質問者には「教授」しない。

701:名無しさん@お腹いっぱい。
09/12/20 15:53:37
>>700
だから「体系だててきちんと教え」てください、って >>695 が言ってるんだから
言葉として正しいじゃん。

それに対して、>>696 は「教授する」自体が間違いだと勘違いして
恥を晒しちゃったね。

702:名無しさん@お腹いっぱい。
09/12/20 16:04:02
恥を晒してる奴がいると思うとすかさず飛びつく奴って流石だよな。
楽しい休日の午後のひとときって感じ。

703:名無しさん@お腹いっぱい。
09/12/20 17:18:06
>>701
メクラ? >>695のどこに「体系だててきちんと教えてください」と書いてあるんだ?
揚げ足とったつもりが恥晒して惨め過ぎ。

704:名無しさん@お腹いっぱい。
09/12/20 17:51:05
>>695
定義してない可能性があるから:-なんやで!

705:名無しさん@お腹いっぱい。
09/12/20 18:08:34
>>703
「ご教授ください」=「体系だててきちんと教えてください」(同値)

>>695 には「ご教授ください」と書いてある、
イコール
>>695 は「体系だててきちんと教えてください」と言っている

706:名無しさん@お腹いっぱい。
09/12/20 18:46:44
けんかをやめて~
ふたりをとめて~
わたし~の~ために~
あらそ~わない~で
もう こ~れ~い~じょ~う~♪

707:名無しさん@お腹いっぱい。
09/12/20 18:50:49
じゃあ体系だてて回答してやれ

708:名無しさん@お腹いっぱい。
09/12/20 19:44:15
695です。皆さまなんだかお騒がせしてすみませんでした。
>>697 >>704
ありがとうございます、Linux Standard Baseですか。規格だとしか捉えていなかったので、
関係あるとは想像もしていませんでした。

$BOOTUP=verboseだとold-style bootupらしいので、
加えてLinux Standard Base準拠でないことを確認したいとかなんでしょうかね。

Linux Standard Baseのページには、
「個々のライブラリのインターフェースの装備、および、、各インターフェースに関連したデータ構造・定数を規定しています」
とあったので、どこかで何か定義されているんでしょうね。以下のページを見つけたのですが探しきれませんでした。

URLリンク(dev.linux-foundation.org)

実体がわからないのは残念ですが、私自身が納得できたので、先に進むことができそうです。
皆さま、本当にありがとうございました!

709:名無しさん@お腹いっぱい。
09/12/20 21:01:27
${LSB:-}

:- ってどういう意味?だれか教えて。

#一瞬 :-) かと思ったけど違ったので :-p

710:名無しさん@お腹いっぱい。
09/12/20 21:03:54
・・・と書いておいてなんだけど、man bashに書いてあった

${parameter:-word}
デフォルトの値を使います。 parameter が設定されていないか空文 字
列であれば、 word を展開したものに置換されます。そうでなければ、
parameter の値に置換されます。

へー。しらなかった。

711:名無しさん@お腹いっぱい。
09/12/20 21:06:40
:-)

712:名無しさん@お腹いっぱい。
09/12/20 23:43:43
>>705
バカメ。「ご教授ください」と「体系だててきちんと教えてください」は同値だが、
>>695は誤用だから同値じゃ無いという指摘だ。

論理的思考の出来ないバカは恥を晒すだけだから引っ込んでろ。

713:名無しさん@お腹いっぱい。
09/12/20 23:58:55
日曜日最後のレスがそれじゃあな…

714:名無しさん@お腹いっぱい。
09/12/21 00:50:09
ご教示ください
とすればおkだったような予感w

715:名無しさん@お腹いっぱい。
09/12/21 02:38:22
>>714
ご教授くださいだろ、バーカ!
こんな展開だと予想

716:名無しさん@お腹いっぱい。
09/12/21 07:41:23
>>712
そうじゃなくて、
あくまで誤用であって、「ご教授する」という言葉は日本語として正しい、
というのが主張。
(誤用だけど、言葉自体は正しいの)


ところが、>>696 曰く、
>教授はあげません。

という突っ込みは、「ご教授する」という言葉自体も間違っていると
思い込んでいる。

もし、「誤用」に対する突っ込みなら、
「(こんな掲示版では)ご教授はできません」
となるはずで、
「教授はあげません」みたいには言わないはず。

よって、
>>696 は、「ご教授する」という言葉自体を知らなかったという天で
恥を晒したんだよ。

717:名無しさん@お腹いっぱい。
09/12/21 11:12:52
なにそれこわい

718:名無しさん@お腹いっぱい。
09/12/21 13:14:13
うわ、まだ続けてるのかよ

719:名無しさん@お腹いっぱい。
09/12/21 18:25:12
>>716
アホ丸出しの言い訳止めろ。>>695の用法も正しいと言うのがお前の主張(>>705)。
>>696はオレじゃないが、誤用に対して「あげない」とからかっている。
お前は用法を知らずに揚げ足とったつもりで恥を晒したうえに、小学生並みの見苦
しい言い逃れを続けている単なるバカ。お前の負け。

>>705
> 「ご教授ください」=「体系だててきちんと教えてください」(同値)
> >>695 には「ご教授ください」と書いてある、
> イコール
> >>695 は「体系だててきちんと教えてください」と言っている


720:名無しさん@お腹いっぱい。
09/12/21 19:46:10
関係ない話はくだらないからやめようぜ。
>>695の質問の本質はLSBはどんな意味をもつ変数なの?ってことだろ
LSBについてまともに答えてるの>>697くらいじゃねーか

721:名無しさん@お腹いっぱい。
09/12/21 20:31:51
レスありがとうございます
と書くだけでスレが荒れるのと同じだな

722:名無しさん@お腹いっぱい。
09/12/21 21:02:19
>>721
FreeBSDって何???

723:名無しさん@お腹いっぱい。
09/12/21 22:46:41
>>722
URLリンク(www.freebsd.org)

荒したいならスペースが足らぬわ

724:名無しさん@お腹いっぱい。
09/12/23 17:35:56
cshについて質問させてください
変数の中身が文字列か数字か判断して処理をしたいのですがどうやったらわかりますか?
if ($1 == [0-9]*)
こんな感じでいけるのかなっておもったけどうまくいかずで…

725:名無しさん@お腹いっぱい。
09/12/23 17:40:30
回答が欲しいなら「ご教授ください」って書かないと誰も答えないよ。

726:名無しさん@お腹いっぱい。
09/12/23 19:16:51
パイプラインについて質問です.
% ls
foo.txt bar.txt baz.txt
の状態で,
% ls | wc -l
とやると3が返ってきます.
これは,パイプラインを通すとlsの結果に改行が挿入されるということなのでしょうか?
% ls | xargs echo | wc -l
とすると1が返ってくるので,この結果の違いが不思議です.

727:名無しさん@お腹いっぱい。
09/12/23 19:24:28
まずは ls | cat して確かめてみなさい

一応、はまりそうなので正解を言っておくと、ls が、出力先がパイプか端末かを
調べて、出力を変えています。パイプが変えてるのではありません。

728:名無しさん@お腹いっぱい。
09/12/23 19:26:27
724です。
是非ともご教授いただきたいです。
よろしくお願いいたします。

729:名無しさん@お腹いっぱい。
09/12/23 20:19:56
>>724
先頭が数字かどうかなら 
 if ( $1 =~ [0-9]* )
でいけるけど、より正確に数値かどうか判定するとなると
cshでは難しいかもしれない

教授は付けないほうがいい

730:名無しさん@お腹いっぱい。
09/12/23 20:37:33
「ご教授」で正しいんだよ。

731:名無しさん@お腹いっぱい。
09/12/23 20:38:39
>>727
lsが状況に応じて出力を変えてるとは思いませんでした.
ありがとうございます.

732:724
09/12/23 20:42:48
>729さん
cshでは難しいですか。。。

回答ありがとうございます。


733:名無しさん@お腹いっぱい。
09/12/23 20:46:57
>724
if ( { ( echo -n "$1" | grep '^[0-9][0-9]*$' > /dev/null ) } ) echo yes,yes,yes

734:名無しさん@お腹いっぱい。
09/12/23 23:37:25
>>724にかなり近いのですが、質問します。

kshで「変数の中身が半角英数14桁」であることを確認したいのですが、上手くいきません。

if [ `expr $hoge : [a-zA-Z0-9]+` -ne 14 ] ; then
# 半角英数14桁以外
fi

と書いてみたのですが、+が正規表現になってくれず。
[a-zA-Z0-9][a-zA-Z0-9]*も最初2桁分しかチェックできず。

上手く正規表現でチェックできる術はないでしょうか?
お分かりの方、ご教授お願いします。

735:名無しさん@お腹いっぱい。
09/12/24 01:15:38
$ echo "foo" | if egrep -qs '^[a-zA-Z0-9]+$'; then echo yes; fi
yes
$ echo "_foo" | if egrep -qs '^[a-zA-Z0-9]+$'; then echo yes; fi
$

736:名無しさん@お腹いっぱい。
09/12/24 04:12:15
>>734
if [ `expr $hoge : "[a-zA-Z0-9]\+"` -ne 14 ]




737:734
09/12/25 07:48:46
>>735
>>736
アドバイスありがとうございます。
見た目に単純な736の記述を試して上手く動作したので、この形で実装したいと思います。

\でエスケープすると正規表現になるとは知りませんでした。完全に逆だと思ってました。
エスケープもダブルクオートも試したのですが、両方やるとは思いつかず…

ありがとうございました。

738:名無しさん@お腹いっぱい。
09/12/26 18:19:46
えーと、複数ファイルを結合したいのですが、

・ファイル名の一部が一致している
・結合すべきファイルの数は分かっている
・一致している部分の文字数、箇所も分かっている
・このようなファイルの組がディレクトリ内に複数組ある

というような条件で、例えば

file01abc.txt
file02abc.txt
file03abc.txt

file01def.txt
file02def.txt
file03def.txt

file......

で、わざわざ
cat file??abc.txt > fileabc.txt
cat file??def.txt > fileabc.txt
cat............

などと書かずに一致部分を判別して全ての組を結合させたいのです。うまく出来る方法はあるでしょうか?

739:名無しさん@お腹いっぱい。
09/12/26 18:35:08
>>738
普通に、

for f in abc def
do
cat file??"$f".txt > file"$f".txt
done

740:名無しさん@お腹いっぱい。
09/12/26 19:13:07
すみません、ちょっと説明足りませんでした。
そのabc、defってのが異なる組がかなり大量にあって、かつその文字列が
そこそこ長いこと、毎回その生成される文字列が異なることから、いちいちinの後の部分を
書き出さずに出来るようにしたいのです。つまりこの場合、7,8,9文字目が
(具体的な文字列は何だか分からないけれど)一致しているファイル全てを結合する、
というような指定は出来ないでしょうか?

741:名無しさん@お腹いっぱい。
09/12/26 19:19:01
>>738
普通に、

for ff in *
do
f=${ff:6:3}
cat file??"$f".txt > file"$f".txt
done

742:名無しさん@お腹いっぱい。
09/12/26 19:35:08
>>740
これで合ってる?

ls | sed -n 's/^......//p' | sed 's/....$//' | sort | uniq | while read i
do cat file*${i}.txt > file${i}.txt
done

743:名無しさん@お腹いっぱい。
09/12/26 19:36:00
10
22
3
11
25
90
12




ってあるTextで平均から飛び出る奴(今回は90)切りたいんだけど
ヒントないっすか?

744:名無しさん@お腹いっぱい。
09/12/26 19:38:28
偏差値求めて標準偏差の何倍とかで検出だな

745:名無しさん@お腹いっぱい。
09/12/26 20:34:25
>>741
>>742
ありがとうございます。どっちも動作は完璧です。
さらにお手数をおかけしますが後学のために、
軽く何をやってるのか教えてもらえないでしょうか。

741はワイルドカードの挙動がよく分からないので3行目の時点で
ffに何が入っているのかよくわかりません。ffの6バイト目から3文字分を
fに代入し直しているって理解は合っていますか?

742は-n以降何をやってるか全く分かりません…
特に並んでいるドットの意味を教えてもらえないでしょうか?
察するに文字数ですよね?

746:名無しさん@お腹いっぱい。
09/12/26 20:50:17
>>745
>ffに何が入っているのかよくわかりません。ffの6バイト目から3文字分を
>fに代入し直しているって理解は合っていますか?

あってる

>742は-n以降何をやってるか全く分かりません…
>特に並んでいるドットの意味を教えてもらえないでしょうか?

sedの正規表現です

747:名無しさん@お腹いっぱい。
09/12/26 21:01:15
>>745
's/^......//p'

s は sbustitution == 文字の置換。s/aaa/bbb/ で aaa を bbb に置き換える。
^...... は正規表現。^ は行頭を表していて、. は文字一つ分を表している。
p は print == 印字。s で置き換えた後の文字列を表示する。

sed 's/....$//'

さっきと基本は同じ。
$ は行末を表している。....$ は行末の任意の4文字にマッチする正規表現。

sort | uniq

入力をソートして重複を除去する。
ここまでの処理結果は abc, def 等がファイル数分重複しているので、
重複を取り除く。

while read i; do ...

read で一行ずつ読み込んで、変数 i に格納する。i には abc や def 等が入る。

シェルスクリプトは普段それほど使っていないので、多分、もっと良い
方法があると思います。

748:名無しさん@お腹いっぱい。
09/12/26 21:09:21
スマソ。
s/sbustitution/substitution/

749:名無しさん@お腹いっぱい。
09/12/26 21:15:50
>>746
>>747
度々御丁寧にありがとうございます。よく分かりました。

750:名無しさん@お腹いっぱい。
09/12/27 15:16:39
>>744
そか、いったん合計して偏差値出すしかないか


751:正月前
09/12/29 21:51:50
シェルスクリプトの中で以下のようにperlで重複部分の文字を削除する場合は、最後の文字は消されない理由はなんでしょうか?
perlの中で同じことをすると、最後の文字は消されるのに。
教えて頂ければ、ありがたいです。
--------------------------
hoge='a:b:c:d:a:b:c:d:a'
echo $hoge
echo " "
echo $hoge | perl -F: -ane 'chop;foreach(@F){$s{$_}++ or push(@b,$_)}print join(":",@b)'
echo " "


--------------------------

752:名無しさん@お腹いっぱい。
09/12/29 22:24:22
>>751
echo -n

753:正月前
09/12/29 22:45:31
ありがとうございました!!!
perlの中でchopではだめで、echo -n で改行を消さないといけないんですね!


754:名無しさん@お腹いっぱい。
09/12/30 00:24:04
auto-split後だからchopするとしたら
chop($F[$#F]);

755:名無しさん@お腹いっぱい。
10/01/07 21:10:23
run.shファイルの中で、script_file.shをsourceした場合。
sourceされているscript_fileの中でscript_file自身の絶対パスを得る方法を調べています。

bashの場合はscript_fileの中で$BASH_SOURCEから得られるが、他のシェル(zsh/tcsh/ksh)でscript_file.shのパスを得られる方法を
教えていただけませんか?

>>>>>>>>>>>>>>>>>>>>>>
script_file.shファイルのある場所
/path/to/script_file.sh
>>>>>>>>>>>>>>>>>>>>>>

実行例:
%./run.sh

期待結果:
/path/to/


ファイル <run.sh>の中身
-------------
#!/bin/(sh/zsh/tcsh...)
source $path/script_file.sh
-------------

ファイル script_file:
-------------
script_file_path=`******`
echo $script_file_path;
-------------



756:名無しさん@お腹いっぱい。
10/01/07 21:31:48
>>755
他のシェルのソースを改造して $BASH_SOURCEの機能を実装すれば桶。

757:名無しさん@お腹いっぱい。
10/01/07 21:50:29
>>756
早速のレスありがとうございます。今環境がないので明日試してみます。

758:名無しさん@お腹いっぱい。
10/01/07 22:13:18
こりゃ、わかって無いな。

759:名無しさん@お腹いっぱい。
10/01/08 13:35:29
制限時間を設定して、2つのプロセスを実行して、時間内に1つでもプロセスが終了しなかったら2つともキルして、もう一度最初から実行するにはどのように記述すれば良いのでしょうか?
ご教授ねがいます

760:名無しさん@お腹いっぱい。
10/01/08 14:04:43
どこの馬の骨かわからん奴に教授はしない。

761:名無しさん@お腹いっぱい。
10/01/08 14:41:28
>>759
同条件で、最初から再実行したら、また時間内に
プロセスが終了しないのでループしちゃうのでは?

762:名無しさん@お腹いっぱい。
10/01/08 14:52:01
>>716
ループしてもいいから、まずはやり方を教授しろよ

763:名無しさん@お腹いっぱい。
10/01/08 14:57:34
>>761
ネットとか、I/Oポートとか、外的要因が絡んでるのなら
同条件で、最初から再実行してもループしない。

764:名無しさん@お腹いっぱい。
10/01/08 15:00:24
>>762
だから、誤用だけど言葉として正しい
と言ってるだろバカ


765:名無しさん@お腹いっぱい。
10/01/08 18:36:31
>>764
誤用する奴には教えないと言っているのだ。バカ。

766:名無しさん@お腹いっぱい。
10/01/08 18:43:35
うるせー馬鹿

767:名無しさん@お腹いっぱい。
10/01/08 18:53:46
いい加減ウザイよ。

768:名無しさん@お腹いっぱい。
10/01/08 19:02:39
>>765
仮に誤用してなかったとしても肝心の質問の答を知らないくせに

769:名無しさん@お腹いっぱい。
10/01/08 19:22:50
煽って答えがもらえるのは小学生まで

770:名無しさん@お腹いっぱい。
10/01/08 19:24:23
>>768
惨めだなあ。馬鹿丸出しの言い逃れを↓で完璧にのされたのを忘れてまた出てきやがった。

From: [719] 名無しさん@お腹いっぱい。 <sage>
Date: 2009/12/21(月) 18:25:12

>>716
アホ丸出しの言い訳止めろ。>>695の用法も正しいと言うのがお前の主張(>>705)。
>>696はオレじゃないが、誤用に対して「あげない」とからかっている。
お前は用法を知らずに揚げ足とったつもりで恥を晒したうえに、小学生並みの見苦
しい言い逃れを続けている単なるバカ。お前の負け。

>>705
> 「ご教授ください」=「体系だててきちんと教えてください」(同値)
> >>695 には「ご教授ください」と書いてある、
> イコール
> >>695 は「体系だててきちんと教えてください」と言っている

771:名無しさん@お腹いっぱい。
10/01/08 21:13:41
>>759

#!/bin/sh
program1 &
p1=$!
program2 &
p2=$!

sleep 60

kill -0 $p1; is_p1=$?
kill -0 $p2; is_p2=$?
if [ $is_p1 = 0 -o $is_p2 = 0 ]
then
   kill -9 $p1 $p2
   sh $0
fi

772:名無しさん@お腹いっぱい。
10/01/08 21:24:43
1 SIGKILLは安易に使ってはいけない。
2 exec sh $0

773:名無しさん@お腹いっぱい。
10/01/08 21:57:52
シェルをexecし直すのは効率が悪い。while文で書ける。

#!/bin/sh
while :
do
program1 &
p1=$!
program2 &
p2=$!

sleep 60

kill -0 $p1; is_p1=$?
kill -0 $p2; is_p2=$?
if [ $is_p1 = 0 -o $is_p2 = 0 ]
then
kill -9 $p1 $p2
continue
fi
break
done

774:名無しさん@お腹いっぱい。
10/01/08 22:06:04
SIGTERM と SIGINT のどちらを使うべきか
いまだによくわからないのはオレだけでいい

775:名無しさん@お腹いっぱい。
10/01/08 22:11:32
SIGKILLでおk

776:名無しさん@お腹いっぱい。
10/01/08 22:19:31
>>771 >>773
program1やprogram2が 60秒以内に正常終了した場合には、
sleep 60 せずにスクリプトもすぐ終了したいんですが、、

777:名無しさん@お腹いっぱい。
10/01/08 22:45:57
「ご教授ねがいます」なんていう奴は、これだよ

778:名無しさん@お腹いっぱい。
10/01/08 22:56:17
ご教授ねがえります

779:名無しさん@お腹いっぱい。
10/01/08 23:06:34
ご教授ねがえったか

780:名無しさん@お腹いっぱい。
10/01/08 23:47:21
謀反でござる!
謀反でござる!

781:名無しさん@お腹いっぱい。
10/01/09 05:41:48
女教授おながいします

782:名無しさん@お腹いっぱい。
10/01/09 07:47:50
質問 >>759 >>776 について、
「ご教授」の突っ込みと誤答ばかりで、

==== ここまで正解ゼロ ====

783:名無しさん@お腹いっぱい。
10/01/09 11:58:33
釣り板の釣りスレでマジ回答したら負け

784:771
10/01/09 14:46:50
>>776
sleep 60の代わりに、それらのプロセスが終了したか
チェックすればいい

   t=0
   while t=`expr $t + 1`; [ $t -lt 60 ]
   do
        kill -0 $p1; is_p1=$? 
        kill -0 $p2; is_p2=$? 
        if [ $is_p1 != 0 -a $is_p2 != 0 ] 
        then 
              break
         fi
        sleep 1
    done

785:名無しさん@お腹いっぱい。
10/01/09 15:03:34
お題を良く読みましょう。「制限時間」
オレはご教授しないけどな。

786:名無しさん@お腹いっぱい。
10/01/09 15:06:52
>>784
それ、1秒間隔でポーリングしてるだけなので、
やっぱり最大1秒遅れるので、ダメです。

787:名無しさん@お腹いっぱい。
10/01/09 19:46:58
#!/bin/sh
T1=`date "+%s"`
T2=0
T3=0
STS=1

while t=`expr $T3 - $T1`; [ $t -lt 最大制限時間 ]
do
program1 &
p1=$!
program2 &
p2=$!
T2=`date "+%s"`
T3=0

while t=`expr $T3 - $T2`; [ $t -lt 制限時間 ]
do
kill -0 $p1; is_p1=$?
kill -0 $p2; is_p2=$?
if [ $is_p1 != 0 -a $is_p2 != 0 ]; then
STS=0
break 2
fi
T3=`date "+%s"`
done
kill -9 $p1 $p2
done
exit $STS

もっとスマートに書けると思う ご教授しる

788:名無しさん@お腹いっぱい。
10/01/09 19:47:22
いやです

789:名無しさん@お腹いっぱい。
10/01/09 20:33:37
>>787
それ、ビージーループになってて重いのでNGです

790:名無しさん@お腹いっぱい。
10/01/09 22:00:20
waitすればいいやん
sleep 60 &して、これも含めた三つのpidをwait。
コードは書かないでおくが。

791:名無しさん@お腹いっぱい。
10/01/09 22:03:13
>>790
複数のプロセスをwaitすると、全部が終了するまで返って来ないという仕様なのでNG

792:名無しさん@お腹いっぱい。
10/01/09 22:34:21
ソケット通信でprogram1,2の終了を
管理プロセスに通知する仕組みにすれば
何とかなるかもしれないが、
シェルだけでは無理だね

793:名無しさん@お腹いっぱい。
10/01/09 22:38:41
んなぁこたー無いが、ご教授はしない。

794:名無しさん@お腹いっぱい。
10/01/11 01:17:26
下の input.txt から output.txt を作るにはどうすればよいでしょうか?
input.txt は1列のデータで、output.txt は、
input.txt の1列目から1行目を削除して2列目に並べたものです
perl か何かに全部読み込んで・・・という方法しか思いつかないのですが
ワンライナーでさくっとやる方法あったら教えてください

### input.txt
1
2
3
5
6

### output.txt
1 2
2 3
3 5
5 6

795:名無しさん@お腹いっぱい。
10/01/11 01:25:06
(read a; while read b; do echo $a $b; a=$b; done) <input.txt >output.txt

796:名無しさん@お腹いっぱい。
10/01/11 01:53:40
>>795
ありがとうございます
目から鱗です

797:名無しさん@お腹いっぱい。
10/01/11 12:54:30
>>794
横方向に連結する場合、 paste を使うのが基本
paste - - < input.txt


798:名無しさん@お腹いっぱい。
10/01/11 12:59:32
あ、よく読んでなかった。こうか
# tail -n +2 input.txt | paste input.txt - > output.txt

799:名無しさん@お腹いっぱい。
10/01/11 13:27:17
>>798
なぜ #プロンプト…


800:名無しさん@お腹いっぱい。
10/01/11 13:49:45
あ、いや、特に考え無しに・・。 $ が一般ユーザで、# が root だっけ

801:759
10/01/11 14:32:31
放置してしまってすみません。
みなさんありがとうございます。
>>776さんは自分ではありません、まったくレスしていないので逆に失礼ですが。


802:名無しさん@お腹いっぱい。
10/01/11 19:14:45
>>800
古くはさらに、$と%をそれぞれBourne ShellとC Shellの一般ユーザー
プロンプトとしたものだけれど、いまはそこまで厳密に使う人はいない
かもなー。
zshは基本的には$系のはずなのにデフォルトが%なのはちょっと不思議。


803:名無しさん@お腹いっぱい。
10/01/11 23:07:53
以下の処理のリダイレクトについて教えていただけますでしょうか?
もしくは、よくある処理のようなので解説しているサイトを教えていただけますでしょうか?

commandの結果を取得しつつ、画面及びファイルに出力
status=`exec 3>&1; { command 2>&1 3>&-; echo $? 1>&3; } | tee command.log 1>&2 3>&-`
echo $status

①execにより3で1を指した後にcommand実行時に3を閉じてるのは何故でしょうか?
必要性がよくわからないです。
同時に1が閉じられることはないですよね?

②どういう経路でcommandの結果はstatusに格納されているのでしょうか?

③tee実行時に行っているリダイレクトの意味はどのようなものでしょうか?

正直言って全体的によく分からないです。

804:名無しさん@お腹いっぱい。
10/01/11 23:22:23
>>803
機種依存文字は書き換えました

(1)commandが3に出力しないように念のため

(2) echo $? が 3に出る。3には、あらかじめexec 3>&1 によって、
パイプではなく、コマンド置換(バッククォート)に通じる標準出力が
複製されている。よって、echoが 3に出せば 変数statusに入る。

(3)teeがcommandの出力をcommand.logに書くと同時に
同じものを 1に出そうとするが、1にそのまま出すと変数statusに入ってしまうので
2にリダイレクトして画面に表示されるようにしている。
3>&-は(1)と同じく念のため。


以上、ご教授しましたw

805:名無しさん@お腹いっぱい。
10/01/11 23:49:50
>>804
ありがとうございました。

command時に3を閉じてるので、echo時に1>&3としても出力されないと勘違いしておりました。

それと(3)について、command時に2>&1としていますが、
これはtee時の2には引き継がれないのでしょうか?
引き継がれていると、1>&2とすると元に戻って1に出力して
statusに上書きしてしまうように見えます。


806:名無しさん@お腹いっぱい。
10/01/12 06:29:53
>>805
commandとechoは無関係。
exec 3>&1したものが、commandとechoに並列して引き継がれる。
command側では3は不要なので閉じてるだけ。

commandの2とteeの2は無関係。
commandの1はパイプにつながっているので、
commandの2もパイプに流すためにcommand 2>&1 してるだけ。
teeはそのパイプを0で受けとる。
teeの1や2はcommandとは無関係で、デフォルトのまま。
そこで tee 1>&2 で画面に出す。

以上、俺もご教授しましたw

807:名無しさん@お腹いっぱい。
10/01/12 09:40:26
>>806
ありがとうございました。
全て理解できました。

808:名無しさん@お腹いっぱい。
10/01/12 18:20:04
つまり要約すると「ご教授」で正しかったのですね。
全て理解できました。

809:名無しさん@お腹いっぱい。
10/01/12 18:37:12
つまり要約すると「ご教授」で正しかったのですね。
全て理解できました。


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