5ちゃんねる ★スマホ版★ ■掲示板に戻る■ 全部 1- 最新50  

■ このスレッドは過去ログ倉庫に格納されています

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

1 :名無しさん@お腹いっぱい。:2007/08/15(水) 07:25:02
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。


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

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。

前スレ
シェルスクリプト総合 その8
http://pc11.2ch.net/test/read.cgi/unix/1171517324/

2 :名無しさん@お腹いっぱい。:2007/08/15(水) 07:25:49
□前スレや過去スレ:
シェルスクリプト総合 その7
http://pc10.2ch.net/test/read.cgi/unix/1157601611/
シェルスクリプト総合 その6
http://pc10.2ch.net/test/read.cgi/unix/1143302182/
シェルスクリプト総合 その5
http://pc10.2ch.net/test/read.cgi/unix/1137801629/
シェルスクリプト総合 その4
http://pc10.2ch.net/test/read.cgi/unix/1131026501/
シェルスクリプト総合 その3
http://pc10.2ch.net/test/read.cgi/unix/1124889646/
シェルスクリプト総合 その2
http://pc10.2ch.net/test/read.cgi/unix/1113664637/
シェルスクリプト総合 その1
http://pc10.2ch.net/test/read.cgi/unix/1101820646/

□関連スレ:
sed
http://pc10.2ch.net/test/read.cgi/unix/1085730992/
正規表現
http://pc10.2ch.net/test/read.cgi/unix/1039165754/
おまえら! shell は何を使っているんですか?
http://pc10.2ch.net/test/read.cgi/unix/1012330865/
Eshell の使い方とか設定とか【Emacs Shell、Lisp】
http://pc10.2ch.net/test/read.cgi/unix/1102921590/

3 :名無しさん@お腹いっぱい。:2007/08/15(水) 07:27:17
□初心者向けリンク
「誰にでも」シリーズ
ttp://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/publications/dareUni/
/bin/shプログラミング入門
ttp://freebooks.info.nara-k.ac.jp/archive/ShellProgramming/
シェルを使おう - 導入からプログラミングまで -
ttp://www.netfort.gr.jp/~tomokuni/lms/shell/text/

□入門者向け書籍:
プロフェショナルシェルプログラミング
http://www.amazon.co.jp/exec/obidos/ASIN/4756116329/
入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界
http://www.amazon.co.jp/exec/obidos/ASIN/4797321946/
UNIXシェルプログラミング徹底解説
http://www.amazon.co.jp/exec/obidos/ASIN/4822280489/
入門Kornシェル
http://www.amazon.co.jp/exec/obidos/ASIN/4873110149/
入門bash
http://www.amazon.co.jp/exec/obidos/ASIN/4900900788/

□参考リンク:
UNIXの部屋 (沢山のコマンドの簡単な紹介など)
http://x68000.q-e-d.net/~68user/unix/
POSIX: Shell & Utilities (標準規格)
http://www.opengroup.org/onlinepubs/009695399/utilities/contents.html

4 :名無しさん@お腹いっぱい。:2007/08/15(水) 07:28:56
□最近のシェルスクリプト本(1)

(2004/03) UNIXシェルスクリプトハンドブック 関根 達夫 (著)
http://amazon.co.jp/o/ASIN/4797326522/
(2004/10) UNIXシェルスクリプト逆引き大全333の極意 中橋 一朗 (著)
http://amazon.co.jp/o/ASIN/4798008842/
(2004/11) 仕事に使えるLinuxシェルスクリプト 千葉 真人 (著)
http://amazon.co.jp/o/ASIN/4822282090/
(2004/12) UNIXシェルスクリプトサンプルブック デイブ・テイラー (著)
http://amazon.co.jp/o/ASIN/4797327286/
(2005/02) シェルスクリプト基本リファレンス 山森 丈範 (著)
http://amazon.co.jp/o/ASIN/4774122610/
(2005/04) LinuxWorldスクリプト 月刊リナックス・ワールド総集編 月刊LinuxWorld特別 (著)
http://amazon.co.jp/o/ASIN/4872802349/
(2005/05) UNIXシェルスクリプトコマンドブック 山下 哲典 (著)
http://amazon.co.jp/o/ASIN/4797330635/
(2005/05) わかる&使える UNIX基礎講座 シェルスクリプト編 中井 獏 (著)
http://amazon.co.jp/o/ASIN/4774123625/


5 :名無しさん@お腹いっぱい。:2007/08/15(水) 07:30:05
□最近のシェルスクリプト本(2)

(2005/07) UNIX シェルスクリプト辞典 川井 義治 (著)
http://amazon.co.jp/o/ASIN/4798109231/
(2005/08) シェルスクリプト ポケットリファレンス bash編 宮原 徹 (著), 川原 龍人 (著)
http://www.amazon.co.jp/o/ASIN/4774124818/
(2005/12) 図解でわかるLinuxシェルスクリプト・正規表現 小泉 修 (著)
http://www.amazon.co.jp/o/ASIN/4534040067/
(2006/01)詳解 シェルスクリプト アーノルド ロビンス (著), ネルソン・H.F. ベーブ(著), Arnold Robbins (原著), Nelson H.F. Beebe (原著), 日向 あおい (翻訳)
http://www.amazon.co.jp/o/ASIN/4873112672/
(2007/3) Linuxシェルスクリプトユーザー便利帳―bash2/bash3対応 伊藤 幸夫 (著), 寒川 陽美 (著)
http://www.amazon.co.jp/o/ASIN/4798015954/

6 :名無しさん@お腹いっぱい。:2007/08/15(水) 07:30:56
□関連書籍と関連リンク:

FreeBSD Hypertext Man Pages
http://www.freebsd.org/cgi/man.cgi

Linux JF (Japanese FAQ) Project.
http://www.linux.or.jp/JF/

Unix Programming Frequently Asked Questions 日本語訳
http://www.adl.nii.ac.jp/~moro/unix-programmer/faq-j_toc.html

UNIXプログラミング環境
http://www.amazon.co.jp/exec/obidos/ASIN/4871483517/

□人間初心者へのお願い:
・このスレはシェルスクリプトについてのスレです。
 シェルの対話的な利用についての話やスクリプトと関係ないコマンドの
 使い方の質問などはスレ違いなので無用に願います。

□シェルスクリプトでよく使うコマンド:
制御・条件判定系: [,test,expr,true,false,yes,getopts
テキスト処理系: cat,awk,sed,tr,sort,uniq,grep,wc,head,tail,cut,paste,comm,join
ファイル検索系: find,xargs
(スペースなどを含むファイル名を正しく処理するため、
findは -print0、xargsは -0オプションを常に付けることを推奨
ただし、Solarisでは未対応。どうするんだろ?)
ディレクトリ系: basename,dirname
出力系: echo,printf
対話コマンド制御系: expect
http/ftpの処理自動化: wget,curl

7 :名無しさん@お腹いっぱい。:2007/08/15(水) 09:20:11
>>1


8 :名無しさん@お腹いっぱい。:2007/08/15(水) 09:34:03
1乙

9 :名無しさん@お腹いっぱい。:2007/08/15(水) 13:53:05
乙一

10 :名無しさん@お腹いっぱい。:2007/08/15(水) 13:57:07
関連スレ(bashの話題はこちらへ)

シェルスクリプト総合@LINUX Part3
http://pc11.2ch.net/test/read.cgi/linux/1184077033/l50

11 :名無しさん@お腹いっぱい。:2007/08/18(土) 13:14:39
あち

12 :名無しさん@お腹いっぱい。:2007/08/18(土) 20:14:08
そち

13 :名無しさん@お腹いっぱい。:2007/08/18(土) 22:19:20
前任者から引き継いだスクリプトが結構多数あります。
そこでは、ファイル名を扱う変数が $file みたいにクオートなしで書かれていて、
昔はこれで問題なかったようですが、今はとくにSambaの公開ディレクトリなどで
エラーというか、正常に動作しない事態が起きまくります。
そこで、ひとつずつ、$file を "$file" に書き直すとかしてますが、
それを一発で解決できる方法ないですか?

14 :名無しさん@お腹いっぱい。:2007/08/19(日) 16:46:11
とはいってもクオートの中で使われているのもあるだろうし、
sedでというのも難しそうな。
とりあえずは#!/bin/shになってるのをzshにしてしまうのが楽かも。
zshはクオートされてなくても分割されないから。

15 :名無しさん@お腹いっぱい。:2007/08/22(水) 00:53:34
"結構多数"にもよるけれど、エディタかスクリプトで
インタラクティブに置換するのが簡単かと。
でもこのスレ的に求められている答えではないか

16 :名無しさん@お腹いっぱい。:2007/08/24(金) 10:23:23
「if〜then」の中で「hoo」という変数名を使っていたら「if〜then」までを出力したい。
どうやればできる?



17 :名無しさん@お腹いっぱい。:2007/08/24(金) 10:27:20
>>16
変数hooが、空文字列の場合でも「設定されていない」とみなしていいなら、

if [ "$hoo" ]; then

18 :名無しさん@お腹いっぱい。:2007/08/24(金) 10:36:00
質問の意味が複数にとれるなぁ、

grep '\<if\>.*\<hoo\>.*\<then\>'

ということじゃないかと。だとするとスレ違いだが。

19 :名無しさん@お腹いっぱい。:2007/08/24(金) 12:57:04
>>18

複数行にわたる場合も有るし、
if以前とthen以降は出力しないんだから、
sedとかの方がふさわしいと思う。

20 :名無しさん@お腹いっぱい。:2007/08/24(金) 13:03:24
で、>>16はほんとは何をしたいのよ。

21 :名無しさん@お腹いっぱい。:2007/08/24(金) 16:09:42
楽にログローテーションするコマンドありますか

イメージ
xxcmd | ローテーションコマンド サイズ 世代 ファイル名

xxcmdはfdをオープンしたまま書き出すので、loglotationではNGです。


いいのありますかね?

22 :名無しさん@お腹いっぱい。:2007/08/24(金) 16:13:05
>>21
rotatelogs

23 :名無しさん@お腹いっぱい。:2007/08/24(金) 16:38:19
>>22
ありがとうございます。
あやうく、Log4Perl を選びそうになりました。

24 :名無しさん@お腹いっぱい。:2007/08/25(土) 00:45:19
ちょっと変な聞き方になりますが

root権限で実行しているシェルスクリプト内で実行するコマンドはroot権限で実行されるはず。
例えば、
--------------
#!/bin/sh
whoami
exit 0
--------------
をsudoで実行したらwhoamiはrootを返すはず。

以上の認識は間違ってないですよね?

というのは、とある開発中のUNIXでwhoamiがログインユーザ名を返してきました。
これをバグであると捉えていいのか迷ったので。

25 :名無しさん@お腹いっぱい。:2007/08/25(土) 01:16:25
いや、バグじゃないと思う。

root権限で動いていなけりゃバグと言えるが、whoami云々はまた別の話。

26 :24:2007/08/25(土) 02:26:53
あ、whoamiがrootを返さなくなったのはwhoamiの動作変更かもしれないですからね。
例えとして悪かったですね。
whoami以外の何かを呼んでも、それらはroot権限で動いていませんでした。

気になっているのは、「シェルスクリプトそれ自体がroot権限で動いていれば、
そこから呼び出すコマンドもまたroot権限で動くはず」
と考えていた僕は間違っていたのか?ということです。

27 :名無しさん@お腹いっぱい。:2007/08/25(土) 02:43:35
>>26
その考えは正しい。

% echo Hello > /tmp/hoge
% sudo chown root /tmp/hoge
Password:
% sudo chmod 400 /tmp/hoge
% ls -l /tmp/hoge
-r-------- 1 root wheel 6 Aug 25 02:37 /tmp/hoge
% cat /tmp/hoge
cat: /tmp/hoge: Permission denied
% sudo cat /tmp/hoge
Hello
% echo "cat /tmp/hoge" > /tmp/test.sh
% sh /tmp/test.sh
cat: /tmp/hoge: Permission denied
% sudo sh /tmp/test.sh
Hello

って、Macで試したんだが、ちゃんとroot権限で動いてる。

28 :名無しさん@お腹いっぱい。:2007/08/25(土) 07:12:42
>>27
行の左端に書いてある % はなんの意味があるのですか?

29 :27:2007/08/25(土) 12:05:07
>>28
% はプロンプトです。$ の方が良かったかな。

>>whoami以外の何かを呼んでも、それらはroot権限で動いていませんでした
というのが間違っているんじゃないかと思う。
その確認をしてみたのが >>27


30 :名無しさん@お腹いっぱい。:2007/08/25(土) 12:25:15
rootでじゃなくしつこくroot権限でと書いているのだよな。
シェルスクリプトにsetuidしたつもりとかいうオチじゃないだろうな。

31 :16:2007/08/25(土) 22:36:45
徹夜続きで来れなかった。
遅れてスマソ。
こんな感じでできるかな?と自分で書いてみた↓

awk '/if/,/then/{print $0}' input.file|sed -n '/then/{\
x\
s/\n/\t/g\
/hoo/p\
d\
}\
H'


32 :24,26:2007/08/26(日) 02:11:24
よくよく考えてみれば、スクリプト内で呼び出すコマンドもroot権限で動いてくれないと
root権限で動かす意味がないですよね。

で、バグじゃねーかと開発者に報告しようと思っていたところ、
その開発中UNIXの最新ビルドが出て、改めて確認してみたら、
スクリプト内で呼び出すコマンドはroot権限で動くようになっておりました
(whoamiもrootを返すようになっていました)。やはりバグだったようです。

レス下さった方ありがとうございました。

33 :名無しさん@お腹いっぱい。:2007/08/29(水) 23:50:27
Solaris8上でcshスクリプト使っているのですが、

rm *.log

としたときに*.logが存在しなかった時に表示される
「一致しませんでした」というメッセージを抑止するには
どうしたらいいのでしょうか?

34 :名無しさん@お腹いっぱい。:2007/08/30(木) 00:21:33
set nonomatch

35 :名無しさん@お腹いっぱい。:2007/08/30(木) 00:49:08
あるファイルの最後から指定した行数だけ表示しない、
ということをしたいのですが、どのようにすればよいでしょうか?

ファイルの内容
-----------------------
aaa
bbb
ccc
ddd
eee
-----------------------

表示したい内容(最後から二行だけ表示しない)
-----------------------
aaa
bbb
ccc
-----------------------

よろしくご教授お願いします。

36 :名無しさん@お腹いっぱい。:2007/08/30(木) 01:30:00
誤字等の館:ご教授願います
http://www.tt.rim.or.jp/~rudyard/torii009.html


37 :名無しさん@お腹いっぱい。:2007/08/30(木) 01:31:47
なんか久しぶりにそれらしい質問を見た気がする。

>>35
linux板の方のスレに以前書いたけど、たとえば末尾3行を落とすなら
sed -e '1h;1!H;1,3!{g;P;s/[^\n]*\n//;h;};d' file
行数に合わせて3を適当に変更してくれ。

tailに-rオプションがある一部の環境なら
(tail -r|sed 1,3d|tail -r) < file
というのもできる。ファイルを2回ひっくり返すからかなり計算機の無駄遣いだけど。

38 :名無しさん@お腹いっぱい。:2007/08/30(木) 10:24:24
>>37
sedスレでも最近似た質問があったね。
http://pc11.2ch.net/test/read.cgi/unix/1085730992/198

39 :33:2007/09/01(土) 12:03:10
>>34
ありがとうございます。
set nonomatch
rm -f *.log
の組み合わせでメッセージ抑止できました。

40 :名無しさん@お腹いっぱい。:2007/09/08(土) 01:57:19
次のような処理をシェルスクリプトでやろうと思っています。(ubuntu/bash)

http://www.google.co.jp/search?hl=ja&q=2ch&btnI=I%27m+Feeling+Lucky&lr=
が返す(つまり、ブラウザで飛ぶことが出来る)サイトアドレス(この場合は2ch.net)
を複数、定期的に観測する

素直に考えればwgetかなと思い、--spiderオプション付きでログを取っていくことを
考えました。
しかし、リダイレクトのしかたが違うからか他の「移転しました」のサイトとは違い
403 forbiddenがでます。

なにか良い方法があればご教授ください。


41 :40:2007/09/08(土) 02:14:11
舌足らずだったので補足します。
googleのI'm feeling luckyにかけたい対象キーワードは複数あります。
それらの対象キーワードのgoogleランキングの変遷を知りたいという
わけです。

質問は多分二つに切り分け可能で、I'm feeling luckyによるリダイレクトジャンプを
wgetはフォローできるかというのが一つ、もう一つが英数字以外の文字列によって
構成されている
http://www.google.com/search?q=2ch
といったページをwgetでどうやって取得するか、という問題です。後者が出来れば
一応ソースを取得して検索順位第一位のサイトアドレスを取得することは
何とか出来ます。

42 :名無しさん@お腹いっぱい。:2007/09/08(土) 06:20:40
普通に検索して最初の候補を記録すりゃいいんじゃないの。

43 :名無しさん@お腹いっぱい。:2007/09/08(土) 10:12:00
> (ubuntu/bash)
なんで犬板で聞かないのだ?

44 :名無しさん@お腹いっぱい。:2007/09/08(土) 11:15:40
うぶん厨だから

45 :名無しさん@お腹いっぱい。:2007/09/08(土) 18:08:00
こっちのほうが頼りになるかも?と誤解してるから

46 :名無しさん@お腹いっぱい。:2007/09/08(土) 18:10:33
犬板にbash専門のスレが無いのは何故だろう
cshやzshより圧倒的に利用者が多いしbashが標準みたいなもんなのに。

47 :名無しさん@お腹いっぱい。:2007/09/08(土) 18:35:31
標準であればわざわざ名乗る必要もないということ。
Linux的には単にシェルと言ったらbashを指す。

48 :名無しさん@お腹いっぱい。:2007/09/08(土) 20:32:05
bash 専門じゃないけどスレあるよ。

シェルスクリプト総合@LINUX Part3
http://pc11.2ch.net/test/read.cgi/linux/1184077033/

49 :名無しさん@お腹いっぱい。:2007/09/09(日) 12:25:29
>>41
自分の環境に wget が無くて curl ならあるんで直接的な回答じゃなくてスマンが。

curl だと -L オプションでリダイレクトをたどってくれる。
wget は知らない。調べてちょ。ダメだったら wget はあきらめて curl で代替するのがお勧め。

後、curl の User Agent だと Google から嫌われるので、
-A ' -A 'Mozilla/5.0 (hogehoge)'
のオプションを付けてブラウザのフリをさせる。知ってるかも知れないけど。


50 :名無しさん@お腹いっぱい。:2007/09/09(日) 12:40:04
>>40
ちとやってみたがユーザーエージェントではじかれてるだけっぽい

-U 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)'
とかでUA指定すればよいが、とりあえず'a'とか適当な名前でも通るようだ

>>41の質問だが
-O foo.htmlとか適当な名前を出力先に指定するなり
-O -などとして標準出力に吐かせてシェル側で受け取るなり好きに汁

51 :名無しさん@お腹いっぱい。:2007/09/09(日) 13:07:11
>ユーザーエージェントではじかれてるだけっぽい
そういう問題みたいだね。

>英数字以外の文字列
たとえば「ソニー」の場合のURLは
http://www.google.co.jp/search?hl=ja&q=%E3%82%BD%E3%83%8B%E3%83%BC&btnI=I%27m+Feeling+Lucky&lr=
になる。「ソニー」をUTF-8でURLエンコードして「%E3%82%BD%E3%83%8B%E3%83%BC」
にするんだが、そこから先の細かい話はWebProg板とかで聞いた方が良い。


52 :40:2007/09/09(日) 21:03:32
どうもありがとうございます。
いただいたヒントを元にネットで検索した結果、手元の環境で

curl -L -A 'a' -w %{url_effective} "http://www.google.co.jp/search?hl=ja&q=2ch&btnI=I%27m+Feeling+Lucky&lr="

にて出力される最後の1行だけをテキスト処理していくことで、思っていることが
出来ることがわかりました。
板違いの分も含めてお騒がせしました。


53 :名無しさん@お腹いっぱい。:2007/09/12(水) 00:12:12
/bin/shだけでファイルを表示させるって
while read line; do echo $line; done < file
であってますか?

54 :名無しさん@お腹いっぱい。:2007/09/12(水) 00:21:40
試してみりゃいーんじゃないでしょーか。

55 :名無しさん@お腹いっぱい。:2007/09/12(水) 01:14:37
ヒント: クォート

56 :名無しさん@お腹いっぱい。:2007/09/12(水) 02:55:39
findで検索し、見つかったファイルを引数として
for でファイル数分処理したいと考えています。

例: find で見つかったファイルが /home/abc/1.txt /home/abc/2.txt
であれば、
for i in /home/abc/1.txt /home/abc/2.txt
do ......
といった感じです。

この場合に、find で見つけたファイルを変数に、
「arg1 arg2 arg3 ...」と代入する方法がわかりません。
お助けください、おながいします。m(_ _)m

57 :名無しさん@お腹いっぱい。:2007/09/12(水) 04:28:01
>>56
> for で

ここが間違い

58 :名無しさん@お腹いっぱい。:2007/09/12(水) 06:40:33
>>53
あってるお

>>56
find . | while read line; do echo $line; done

59 :名無しさん@お腹いっぱい。:2007/09/12(水) 08:45:19
>>58
あってないよw

せっかく >>55 がくれてるヒント守れよ
でないと誤動作するよ

60 :名無しさん@お腹いっぱい。:2007/09/12(水) 10:38:11
クォートしても行頭行末のスペースやバックスラッシュはどうにもならんので、
完全な方法はないってことで。
# \ は read -r で動作を変えられるけど。


61 :名無しさん@お腹いっぱい。:2007/09/12(水) 10:56:32
/home/hoge/1.txt
/home/fuga/2.txt
/home/ahan/3.txt

このパスから
Unixユーザ名部分(上記の場合、hogeとfugaとahan)を
抜き出して変数に代入するにはどうすればよいでしょうか。
正規表現を使うということはなんとなくわかります。

62 :名無しさん@お腹いっぱい。:2007/09/12(水) 10:59:39
>>61
雑でいいなら
awk -F/ '{ print $3 }'
で出るけど、他に条件あるなら言ってくれ。

63 :61:2007/09/12(水) 11:10:04
>>62
ありがとうございます、
お言葉に甘えて
Unixユーザ名が
[a-z0-9-]+
の場合、という条件も加えてもらえるでしょうか。
それで awk の使い方などを調べてみます。

64 :名無しさん@お腹いっぱい。:2007/09/12(水) 11:19:21
いや、そういうことじゃなくて。

65 :名無しさん@お腹いっぱい。:2007/09/12(水) 12:58:10
trap について教えてください。

スクリプトfoo.shは、trapを用いて、SIGINTのハンドラを記述しています。
スクリプトbar.shは、スクリプトfoo.shをバックグラウンドで起動します。

foo.shをコマンドラインからフォアグラウンドで実行した場合。
foo.shをコマンドラインからバックグラウンドで実行した場合。
foo.shをdaemonで実行した場合。

いずれのケースでも、foo.shにSIGINTを送ると、foo.shのハンドラは
実行されます。

しかし、bar.shからバックグラウンドで起動されたfoo.shに対して
SIGINTを送っても、foo.shのハンドラは実行されません。
また、foo.shから起動しているコマンドにSIGINTを送っても、
無視されている様子です。

なぜでしょう?
また、bar.shからバックグラウンドでfoo.shを起動した場合でも、
foo.shのハンドラが実行され、foo.shから起動しているコマンドも
同様にSIGINTを受け付けてくれるようにする為にはどうすれば
良いのでしょうか?

66 :65:2007/09/12(水) 12:59:09
こんなスクリプトで試しています。

スクリプト foo.sh
#!/bin/sh
trap 'HANDLE' INT
HANDLE()
{
   touch /tmp/foo.log
   exit
}
echo "START"
/bin/rm -f /tmp/foo.log
/bin/sleep 30
echo "END"
 
スクリプトbar.sh
#!/bin/sh
/tmp/foo.sh &


67 :名無しさん@お腹いっぱい。:2007/09/12(水) 13:15:52
>>65
バックグラウンドで起動されたプロセスは、
最初から SIGINT無視の状態で起動される。
これは、シェル上で trapを実行しても再設定されない。
シェルスクリプトでは不可能。

68 :65:2007/09/12(水) 13:19:32
ちなみに、bar.shを、Cシェルのスクリプトにしても、
perlのスクリプトにしても同じでした。

69 :名無しさん@お腹いっぱい。:2007/09/12(水) 13:21:31
>>68
>>67

70 :名無しさん@お腹いっぱい。:2007/09/12(水) 13:32:35
>>67 に補足すると、ジョブコントロール可能なシェルのコマンドラインから
直接起動する場合に限り、バックグラウンドで起動してもSIGINTは無視されない。
しかしこれは例外と考えるべき。

ジョブコントロールは、プロセスグループを変更することによって管理していて、
fgでフォアグラウンドになる時のために、
SIGINTを無視しないようになっているだけの話。

71 :65:2007/09/12(水) 13:42:08
レスTHXです。
shのソースを見てましたが、確かにバックグラウンドで起動されたときは
SIGINT,SIGQUITをSIG_IGNしているみたいです。

ひとつ賢くなりました。
daemonで起動することにします。

72 :名無しさん@お腹いっぱい。:2007/09/12(水) 16:01:50
/home/hoge/file
のfileだけ返すようなコマンドってないでしょうか。



73 :名無しさん@お腹いっぱい。:2007/09/12(水) 16:21:27
basename

74 :名無しさん@お腹いっぱい。:2007/09/12(水) 16:47:52
awk -F/ '{ print $4 }'

75 :名無しさん@お腹いっぱい。:2007/09/12(水) 16:53:28
>>74
アフォか。/hoge/hage/boke/file だったらどうすんだよw

76 :名無しさん@お腹いっぱい。:2007/09/12(水) 16:55:41
>>73
サンクスです!!

77 :名無しさん@お腹いっぱい。:2007/09/12(水) 16:55:49
>>75
後からそんな条件追加されてもな。

78 :名無しさん@お腹いっぱい。:2007/09/12(水) 17:06:15
条件追加なんかしてないじゃん。
正解が出る前にわざとボケるならまだしも、
>>73 に正解が出た後でボケてもウケないよ。

79 :名無しさん@お腹いっぱい。:2007/09/12(水) 17:38:55
find / -regex "/home/.*\.c"

find /home -regex "/home/.*\.c"
ってCPUやHDDへの負荷って変わりますか?
後者の方が良い気がしますが、現在全て前者で作っちゃってます。

80 :名無しさん@お腹いっぱい。:2007/09/12(水) 18:27:30
>>79
やってみればすぐわかるのに

あと、cのソース探すのに、-regexは過剰だろ。-nameで十分

81 :名無しさん@お腹いっぱい。:2007/09/12(水) 18:30:50
自分では違いに気がつかなくて人に質問しなければわからないほどの差なのであれば
どっちでもいいんじゃないかな。たまには痛い目を見るのもいい経験だよ。


82 :61:2007/09/12(水) 18:33:59
awkについて勉強しました。
ありがとうございます。
今回のケースはこれでいけそうです。

何度もすいません、今後のために聞いておきたいのですが、
/home/hoge/abc.txt
の.txtを除いたファイル名、つまりabcを取得したい場合、
などには
どんな方法があるでしょうか。

83 :名無しさん@お腹いっぱい。:2007/09/12(水) 18:37:19
basename

84 :61:2007/09/12(水) 18:42:02
basename では abc.txt とならないでしょうか。
abc.txt ではなく、 abc を取得したいと思います。

85 :名無しさん@お腹いっぱい。:2007/09/12(水) 18:50:29
man basename

86 :名無しさん@お腹いっぱい。:2007/09/12(水) 18:57:34
>>85
それだとなんか英語のようなものが表示さ(ry

87 :名無しさん@お腹いっぱい。:2007/09/12(水) 18:59:40
こんな初心者の質問いちいちめんどくさいから、
黙らせるためにずばり答え書いてやれよ。

basename /home/hoge/abc.txt .txt

88 :61:2007/09/12(水) 19:06:57
そ、そんな言い方ひどいよ!!!!













サンクスです

89 :名無しさん@お腹いっぱい。:2007/09/12(水) 19:11:12
もうひとつ教えてやろう。
>>61 は awkなんか使わなくてもできる。

basename `dirname /home/hoge/1.txt`

90 :名無しさん@お腹いっぱい。:2007/09/12(水) 22:20:18
1時間ごとにのsyslog、messegesを
監視(ここでは適当なcommand)したいです。

syslogやmessegesはローテートしているので
前回の監視(1時間前)後にログが切り替わった場合と
そのまま使われている場合で実行commandを変えたいのですが
どのようなシェルスクリプトにしたらできるでしょうか?

たとえばどのログも切り替わっていない場合はcommandA、
syslogが切り替わった場合はcommandB、
messegesが切り替わった場合にはcommandCを
実行するというようなシェルスクリプトが書きたいのですが^^;


91 :名無しさん@お腹いっぱい。:2007/09/12(水) 22:36:41
今時のPOSIX準拠のshellだったら、外部コマンドなんか使わなくてもできる。
name=/home/hoge/1.txt; name=${name#/*/}; echo ${name%%/*}

92 :名無しさん@お腹いっぱい。:2007/09/12(水) 22:39:40
>>90
どっちも切り替わった場合は?

というのは置いといて、
前回と今回見ているファイルの実体同じかどうかのチェックということなら、
切り替え時に必ずi-node番号が変わるという前提で、
ls -iでi-node番号を取得して、保存しとくしかないだろうな。

oldinode=`cat /var/log/oldinodestore`
ls -i /var/log/syslog | awk '{print $1}' >/var/log/oldinodestore
newinode=`cat /var/log/oldinodestore`
if [ $newinode -eq $oldinode ]; then
kawattenai
else
kawatta
fi

93 :名無しさん@お腹いっぱい。:2007/09/12(水) 22:44:43
>>59
あってるだろがwwwwwwwwwww
ばかかwwwwwwwww

94 :名無しさん@お腹いっぱい。:2007/09/12(水) 22:50:16
>>93
あってねーよ。池沼。WWWW
(echo " aaa"; echo " bbb")|while read line; do echo $line; done

95 :名無しさん@お腹いっぱい。:2007/09/12(水) 22:55:10
>>90
切り替わってなくて commandA を実行しはじめたとたんに、
あるいはその直前に、切り替わっても問題ないという前提か?

96 :90:2007/09/13(木) 10:35:28
お返事が遅くなってしまいました。

>>92
ありがとうございます。
いただいたShellで試してみますね。
いつか自分でもShellがすらすら書けるようになるのかなぁ。。

>>95
そこまでシビアなタイミングは前提にしていないようです。
最悪1時間後の監視でひっかかればよいという前提です。

>90を訂正します。
syslog、messegesどちらが切り替わってもcommandBを
実行すればよいみたいです。
syslog、messegesが切り替わっていたらcommandBを実行。
切り替わっていなかったらcommandAを実行できればよいようです。





97 :名無しさん@お腹いっぱい。:2007/09/13(木) 10:40:56
Shellってゆーな

98 :90:2007/09/13(木) 10:49:31
そうでしたね^^;
先日区別しなくてはいけないと読んだばかりでした><

99 :名無しさん@お腹いっぱい。:2007/09/13(木) 13:00:29
>>90
>1時間ごとにのsyslog、messegesを
>監視(ここでは適当なcommand)したいです。

新人君かな?それじゃなきゃ、おわってるけどw
君には、このギョーカイ向いて無いぞ

でも、そんなの関係ねぇー♪なら、いいけどさ。

分からないことは、聞くんじゃ無くて検索するようにすれば、生き残っていけるから頑張れ!!

100 :名無しさん@お腹いっぱい。:2007/09/13(木) 13:23:47
>>99

新入社員です^^;


シェルスクリプトを勉強し始めましたが
自分で作れるほどにはなっていなくて><

101 :名無しさん@お腹いっぱい。:2007/09/13(木) 18:09:32
緊急なんだ、誰かいい知恵を貸してはもらえませんか?

CPU使用率を跳ね上げた状態で試験がしたいのです。
それで、CPU使用率がバカ上がる(目標90%)シェルかスクリプトを簡単に作りたいんです。

Whileでfindやgrepやsortをまわしたんですが、70%越えが精一杯。
もっと凶悪なものないでしょうか?


102 :名無しさん@お腹いっぱい。:2007/09/13(木) 18:19:13
>>101
while :; do :; done
とかは?

103 :名無しさん@お腹いっぱい。:2007/09/13(木) 18:21:52
>>102
whileで無限ループはかけてますよ。

104 :名無しさん@お腹いっぱい。:2007/09/13(木) 18:33:29
いやその、IO待ちなどが発生するコマンドを起動するんじゃなくて、
単にシェルのなかでビジーループするだけのほうがCPU占有するだろうと
思えるから書いたんだが。

105 :名無しさん@お腹いっぱい。:2007/09/13(木) 18:44:01
>>102 で正解だよ。
>>103 みたいな、恩を仇で返すような質問者にはなりたくないなぁ

106 :名無しさん@お腹いっぱい。:2007/09/13(木) 19:03:59
実はcoreが2個あるとエスパー



107 :名無しさん@お腹いっぱい。:2007/09/13(木) 19:06:19
hoge() { hoge & hoge; }; hoge

実験注意

108 :名無しさん@お腹いっぱい。:2007/09/13(木) 19:13:45
やあ (´・ω・`)

ようこそ、バーボンハウスへ。
このしょっぱいロールケーキはサービスだから、まず食べて落ち着いて欲しい。

実は、君に一生セクロス出来ない呪いをかけたんだ。
うん、「また」なんだ。済まない。
仏の顔もって言うしね、謝って許してもらおうとも思っていない。

↓このスレに「こんばんは、プッシーキャットです」とレスすれば呪いは解ける。
http://ex21.2ch.net/test/read.cgi/voiceactor/1189073996/


じゃあ、注文を聞こうか。


109 :102:2007/09/13(木) 19:29:23
>>103-105
すみません、無知だったもので勘違いしてしまいました。
それで組んでやってみます。

ほんとありがとうございます。

110 :名無しさん@お腹いっぱい。:2007/09/13(木) 20:02:20
>>109
どうでもいいが、君は>>101かな?
レス番ずれとるぞ

111 :名無しさん@お腹いっぱい。:2007/09/13(木) 23:40:34
>>94
それのどこがファイル表示してんだ?wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
ばかばっかりwwwwwww

112 :名無しさん@お腹いっぱい。:2007/09/14(金) 00:12:41
    _, ._
  ( ・ω・)んも〜
  ○={=}〇,
   |:::::::::\, ', ´
、、、、し 、、、(((.@)wwwwwwwwwww

113 :名無しさん@お腹いっぱい。:2007/09/14(金) 00:36:44
>>111
 >>94は「行頭行末の空白が出ない」って言いたいんだろ。 >>60 参照。


114 :名無しさん@お腹いっぱい。:2007/09/14(金) 19:39:12
シェルスクリプトって、キーボードから入力する代わりに
ファイルからコマンドラインを読み込んでるだけですよね?
だったら、なぜシェルスクリプトのモード(?)の時は、
プロンプトが出ないんですか?
プロンプトを出す方法はありますか?

115 :名無しさん@お腹いっぱい。:2007/09/14(金) 20:25:19
ランダムな時間、例えば1分〜30分程度の間でランダムにsleep
させたいのですが、bashで乱数を発生させるのにはどうすれば
良いでしょうか?

何に使うかというと、

OSはCentOS5.0です。NFSサーバが一台、NFSクライアントが100台です。
NFSクライアントの個々のlocal HDDのファイルを土曜深夜に
自動バックアップさせようと思っていますのでcrontabに一行
書こうと思っています。1台あたりのバックアップは10秒もか
かりません。

うんで、100台が一斉にバックアップはじめるとサーバが死ぬので
ランダムにsleepを居れたいのですが、、、

100台のcrontabの時間を1分刻に変更してくなんて、めんどくさい
にょろ。

116 :名無しさん@お腹いっぱい。:2007/09/14(金) 20:27:50
>>115

sleep $((RANDOM*1800/32768))

117 :115:2007/09/14(金) 20:30:51
>>116
ありがとうございました。

118 :名無しさん@お腹いっぱい。:2007/09/14(金) 20:32:04
ばっしゅ、うぜーーーーーーーーーーーーーーーーーーーー

119 :名無しさん@お腹いっぱい。:2007/09/14(金) 21:03:49
>>115
次はこっちで聞こうな。
シェルスクリプト総合@LINUX Part3
http://pc11.2ch.net/test/read.cgi/linux/1184077033/

120 :名無しさん@お腹いっぱい。:2007/09/14(金) 21:25:44
>>114
>ファイルからコマンドラインを読み込んでるだけ

違う。
プロンプトではコマンドラインしか実行できないが、
シェルスクリプトではコマンドラインの他、
if文とかfor文とか、変数の代入とかもできるようになる。

そもそも別物なので、プロンプトは出ない。

121 :名無しさん@お腹いっぱい。:2007/09/14(金) 21:49:47
おいおい初心者に嘘を教えるなよ

122 :名無しさん@お腹いっぱい。:2007/09/14(金) 22:08:09
プロンプトからはfor文とか使えないよ。

$ for i in hoge
for: Command not found.

って出るし。
変数も使えない。

$ HOGE=hage
HOGE=hage: Command not found.

123 :名無しさん@お腹いっぱい。:2007/09/14(金) 22:33:15
自作自演ですか

124 :名無しさん@お腹いっぱい。:2007/09/14(金) 22:46:57
>>114
シェルがプロンプトを出力するのは、ユーザに入力を受け付ける事ができるようになった事を表すため。
なので、基本的にその必要のない、非対話的(>シェルスクリプトのモード)な動作をするときはプロンプトを出力しない。
この対話的、非対話的であるということは起動時に決定され移行する手段もないためスクリプト実行中にプロンプトを出力する事は出来ない。


125 :名無しさん@お腹いっぱい。:2007/09/14(金) 23:37:55
>>124
set -i すればプロンプト出るよw

126 :124:2007/09/15(土) 00:25:37
>>125
そっか。知らんかった。
上の部分はおk?


127 :名無しさん@お腹いっぱい。:2007/09/15(土) 08:45:14
>>111
これで満足か? イケヌマ君。www

echo " aaa" >file
while read line; do echo $line; done <file

128 :名無しさん@お腹いっぱい。:2007/09/16(日) 21:05:08
>>122
こんなどうしようもないショボい釣り針は初めて
うっかり釣られたけど、どうやったらこんなショボいこと浮かぶの?

129 :名無しさん@お腹いっぱい。:2007/09/16(日) 21:08:42
>>128
本当に使えないんですが,,,
使えるようになる設定とかあるんですか???

130 :名無しさん@お腹いっぱい。:2007/09/16(日) 21:21:06
コマンドラインでは制御文は使えないよ。
もし使えたらおかしなことになるだろ。
例えば forだったら、doneコマンドを実行したら
doコマンドのところまで後ろにジャンプしないといけない。
コマンドラインでは、打ったコマンドを順番に実行するだけだから、
後ろに戻るような動作はできない。
forを使いたきゃ、シェルスクリプトに一旦書くしかない。

131 :名無しさん@お腹いっぱい。:2007/09/16(日) 21:51:01
>>129
コマンドラインでfor文を使いたければ、Cシェル系(foreach)でも使ったら?

132 :名無しさん@お腹いっぱい。:2007/09/16(日) 22:02:42
>>129
もしかしてマジ?そんな環境があるのか知らないけど
取り合えず以下でも受け付けない?

for x in a b; do echo $x ; done

133 :名無しさん@お腹いっぱい。:2007/09/16(日) 22:09:27
$ for x in a b; do echo $x ; done
for: Command not found.
x: Undefined variable.

134 :名無しさん@お腹いっぱい。:2007/09/16(日) 22:18:59
くだらなさ全開。

$ csh
%set prompt='$ '
$ for x in a b; do echo $x;done
for: Command not found.
x: Undefined variable.

135 :名無しさん@お腹いっぱい。:2007/09/16(日) 22:20:51
すまん、マジならどんな環境?/bin/shだよね?
まじですまないがググらんと原因が分からないんでパス


136 :名無しさん@お腹いっぱい。:2007/09/16(日) 22:26:14
cshで一般ユーザのプロンプトを$にするとかどんだけ・・・
いやプロンプトをどうするかは自由だけどね

137 :名無しさん@お腹いっぱい。:2007/09/17(月) 10:19:56
某、犬式配布系では cshのプロンプトのデフォが $ に設定されてるね。

138 :名無しさん@お腹いっぱい。:2007/09/17(月) 18:50:07
そうなんだ
でも >>129-131 の時点で自演に気付けなかった自分にorz
参りました一生romってます

139 :名無しさん@お腹いっぱい。:2007/09/18(火) 19:37:25
初心者です。

非常に簡単なスクリプト、たとえば以下のような場合ですが
このままでいいのですかね?

もうちょっとスクリプトらしく書けとかありません?^^;
役割果たすならシンプルが一番なのかもしれませんが
シェルスクリプトというよりコマンドの羅列なので・・


#!/bin/sh
ls -i /var/log/syslog > var/log/check.log
date >> var/log/check.log

140 :名無しさん@お腹いっぱい。:2007/09/18(火) 20:15:57
>>139
var/log/check.logを、わざわざ相対PATHで書いてるのはなぜ?
これだと、このシェルスクリプトを / で実行しないと
期待通り動かないよ。
もうちょっとシェルスクリプトらしくするには、
例えば↓

#!/bin/sh

CHECK_LOG=/var/log/check.log
{ ls -i /var/log/syslog; date; } > $CHECK_LOG

141 :139:2007/09/18(火) 22:35:51
>>140
おぉー、シェルスクリプトになっていますね。
こういうのは慣れなのでしょうか^^;

相対パスになっていたのも気がつきませんでした。
これも慣れるんでしょうかね・・

がんばります。アドバイスどうもありがとうございました。

142 :名無しさん@お腹いっぱい。:2007/09/18(火) 23:10:07
俺だったら

#!/bin/sh

CHECK_LOG=/var/log/check.log

exec > $CHECK_LOG

ls -i /var/log/syslog
date

143 :139:2007/09/19(水) 00:41:33
>>142
レスありがとうございます。
なるほど、execコマンドって便利そうですね。
本で読んでみましたが最初よくわかりませんでしたw
リダイレクトの章を読んでで納得^^

こんな簡単な処理でもいろんな書き方があって
奥が深いですねヽ(´ー`)ノ

144 :名無しさん@お腹いっぱい。:2007/09/19(水) 08:11:38
>>143
>>142 は半分ネタだろ。真に受けるなw
execリダイレクトしてしまうと、今後この後に別のコマンドを追加した場合、
すべてリダイレクトされてしまって、保守性の悪いスクリプトになる。

145 :名無しさん@お腹いっぱい。:2007/09/19(水) 08:29:17
/root/test.txt
/root/test.1.txt
/root/test-1.txt
があります。

find / -regex "/root/[a-z0-9\-\.]+\.txt"
としても
/root/test-1.txt
だけ見つかりません。
\.をはずすと
なぜか
/root/test-1.txtが見つかるのですが、これはなぜでしょうか?

146 :名無しさん@お腹いっぱい。:2007/09/19(水) 08:40:10
>>145
正規表現の [ ] の中で、\ は意味ないわけだが。\- としてもだめ。

147 :名無しさん@お腹いっぱい。:2007/09/19(水) 08:41:11
正規表現についてはスレ違いなのでよろしこ

148 :145:2007/09/19(水) 08:54:43
単純に正規表現単一の問題というよりは、
find での正規表現の利用の
仕方が関係ある気がします。

perl互換の正規表現を使ってperlなどでは
[a-z-.]でいけるんですが、
find でこれを使うと Invalid range end が表示されてしまいます。

149 :名無しさん@お腹いっぱい。:2007/09/19(水) 09:04:42
単純に正規表現単一の問題ですね。

150 :名無しさん@お腹いっぱい。:2007/09/19(水) 09:33:06
>>148
find /root -regex "/root/[-.a-z0-9]+\.txt"

151 :名無しさん@お腹いっぱい。:2007/09/19(水) 09:35:01
root 常用すんな。

152 :名無しさん@お腹いっぱい。:2007/09/19(水) 18:54:59
>>107 ってなんで実験注意なの?

153 :名無しさん@お腹いっぱい。:2007/09/19(水) 20:16:33
>>152
見た感じfork爆弾なのかなと思ったけど、どうなんだろ。

#!/bin/sh
$0 & $0 &

でよさそーな気もする。


154 :名無しさん@お腹いっぱい。:2007/09/20(木) 13:26:36
{cd /tmp ; ls}
この{}の意味って何なのでしょうか?
()のサブシェルとの違いは?

155 :名無しさん@お腹いっぱい。:2007/09/20(木) 13:28:51
>>154
意味以前に、{ } の文法間違ってる。それでは正しく動かない。

156 :名無しさん@お腹いっぱい。:2007/09/20(木) 15:53:30
>>155
zshなら動くみたい

>>154
cd; foo=''; { cd /tmp; foo=bar; }; pwd; echo $foo

cd; foo=''; (cd /tmp; foo=bar); pwd; echo $foo
を実行してみればわかるかも

157 :名無しさん@お腹いっぱい。:2007/09/20(木) 16:21:49
zshうぜーーーーー

158 :名無しさん@お腹いっぱい。:2007/09/20(木) 17:31:38
シェルスクリプトで変数が使えないんですが、どうしてでしょう?
もちろん、SHELL=/bin/sh と、あらかじめ設定されてます。

#!$SHELL

echo helloworld

159 :名無しさん@お腹いっぱい。:2007/09/20(木) 17:35:19
  (  ゚д゚) 

  ( ゚д゚ )

  ( ゚д゚ ) 

160 :名無しさん@お腹いっぱい。:2007/09/20(木) 17:44:06
つまんね。

161 :名無しさん@お腹いっぱい。:2007/09/20(木) 17:45:31
exportし忘れてるんじゃねーの?

162 :名無しさん@お腹いっぱい。:2007/09/20(木) 18:00:59
zshなら動くみたい


163 :名無しさん@お腹いっぱい。:2007/09/20(木) 20:12:04
>>161
exportは既にしています

>>162
ありがとうございます。zshにしたら動きました

164 :名無しさん@お腹いっぱい。:2007/09/22(土) 18:06:21
testコマンドでファイルサイズの比較のオプションは用意されてないのでしょうか?
ls fileA | awk '{print $5}' ってな感じで抜き出して比較しないとダメですか?


165 :名無しさん@お腹いっぱい。:2007/09/22(土) 18:26:34
>>164
testコマンドではファイルサイズが0かどうかの判定しかできないね。
ls | awk じゃ無駄。
wc -c を使うと良い。

if [ `wc -c < fileA` -gt `wc -c < fileB` ]; then

みたいに。

wc -cの結果にファイル名が出ずにファイルサイズの数字のみになるように、
wc -c fileA じゃなくて wc -c < fileA にするのがコツ。

166 :名無しさん@お腹いっぱい。:2007/09/22(土) 18:48:12
MacOSX(BSD)とGNU版のマニュアルをみただけだが……
wcの-cオプションて国際化されててもバイト数を返すんだな。
-mで文字数か。


167 :名無しさん@お腹いっぱい。:2007/09/23(日) 00:40:46
ファイルの情報をとるなら stat コマンドも便利だが
どのへんのOSに入ってるかまでは把握してない...

168 :名無しさん@お腹いっぱい。:2007/09/23(日) 03:12:27
>>167
Coreutils か Shellutils じゃなかったっけ?

169 :名無しさん@お腹いっぱい。:2007/09/23(日) 05:30:15
coreutilsだけど、割と新しいコマンドじゃなかった?

170 :名無しさん@お腹いっぱい。:2007/09/23(日) 11:20:40
Linuxだとcoreutilsで、coreutilsのstatだと、
stat -c %s file
で、ファイルサイズだけ表示できるが、

FreeBSDのstatはcoreutilsのではなくて、
オプションは違うし、互換性がない。

Solarisではstatはない。

171 :名無しさん@お腹いっぱい。:2007/09/25(火) 10:35:27
互換性を気にする場合は tcsh のビルトインを使うとよろし。
tcsh がない OS もあるけど、stat よりはマシ。

tcsh -fc 'filetest -Z filename'


172 :名無しさん@お腹いっぱい。:2007/09/25(火) 10:37:40
>>171
いや、tcsh使うくらいなら >>165 の wc -c < file で決まりだろ。

173 :名無しさん@お腹いっぱい。:2007/09/25(火) 10:39:10
全部なめるしかないのかねぇ。

174 :名無しさん@お腹いっぱい。:2007/09/25(火) 10:41:54
>>172
wc はファイルをオープンするので read permission がないファイルでコケるし、
読めても巨大なファイルでは I/O に時間がかかる。
filetest はその問題はない。


175 :名無しさん@お腹いっぱい。:2007/09/25(火) 10:45:05
>>173-174
おいおい、本気でファイルなめると勘違いしてたのかよ。

wc -c < file ならファイルはなめないよ。
open()して、ファイルサイズ取得するだけ。
巨大なファイルでも一瞬。

176 :名無しさん@お腹いっぱい。:2007/09/25(火) 10:47:15
そんな言い方しなくたって・・・

177 :名無しさん@お腹いっぱい。:2007/09/25(火) 10:55:45
>wc -c < file ならファイルはなめないよ。

うんにゃ。実装依存なので期待しない方がいい。
俺の知ってるかぎりでは GNU の wc 以外でそれをやるものはない。
パーミッションの問題は変わらないし。


178 :名無しさん@お腹いっぱい。:2007/09/25(火) 11:16:07
FreeBSDのwcだと、

wc -c < file だとなめるけど、
wc -c file だとなめないね。

ファイル名表示されるのが邪魔だけど、
wc -c file の方使えばいいか。

179 :名無しさん@お腹いっぱい。:2007/09/25(火) 14:32:43
>>163 ってマジ? zshで試してみたけど、できないんだが…

180 :名無しさん@お腹いっぱい。:2007/09/25(火) 22:37:12
>>163 の元は >>158 ね。

181 :名無しさん@お腹いっぱい。:2007/09/26(水) 00:16:57
$ ls -l '$SHELL'
lrwxr-xr-x 1 root wheel 7 Sep 26 00:13 $SHELL -> /bin/sh
$ cat scr
#!$SHELL
echo a
$ ./scr
a

182 :名無しさん@お腹いっぱい。:2007/09/26(水) 10:18:40
これはひどいw

183 :名無しさん@お腹いっぱい。:2007/09/26(水) 12:20:36
>>178
ファイル名が表示されたら、そもそもの [ x -gt y ] が使えないとおも

184 :名無しさん@お腹いっぱい。:2007/09/26(水) 12:28:03
>>183

set `wc -c fileA`
A=$1
set `wc -c fileB`
B=$1

if [ $A -gt $B ]; then

185 :名無しさん@お腹いっぱい。:2007/09/26(水) 13:10:43
>>184
それだったら、↓の方が簡単

set `wc -c fileA` `wc -c fileB`
if [ $1 -gt $3 ]; then


186 :名無しさん@お腹いっぱい。:2007/09/26(水) 15:52:53
>>184
>>185

このsetの使い方ってどういうことなのでしょうか?
理解すれば幅が広がりそう。

187 :名無しさん@お腹いっぱい。:2007/09/26(水) 17:09:39
>>186
ポジショナルパラメータをセットする

188 :名無しさん@お腹いっぱい。:2007/09/27(木) 23:09:07
すいません。ご教示ください。
下記のような入力データから、ワークに1行入力して、

ABCDE 12
BC 123
A
BB
CCCCC 2

変数Xへ、2番目のフィールドを取り出す場合は
どうすればよいでしょうか。
もちろん、2番目で空白の場合は、0または読み
飛ばしする。

189 :名無しさん@お腹いっぱい。:2007/09/27(木) 23:24:54
普通に
while read dummy x; do
echo ${x:-null}
done < file


190 :名無しさん@お腹いっぱい。:2007/09/27(木) 23:32:34
>>189
ありがとうございました。勉強になりました。

191 :名無しさん@お腹いっぱい。:2007/09/29(土) 11:38:30
HP-UX上のBシェルです。

NGの場合:
# A=/
# expr substr A 1 1

シンタックスエラー

このシンタックスエラーになる理由がわかりません。Linux(Plamo)ではOKみたいす。

OKの場合:
# A=/a
# expr substr A 1 1
# /

勉強不足ですいませんが、ご教示ください。

192 :名無しさん@お腹いっぱい。:2007/09/29(土) 11:44:02
どうでもいいけど、Aじゃなくて$Aだよな?

HP-UXのexprがsubstrをサポートしていないんじゃないの?
LinuxのはGNU coreutilsのexprを使っていることが多いので、
いろいろ拡張されているよ。

Macの/bin/exprもsyntax errorになった。


193 :名無しさん@お腹いっぱい。:2007/09/29(土) 11:56:31
POSIXのexprの説明には
>The use of string arguments _length_, _substr_, _index_ or _match_ produces unspecified results.
とあるな。未定義ということは、鼻から悪魔が出てきてもOK。


194 :名無しさん@お腹いっぱい。:2007/09/29(土) 12:09:41
A じゃなくて $A じゃないの? と言う点に誰も突っ込まない件に付いて

195 :名無しさん@お腹いっぱい。:2007/09/29(土) 12:17:46
ありがとうございます。
>>192 193
よくわかりませんが、未定義の動作かも知れませんね。

196 :名無しさん@お腹いっぱい。:2007/09/29(土) 12:28:35
>>194
>>192

197 :名無しさん@お腹いっぱい。:2007/09/29(土) 12:36:01
exprに限らず、互換性の点からコマンドの拡張オプションには
ほとんど対応していないことが多いSolarisのexprでさえ、
substrには対応してる。POSIXがどう言っていようが、
業界標準的にはexprはsubstrが使えるべきだろう。

198 :名無しさん@お腹いっぱい。:2007/09/29(土) 12:42:14
FreeBSDの exprでは使えないね。

ポータビリティ考えたら、exprじゃなく、
echo $A | cut -b1
を使うべきだな。

199 :名無しさん@お腹いっぱい。:2007/09/29(土) 12:42:25
>>197
確かに互換性を考慮するれば、使えるべきですね。
特定の場合だけ、エラーになるということは、(HP-UX)の不具合なのかも
知れませんね。

200 :名無しさん@お腹いっぱい。:2007/09/29(土) 12:44:04
>>198
別な方法があるのですね。勉強になります。

201 :名無しさん@お腹いっぱい。:2007/09/29(土) 12:46:16
>>198
古い cutでは -bオプションが使えない。
cut使うなら↓にするべき。

echo $A | LANG=C cut -c1

202 :名無しさん@お腹いっぱい。:2007/09/29(土) 13:01:47
再びの質問ですいません。
変数$Aに "/etc 123" という文字列情報(空白がある)があった場合、
123を取り出したい場合は、どうすればよいでしょうか。

"AAA /etc 123"
"AAA BBB /etc 45"

という場合もあり、一番右側の数値だけを取り出したい場合です。

203 :名無しさん@お腹いっぱい。:2007/09/29(土) 13:10:47
>>202

A='AAA BBB /etc 45'

set $A
shift `expr $# - 1`
echo $1

204 :名無しさん@お腹いっぱい。:2007/09/29(土) 13:16:20
>>203
なるほど、ありがとうございます。勉強になります。
# スキル不足のため、トライ・エラー繰り返しです。(泣)

205 :名無しさん@お腹いっぱい。:2007/09/29(土) 20:31:47
もっとシンプル

echo ${A##* }

206 :名無しさん@お腹いっぱい。:2007/09/29(土) 21:22:12
>>205
Bourne shellの範囲外。失格。

207 :名無しさん@お腹いっぱい。:2007/09/29(土) 21:28:07
A='AAA BBB /etc 45'

expr "$A" : '.* \([^ ]*$\)'

208 :名無しさん@お腹いっぱい。:2007/09/29(土) 21:36:37
expr "$A" : '.* \([^ ]*$\)'

上記の意味は、日本語で解説していいただかないとわかないです。

209 :名無しさん@お腹いっぱい。:2007/09/29(土) 21:48:38
いや、ここは外部コマンドなしが美しい。

A='AAA BBB /etc 45'

set $A; while [ $# -gt 1 ]; do shift; done
echo "$1"

210 :名無しさん@お腹いっぱい。:2007/09/29(土) 21:53:33
      /     \
     /  / ̄⌒ ̄\
     /   / ⌒  ⌒ |   | ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
    | /  (・)  (・) |   | てめーなんだよこの糞スレは!!
  /⌒  (6     つ  |   | てめーは精神障害でもあんのか?
 (  |  / ___  |  < 何とか言えよゴルァァァァァァ!
  − \   \_/  /    \__________________
 //  ,,r'´⌒ヽ___/     ,ィ
   /    ヽ       ri/ 彡
  /   i    ト、   __,,,丿)/        ζ           
 |    !     )`Y'''" ヽ,,/      / ̄ ̄ ̄ ̄\        
  ! l   |   く,,   ,,,ィ'"      /.         \ 
  ヽヽ  ゝ    ! ̄!~〜、       /           |    
  ヽ  / ̄""'''⌒ ̄"^'''''ー--、 :::||||||||||||||||||||||||||||||||| 
  Y'´          /    """''''〜--、|||||||||||||||||) 
   (      丿  ,,;;''  ....::::::::::: ::::r''''"" ̄""ヽ   |
   ゝ   ー--、,,,,,___      ::: ::,,,,,ー`''''''⌒''ーイ  ./
     ヽ      \  ̄""'''"" ̄   \____/-、
     ヽ       ヽ  :::::::::::::::::::: /          `ヽ
      ヽ  丿   )       /    ノ   ゝ ヽ ,〉
       ゝ      !      /            ∀
        !     |      /   人     ヽ   ヽ
        |     ,;;}      !ー-、/  ヽ _,,,-ー'''''--ヘ
          |ノ    |      |  /    Y        ヽ
         {     |      |   j      )  >>1     ヽ

211 :名無しさん@お腹いっぱい。:2007/09/29(土) 22:10:12
>>206
POSIXだから範囲内。 俺の圧勝。

212 :名無しさん@お腹いっぱい。:2007/09/29(土) 23:06:00
>>211
そういう問題じゃない。Solarisでは動かないし。

213 :名無しさん@お腹いっぱい。:2007/09/29(土) 23:10:47
##とか%%ってPOSIXだったっけ


214 :名無しさん@お腹いっぱい。:2007/09/29(土) 23:14:12
>>213
POSIXではあるが、実際の使用は推奨されない。

215 :名無しさん@お腹いっぱい。:2007/09/30(日) 00:21:16
>>212
xpg4使えばいい。

216 :名無しさん@お腹いっぱい。:2007/09/30(日) 00:27:23
>>215

各OS共通で
#!/bin/sh
って書くのに、どうやってxpg4を使うって言うんだい。

#!/usr/xpg4/bin/sh
なんてスクリプト見たことないし、
逆に、こう書いてしまうとSolaris以外で動かなくなる。

217 :名無しさん@お腹いっぱい。:2007/09/30(日) 00:30:03
>>215
NEWS-OS(4) で動かない。xpg4もない。

218 :名無しさん@お腹いっぱい。:2007/09/30(日) 00:40:36
>>217
NEWS-OSまで遡らなくても、SunOSでも動かないよw 当然 xpg4も無い。

219 :名無しさん@お腹いっぱい。:2007/09/30(日) 00:45:53
>>216
それはお前がへぼだから。POSIX shellであることを判定して偽なら
/usr/xpg4/bin/shをexecするとか幾らでも方法はある。

>>217-218
はいはい。板違い。
http://bubble6.2ch.net/i4004/

220 :名無しさん@お腹いっぱい。:2007/09/30(日) 00:48:52
>>219
POSIX shellであることを判定して偽なら
/usr/xpg4/bin/shをexecしているような
シェルスクリプトを未だに見たことがないがw

あと、>>217-218 が言うように xpg4がないOSではどうすんだよwww

221 :名無しさん@お腹いっぱい。:2007/09/30(日) 00:53:57
## とか %% とか使わなくても書けるのに、
わざわざ動作環境限定して ## とか %% とかで書くことはない。

222 :名無しさん@お腹いっぱい。:2007/09/30(日) 01:04:25
kshつかえ

223 :名無しさん@お腹いっぱい。:2007/09/30(日) 01:07:02
kshが標準では入っていないOSは多数ある

224 :名無しさん@お腹いっぱい。:2007/09/30(日) 01:23:43
いいからつかえ

225 :sage:2007/09/30(日) 01:33:53
限定ユーザでrootユーザのコマンドってうつ方法ってあるの?

226 :名無しさん@お腹いっぱい。:2007/09/30(日) 01:36:08
何言ってんの?

227 :名無しさん@お腹いっぱい。:2007/09/30(日) 01:42:26
>>219
何で「昔のPC」なんだ?
NEWS-OSってSVR4系UNIX-WSなんだけど。

>>222, 224
客からcshでスクリプトを書くよう強制されたときの事を思い出す。
ファイルのクローズができなくて大変だったな....
ところで、 >>223 のようなkshの無い環境で、顧客からの許可が得られない場合、どうやってkshをつかえばいいのか、教えていただけますか?
それだけ強く要求するのですから、きっと万能な解決策をごぞんじなんでしょう?

228 :名無しさん@お腹いっぱい。:2007/09/30(日) 07:19:29
zsh! zsh!

229 :名無しさん@お腹いっぱい。:2007/09/30(日) 08:51:16
>>220
シェルスクリプトを異機種間で共有することは稀だからな。
お前が共有したい(#!/usr/xpg4/bin/shは嫌だ)と言い出したんだぞ。

>>221
POSIXを仮定すれば、1ワードで書けるものを水増しする必要は無い。

>>227
保守切れてるWSなんてゴミだよ。
そもそもまともなところなら、セキュリティパッチが出ないマシンは
ネットワーク接続禁止。だから昔のPC。

>>227
そんな仕事受けない。
見積もりで3倍くらいふっかける、それだけ手間がかかるんだから当たり前だ。

230 :名無しさん@お腹いっぱい。:2007/09/30(日) 08:58:06
>>229
シェルスクリプトは異機種間で共有する際に威力を発揮する。
異機種間で共有する必要がないならC言語で書いた方がいい。

たとえば、GNUのconfigureスクリプトとか。
異機種間で共有できなければそもそもconfigureの目的を果たせない。

231 :名無しさん@お腹いっぱい。:2007/09/30(日) 09:33:00
また宗教論争かyo

>>230
configureスクリプトはautomake/autoconfに吐かせる(つまり自分では書かない)
のが普通でしょう
手書きしないのは、それが一種の黒魔術でありバッドノウハウのカタマリであるから、
といっていいんじゃないのかな

232 :名無しさん@お腹いっぱい。:2007/09/30(日) 13:49:59
>>231
自分でconfigure.inとか書いたことない人?
カスタムルール書こうとすると自分でシェルスクリプト(+m4)書かなきゃ
いけないんですけど。
んでその断片がLinux依存になってたりすることもままある。

233 :名無しさん@お腹いっぱい。:2007/09/30(日) 14:25:45
>>232
あなたのその見解が、何故>>231への反論になりえるのかが理解できない。

汚い泥仕事は自動化したい・最小化したいが
完全に自動化できない場合があるからその場合は仕方なく泥仕事を
自分でやる必要がある、というだけのことでしょう。

それが泥仕事であることの否定にはなっていませんよ。

234 :233:2007/09/30(日) 14:28:54
ああ、ちょっと俺のほうが言ってることがおかしいか。

問題はポータブルなスクリプトを書くのが泥仕事であるかどうかではなく、
そういう必要性があるかどうか、の話だったね。

それなら、ある人にとってはあるでしょうし、無い人にとってはないでしょう。
TPOをわきまえずに常にポータブルに書けというのはナンセンスだと思いますが。

235 :名無しさん@お腹いっぱい。:2007/09/30(日) 14:35:50
>>233
それをSolarisやNEWS-OSで動かないと文句言ってる奴に言ってやれ。

236 :名無しさん@お腹いっぱい。:2007/09/30(日) 14:38:11
まあ何だ、わけの分からない先人の遺産をひきついで移植にヒイヒイいった
経験のある老害の愚痴なんだろうから
そっとスルーしといてやれ

237 :名無しさん@お腹いっぱい。:2007/10/01(月) 13:17:21
POSIXLY_CORRECT=true; export POSIXLY_CORRECT

238 :名無しさん@お腹いっぱい。:2007/10/01(月) 14:32:13
POSIXLY_CORRECT=true にセットしても、実際にはほとんど何も変わらない(解決にならない)よ。

239 :名無しさん@お腹いっぱい。:2007/10/01(月) 19:13:07
相対パスを絶対パスに変換する方法はありますでしょうか?

cd /usr/
FULL_PATH=`getfullpath "A/B"`
echo $FULL_PATH

で /usr/A/B を出力、といったようなことがしたいのです

240 :名無しさん@お腹いっぱい。:2007/10/01(月) 19:36:12
PWD=`pwd`
FULL_PATH=$PWD/"A/B"
.とか..とかあったら知らんが絶対パスには違いない。

241 :名無しさん@お腹いっぱい。:2007/10/01(月) 20:01:24
>>240
単に `pwd` だと、シェルによってはシンボリックリンクを解決しないPATHを返してしまう。
`/bin/pwd` にした方が良い。シェルによっては `pwd -P`も使える。

242 :名無しさん@お腹いっぱい。:2007/10/01(月) 21:34:34
getfullpath()
(
cd ${1%/*} && echo `/bin/pwd`/${1##*/}
)


243 :名無しさん@お腹いっぱい。:2007/10/01(月) 22:14:03
だからぁ、%% ## の類は Bourneじゃ使えないんだって。
dirname basenameあるんだからそれ使えよ。

244 :名無しさん@お腹いっぱい。:2007/10/01(月) 23:13:12
断る。

245 :名無しさん@お腹いっぱい。:2007/10/01(月) 23:15:26
というか、realpath っていうそのものずばりのコマンドあるじゃんw

246 :名無しさん@お腹いっぱい。:2007/10/01(月) 23:27:38
俺のNEWS-OSに入ってないようなOS依存のコマンドは禁止

247 :239:2007/10/01(月) 23:39:15
レスありがとうございます

環境はMac OS Xですがrealpathはコマンドラインとしてはないようです(関数はある)

pwdでも良さげですがpwdが返すパスは必ず/で終わっていない、という保証もなさそうで
ちょっと不安なので、自分でrealpathのような事をするツールを作る事にします。

248 :名無しさん@お腹いっぱい。:2007/10/01(月) 23:45:16
>>247
pwdが返すpathは、/ディレクトリ以外は / では終らないよ。

だから、`pwd`/A/B とする場合に、/ に居る場合のみ、
pwdの結果の単独の / を取り除く処理が要るね。

249 :名無しさん@お腹いっぱい。:2007/10/01(月) 23:46:18
ご教示ください。
変数Aの中を、キーワード検索するには、どうすれば
よいでしょうか。たとえば、/usr があるかどうかを検索
したい場合、キーワードはランダムな位置にある。

A="aaaaa /usr bbb 789 ccc"
       ↑キーワード

250 :名無しさん@お腹いっぱい。:2007/10/01(月) 23:48:51
>>246
GK乙

251 :名無しさん@お腹いっぱい。:2007/10/01(月) 23:49:21
>>249
普通に、

case $A in */usr*) /usrがあった場合の処理;; esac

252 :名無しさん@お腹いっぱい。:2007/10/01(月) 23:53:47
>>251
どうも、ありがとうございます。ちょっと実現に向けてがんばってみます。

253 :名無しさん@お腹いっぱい。:2007/10/02(火) 01:36:48
ご教示ください。

aaaa,bbbb
bbbb,cccc
aaaa,cccc
bbbb.aaaa
aaaa,dddd
bbbb,eeee

こんな感じにならんでいるものを

aaaa,bbbb
aaaa,cccc
aaaa,dddd
bbbb,cccc
bbbb,aaaa
bbbb,eeee

と並べ替えたいのですが、どうやればいいでしょうか。

254 :名無しさん@お腹いっぱい。:2007/10/02(火) 01:44:11
>>253
普通に sort の -k あたり使えばいいんじゃね?
man sort 参照。

255 :名無しさん@お腹いっぱい。:2007/10/02(火) 01:47:32
>>254
すみません。書いた後気がつきました^^;
お手数かけました。

256 :名無しさん@お腹いっぱい。:2007/10/03(水) 00:07:24
教えてください。
標準出力をif文の制御をパイプでつなぎたいですが、
下記の例で、if文の制御で可能でしょうか、だめの場合は、
別な方法はあるでしょうか。

例:
if [[ $? -nq 0 ]]; then
ls -x |
else
cat /etc/hosts |
fi
while read line
do
:



257 :名無しさん@お腹いっぱい。:2007/10/03(水) 00:29:38
日本語でおkだが、

if [[ $? -nq 0 ]]; then
ls -x
else
cat /etc/hosts
fi |


258 :名無しさん@お腹いっぱい。:2007/10/03(水) 00:33:08
>>257
どうもありがとうございます。やってみます。

259 :名無しさん@お腹いっぱい。:2007/10/03(水) 01:40:42
[[ ]]ってなんだよ。

260 :名無しさん@お腹いっぱい。:2007/10/03(水) 01:44:11
bash は犬板へ

261 :名無しさん@お腹いっぱい。:2007/10/03(水) 01:48:58
大阪にみえた。もう寝よう。

262 :名無しさん@お腹いっぱい。:2007/10/03(水) 07:35:15
[[ ]] も POSIXでは OKだよ。bashじゃない。
でも、bourneで使えないから、[[ ]] は普通使うべきじゃない。
## %% を使うべきじゃないのと同じ。

263 :名無しさん@お腹いっぱい。:2007/10/03(水) 08:03:05
俺的には
-nq
のほうが引っかかるのだが、
何でみんなスルーするのだ?

264 :名無しさん@お腹いっぱい。:2007/10/03(水) 20:38:08
申し訳ないです。

then節またはelse節がエラーになった場合、
標準出力をパイプに渡したくないするのに、よい方法
はあるでしょうか。エラーがあった場合は、メッセージ
を出したexitするようなことはできないでしょうか。


if [ $? -nq 0 ]; then
 ls -x      ← エラーがあった場合
else
 cat /etc/hosts ← エラーがあった場合
fi |
while read line
do
:

265 :名無しさん@お腹いっぱい。:2007/10/03(水) 20:42:50
>>264
エラーがあった場合、

echo 'エラーメッセージ' 1>&2
exit

とすればいいだけ。標準エラー出力に出るので、
パイプには渡されない。


-nq はいい加減に直せよ

266 :名無しさん@お腹いっぱい。:2007/10/03(水) 21:14:47
>>265
-nq を -ne に修正します。

ようわからないのですが、
正常ケースだと、echoで指定したメッセージが渡されて
しまいそうなんですが。

267 :名無しさん@お腹いっぱい。:2007/10/03(水) 21:31:46
>>266
正常ケースについては言っていない。

エラーが出た場合のエラーメッセージの出し方を言っているのだが。

もしかして、$? での判断の方法とか知らないの?

268 :名無しさん@お腹いっぱい。:2007/10/04(木) 00:38:55
パイプの前に||を入れて、{}かなんかで>265のを囲う。みたいな?

269 :名無しさん@お腹いっぱい。:2007/10/04(木) 03:16:20
>>268
パイプの前で exit してもスクリプト自体は終了しないから
>>265 を入れてもあまり意味が無いんじゃね?


270 :名無しさん@お腹いっぱい。:2007/10/04(木) 06:46:06
>>269
while read で、パイプから読もうとしているから、
broken pipe で終了するよ。

もし、パイプの先が標準入力(=パイプ)を読まないコマンドばかりだったら
確かにすぐには終了しないけどね。

よって、>>265 で正解。

271 :名無しさん@お腹いっぱい。:2007/10/04(木) 20:53:04
すみません。基本的なことかも知れませんが、
シェルを書く時、まず最初の方で、
#!/bin/sh みたいに、シェルをインクルードしますよね。
でも、この前インクルードしなくても動いてしまったんですよ。
結局インクルードは必要ないんでしょうか?
Cで、printf()を使う程度だったら<stdio.h>を
インクルードしなくていいのと同じですか?

272 :名無しさん@お腹いっぱい。:2007/10/04(木) 21:42:37
>>271
シェルスクリプト総合 その4
http://pc10.2ch.net/test/read.cgi/unix/1131026501/33-

http://www.bookshelf.jp/2ch/unix/1131026501.html

273 :名無しさん@お腹いっぱい。:2007/10/05(金) 08:31:25
シェルをインクルードとはまた新しい概念だな。

274 :名無しさん@お腹いっぱい。:2007/10/05(金) 08:54:33
インクルード=オマジナイ

275 :名無しさん@お腹いっぱい。:2007/10/05(金) 09:09:24
.はインクルードって言っていい?

276 :名無しさん@お腹いっぱい。:2007/10/05(金) 15:53:06
そっちかよ

277 :名無しさん@お腹いっぱい。:2007/10/07(日) 15:08:28
説明が難しいのですが

a=hoge
b=a

こういう時

echo "$b"
↓b=aなので
echo "$a"
↓a=hogeなので
hoge

みたいな処理をしたいのですができますでしょうか?

278 :名無しさん@お腹いっぱい。:2007/10/07(日) 15:21:34
eval echo \$$b

279 :名無しさん@お腹いっぱい。:2007/10/08(月) 05:23:27
ありがとうevalかー

280 :277:2007/10/08(月) 06:08:15
何度もすみません。
変数の中に変数を入れることはできないでしょうか?
自分の応用力の無さが嫌になります

hoge_A=AAA
foo=A

${hoge_$foo}
↓foo=Aなので
${hoge_A}

AAA


281 :名無しさん@お腹いっぱい。:2007/10/08(月) 06:29:01
>>280
eval "echo \"\${hoge_$foo}\"

>>277 ならbash 限定かもしれんが eval なしでもできる
echo "${!b}"



282 :名無しさん@お腹いっぱい。:2007/10/08(月) 08:02:57
>>280
eval echo \"\$hoge_$foo\"

変数の中に空白とかがなければ
eval echo \$hoge_$foo
でも桶。


>>281 のひとつ目の解答、ダブルクォートがおかしいよ。

283 :名無しさん@お腹いっぱい。:2007/10/08(月) 20:38:58
応用力のなさよりも、evalを理解しきれていない感じ?
>>278

入力: eval echo \$$b
↓ 変数展開($b)・エスケープ解釈
シェルが実行する文: eval echo $a
↓ そのevalコマンドを実行……
入力: echo $a ←←※
↓ 変数展開($a)
echo hoge

evalを使う式を作る場合は欲しい文※からスタートしてさかのぼればいい。

echo "$hoge_A" ←←※実行させたいケースの例
↓ Aを変数fooの参照に戻す・$などをエスケープ
echo \"\$hoge_$foo\"
↓ 頭にevalをつける
eval echo \"\$hoge_$foo\"

284 :277:2007/10/08(月) 21:08:00
皆さんありがとうございます。
283さんの解説を見つついろいろ試して理解しようと思います。


285 :名無しさん@お腹いっぱい。:2007/10/10(水) 02:28:09
横の行をsortするコマンドはないでしょうか?

echo 'aaa bbb aaa ccc" | sort

286 :名無しさん@お腹いっぱい。:2007/10/10(水) 02:53:48
echo "aaa bbb aaa ccc" | sed s/\ /\\n/g | sort

287 :名無しさん@お腹いっぱい。:2007/10/13(土) 10:12:10
>>285

sedでやる(置換して戻す二度手間が少しダサい)

echo "aaa bbb aaa ccc" | sed 's/ /\
/g' | sort | sed ':loop
N;s/\n/ /;$!b loop'

awkでやる(長い。一目見て何をしているのか解らない)
※とりあえず「行が長すぎる」と投稿時に怒られたので、分割しますたが元は一行です。

echo "aaa bbb aaa ccc" | \
awk '{ sizeOfArray = split($0,words," ")
  for (i = 2; i <= sizeOfArray; ++i) {
    for (j = i;(j-1) in words && wrods[j] < words[j-1]; --j) {
       tmp = words[j]; words[j] = words[j-1]; words[j-1] = tmp
    }
  }
    for (i = 1; i < sizeOfarray; ++i) printf("%s ",words[i])
  print words[i]
}'

sortアルゴリズムを工夫すると更に訳解らん一行コマンドになりそうw

288 :名無しさん@お腹いっぱい。:2007/10/13(土) 10:50:03
sed 's/ /\n/g;s/^/sort <<.\n/;s/$/\n.\n/;e
s/\n/ /g'


289 :名無しさん@お腹いっぱい。:2007/10/13(土) 11:26:44
普通にperl使えよ。

290 :名無しさん@お腹いっぱい。:2007/10/13(土) 11:43:34
awk+sed 使うんなら perl にするかなぁ。


291 :名無しさん@お腹いっぱい。:2007/10/13(土) 12:39:03
perl使ったら負け。sed awkだけで何とかするのが面白い。
ただし、awkを使う場合はawkだけにしてsedは使わないのが美しい。

292 :名無しさん@お腹いっぱい。:2007/10/13(土) 14:49:02
オナニーするのは勝手だがそういうのは独りで迷惑をかけないようにやれよ

293 :287:2007/10/13(土) 15:27:47
>>289

済みません。perl 知らないんですw
シェルスクリプトや sed,awk なんかも勉強し始めたばかりで、
もう少し上達したら、次は perl を学ぼうと思ってます。

294 :名無しさん@お腹いっぱい。:2007/10/13(土) 15:53:04
いるんだよなぁ、シェルで普通に書けるのに、わざわざperlで書くやつ。
ああいうの、まわりに迷惑かけてるよなぁ。

295 :名無しさん@お腹いっぱい。:2007/10/13(土) 17:32:28
「シェル」で書いてみろ。出来もしないことをゆうな。クズ。

296 :名無しさん@お腹いっぱい。:2007/10/13(土) 17:44:54
いつもシェルで書いてるよ。今さらなに言ってんの?w

297 :名無しさん@お腹いっぱい。:2007/10/13(土) 17:47:48
perlなら「書く」というレベルじゃない。コマンドラインで実行して使い捨て。

perl -ne 'print join(" ", sort(split(/\s+/))), "\n"'

298 :名無しさん@お腹いっぱい。:2007/10/13(土) 17:49:04
>>296
でた、口だけ番長。

299 :名無しさん@お腹いっぱい。:2007/10/13(土) 17:51:20
「シェルで書く」は別にいいだろ。

300 :287:2007/10/13(土) 18:12:06
>>297

便利ですね

でも私にはまだ早い。

301 :名無しさん@お腹いっぱい。:2007/10/13(土) 19:08:53
口だけ番長は>>285のお題を「シェル」でどのように解くのだ?

302 :名無しさん@お腹いっぱい。:2007/10/13(土) 20:56:42
>>299
「シェルをかく」と大して変わらん。
シェルはシェル、スクリプトはスクリプト。

303 :名無しさん@お腹いっぱい。:2007/10/13(土) 21:15:30
>>302
日本語大丈夫ですかw
「シェルを書く」は間違い。
「シェルで書く」は桶。

「シェルで書く」→「シェルで記述する」
→「シェルをインタプリタとして(コマンドを)記述する」


逆に、
「シェルスクリプトで書く」は間違い。
書かれたもののことを「シェルスクリプト」と言うのだから、
「シェルスクリプトで書く」だと、
「(別の)シェルスクリプトを自動的に書いてくれるようなシェルスクリプトを使う」
みたいな意味になってしまう。

304 :名無しさん@お腹いっぱい。:2007/10/13(土) 21:20:49
>>303
もしかすると世の中にはシェルスクリプトで書かれたエディタがあったりして

……と書いてこの「シェルスクリプトで」はあってるのか間違ってるのか
わからなくなってきた

305 :名無しさん@お腹いっぱい。:2007/10/13(土) 21:25:48
口だけ番長は話題をそらすことに必死なようです。

306 :名無しさん@お腹いっぱい。:2007/10/13(土) 21:46:23
コンピュータ用語を日本語で記述する際に
「てにをは」が通用しないケースが有るだけのこと。

くだくだしく文法を語らなくてよろし。

307 :名無しさん@お腹いっぱい。:2007/10/15(月) 00:22:28
>>296
やっぱり逃げたな。口だけ番長。

308 :名無しさん@お腹いっぱい。:2007/10/15(月) 09:31:23
>>294
俺はシェルで書けば直ぐ終わるものをJavaしか
書けないから?と言う理由で全部Javaで書いて
帰って行った外注さん知ってるぞ。

309 :名無しさん@お腹いっぱい。:2007/10/15(月) 15:27:51
javaでかけないのって結構多いけどな。
chmod(相当)だって、やっと1.6で出来るようになったのに。

310 :名無しさん@お腹いっぱい。:2007/10/15(月) 20:14:03
>>308-309
権限関連の操作と、ファイルのコピー、移動は、javaから子プロセス起こしてシェルスクリプト実行してる。
1.3,1.4の環境だと実装が面倒&パフォーマンス悪すぎなので。

311 :名無しさん@お腹いっぱい。:2007/10/17(水) 01:48:54
なんかのFAQで#!ラインは最後にハイフンをつけて
#!/bin/sh -
とした方が安全、みたいなことを読んだことがあるような
気がするんですが、そういう話ってありますか?
なんかごにょごにょして予期しないオプションを渡されないように、
みたいなことだったと思うんですが。

312 :名無しさん@お腹いっぱい。:2007/10/17(水) 06:03:25
あるディレクトリ以下のファイル名とディレクトリのパスを別々に表示(間にスペースを表示)させたいです。

とりあえず、ファイルのフルパスのみ、もしくは、ファイル名のみであれば以下で表示できるのですが、
find `/bin/pwd` -type f -print -exec ls {} \;|xargs -i dirname {}
find `/bin/pwd` -type f -print -exec ls {} \;|xargs -i basename {}
これを同時に行って

/hoge/hoge bar.txt
/hoge/hoge foo.txt
/hoge/hoge/hoge foo.txt

のように表示することはできないでしょうか?
あるコマンドの処理結果の一行に対して複数コマンドを発行する、ということになると思うのですが。

一旦 set -A で配列に入れてからloopで一行づつ処理することも考えたのですが、ファイル数が多すぎる場合Errorになってしまいます。

どなたかご教示ください

313 :名無しさん@お腹いっぱい。:2007/10/17(水) 09:05:20
その -print と -exec ls を同時にするという既知概じみた発想をなんとかしろ。
話はそれからだ。

314 :名無しさん@お腹いっぱい。:2007/10/17(水) 09:12:11
find `pwd` -type f -print | sed -e 's|/\([^/]*\)$| \1|g'
でどうかな。

315 :名無しさん@お腹いっぱい。:2007/10/17(水) 09:12:53
s/.../.../g は GNU 拡張で s|...|...|g にしたから、/ にする所は
適当に直してください。

316 :名無しさん@お腹いっぱい。:2007/10/17(水) 09:14:22
>>312
できたよ。

find `/bin/pwd` -type f -exec sh -c 'echo `dirname {}; basename {}`' \;

317 :名無しさん@お腹いっぱい。:2007/10/17(水) 13:53:01
>>315
> s/.../.../g は GNU 拡張で s|...|...|g にしたから、/ にする所は

それってGNU拡張?

雉も鳴かずば撃たれまいに……w

318 :名無しさん@お腹いっぱい。:2007/10/18(木) 01:54:00
>>317
うぉ、実はedからこういう挙動なのね:

 $ echo hogehoge > a
 $ ed a
 9
 ,s,hoge,fuga,g
 w
 9
 q
 $ cat a
 fugafuga

なんとなくPerlとかそういう無節操な時代になってからの事だとばかり・・・(恥


319 :名無しさん@お腹いっぱい。:2007/10/18(木) 19:51:23
んじゃ別解でも。
find "`/bin/pwd`" -type f -exec sh -c "echo \`dirname '{}';basename '{}'\`" \;

または312のようにそれぞれ一方だけを出力する方法はわかるのなら
それぞれ出力して後からくっつけるとかでもいいし
find 〜 -exec dirname '{}' \; > /tmp/dirname.txt
find 〜 -exec basename '{}' \; > /tmp/basename.txt
paste -d ' ' /tmp/dirname.txt /tmp/basename.txt

もしくはリストを出力させてwhileループで料理してもいい
find 〜 -print | while read f; do
echo "`dirname $f` `basename $f`"
done

他にはfindに-execを複数並べて、後から2行を1行にまとめるのでも。
find 〜 -exec dirname '{}' \; -exec basename '{}' \; | while read d; do read b; echo "$d $b"; done

320 :名無しさん@お腹いっぱい。:2007/10/18(木) 19:55:24
おっと、先頭のは316が既に書いていたのを見落としてました。

321 :名無しさん@お腹いっぱい。:2007/10/20(土) 08:46:44
以下のデータ構造で、
先頭に#があり、行の終わりにキーワード(Japan_A)がある行
から次の#と行の終わりにキーワード(Japan_X)がある直前まで読み込む
方法を考えています。

readとwhile文で簡単に実現するにはどうすれば、よいでしょうか。
while の条件がよくからないです。

====データ構造
BBB nnn
AAAA
#△△ABC△△△△Japan_A ← このパターンを検出して、次の行を読み込む。

123△△456

:△789△10

#△△ABC△△△△Japan_Z ← ここのひとつ前の行まで、
:zzz△12

====

322 :名無しさん@お腹いっぱい。:2007/10/20(土) 09:58:25
>>321
whileの条件: コマンドの終了ステータスが0ならループ

その例はsedでやるのが簡単で速いけど。

323 :名無しさん@お腹いっぱい。:2007/10/20(土) 12:09:46
ファイルの内容を読み込んで、それを
変数に代入するのってどうやればいいでしょうか?


324 :名無しさん@お腹いっぱい。:2007/10/20(土) 12:30:47
a=`cat a.txt`

325 :名無しさん@お腹いっぱい。:2007/10/20(土) 13:24:38
/bin/sh
で変数numが1〜10の値の場合、
という処理をしたい場合、
下記って正式にサポートされている構文なんでしょうか。
一応動きますが。。。

if [ ${num} -ge 0 ] && [ ${num} -le 9 ]

また、${num}が1〜9の値の場合、
echo "${num} is 1-9."
というコマンドを実行したい場合、
下記のような記述の仕方も認められているんでしょうか?

if [ ${num} -ge 0 ] && [ ${num} -le 9 ] && echo "${num} is 1-9."



326 :名無しさん@お腹いっぱい。:2007/10/20(土) 14:10:17
>>325
「正式サポート」って、Bourne shell桶っていう意味かな?
であればすべて桶。無問題。

一番下の行、間違ってるよ。ifは要らん。

× if [ ${num} -ge 0 ] && [ ${num} -le 9 ] && echo "${num} is 1-9."
○ [ ${num} -ge 0 ] && [ ${num} -le 9 ] && echo "${num} is 1-9."

327 :名無しさん@お腹いっぱい。:2007/10/20(土) 14:40:32
[ ... ] が test ... というコマンドの別名だというのは知ってるよね?

if文の条件式のところに書くのは「リスト」
リストというのは、1つ以上のコマンド(のパイプ列)を&&や||でつないだもの

[ ${num} -ge 0 ] && [ ${num} -le 9 ] がリストとして正当な以上、
if文の条件としても正当。



328 :名無しさん@お腹いっぱい。:2007/10/20(土) 15:04:29
testというコマンドは使った事ありません。
if文の中の&&が正式サポートされているという事ですが、
if文がないのに、条件式だけ&&で書いても実行できてしまうのは
正式サポートなんですか?

329 :名無しさん@お腹いっぱい。:2007/10/20(土) 15:20:55
>条件式だけ&&で書いても実行できてしまう
それがリスト。

&&の機能は、左のコマンドが成功したら(0を返したら)右のコマンドを実行する。
||の機能は、左のコマンドが失敗したら(非0を返したら)右のコマンドを実行する。
他に ; てのもあって、これは左のコマンドを実行し、続いて右のコマンドを実行する。


330 :名無しさん@お腹いっぱい。:2007/10/20(土) 15:36:38
複数の [ ... ] を && でつなぐよりも、test の -a オプションで ANDしたほうがいい。

if [ ${num} -ge 0 ] && [ ${num} -le 9 ]; then

if [ ${num} -ge 0 -a ${num} -le 9 ]; then

今時はないが、[ ] が外部コマンドになってるシェルの場合、
下の方法の方がtestが1回で済むため速い。

あと、変数numが空の場合にtestが混乱するのを避けるため、
常にダブルクォートを付ける癖を付けた方がいい。
さらに、単純な変数参照では { } は不要。
以上を考慮すると、

if [ "$num" -ge 0 -a "$num" -le 9 ]; then

となる。

ところが、実はこの場合はif文じゃなくてcase文で書いた方が簡単。
すべて内部コマンドになり、少しだけ速い。

case $num in [0-9]) 実行したいコマンド;; esac

331 :名無しさん@お腹いっぱい。:2007/10/20(土) 15:36:53
&&や||といったリストは、最後に実行したコマンドのステータスを返す。
具体的には、
&&は、左のコマンドが失敗したらそのステータス値を返して終了。
成功なら、まだ終わらず、右のコマンドの結果をステータス値を返す。
||は、左のコマンドが成功したら0で終了。
失敗なら、右のコマンドのステータスを返す。
となる。これ自体はシェルの正式な動作。

で、if 条件式…だと思っているものは正しくは if リスト ... であり、
リストを実行し、成功なら(0を返したら) then以下を〜という構文。

testというのはいろんな条件を調べて、成り立つなら成功(0)で終了、
成り立たないなら0以外を返すコマンド。if文に書くときにカッコに
見えるように [ という同機能のコマンドも用意されている。([という
名前で実行する場合は、カッコのペアに見えるように最後に ] という
引数を付ける。



332 :名無しさん@お腹いっぱい。:2007/10/20(土) 22:51:51
>>322
支援ありがとうございました。
sed ですか。あまり、熟知していないなぁ。

333 :名無しさん@お腹いっぱい。:2007/10/21(日) 01:48:28
>>321
データが収められているのが file とするとこんな感じ。

flag='false'
while read line ; do
 if echo "$line" | grep -q '^#.*Japan_A' ; then
  flag='true'
 elif echo "$line" | grep -q '^#.*Japan_Z' ; then
  flag='false'
 elif $flag ; then
  echo "$line"
 fi
done < file

あまり効率の良いコードじゃないので、これは叩き台として使ってくれ。

334 :名無しさん@お腹いっぱい。:2007/10/21(日) 05:53:04
すみません。bashど素人です。
FILE[0]=a
FILE[1]=b
FILE[2]=c
この配列をforを使ってechoしたいのですがどうしたらいいでしょうか?


335 :334:2007/10/21(日) 06:04:47
ごめんなさい。解決しました。

336 :名無しさん@お腹いっぱい。:2007/10/21(日) 06:34:27
>>333
親切な、詳細コードありがとうございます。感謝いたします。
参考にさせていただきます。


337 :名無しさん@お腹いっぱい。:2007/10/22(月) 23:18:56
無知で申しわけありません。追加で教えていただきたいのですが、
grep の検索キーを変数などで、変更可能でしょうか。

例: 1022の部分を変数などで変更する方法?は

grep 'ABC_071022' $line

grep 'ABC_???' $line


338 :名無しさん@お腹いっぱい。:2007/10/22(月) 23:39:57
普通に、grep "ABC_$key" "$line"

339 :名無しさん@お腹いっぱい。:2007/10/22(月) 23:53:19
>>338
ありがとうございます。試してみます。
( ' → " になるのですね。)

340 :名無しさん@お腹いっぱい。:2007/10/23(火) 00:00:32
いや、「になる」って言うか……。
基本から勉強しなおしてみたら?

341 :名無しさん@お腹いっぱい。:2007/10/23(火) 00:05:24
>>340
ご指摘のとおりかと思います。やはり基本からですね。

342 :名無しさん@お腹いっぱい。:2007/10/23(火) 22:28:14
キーワード: クォート


343 :312:2007/10/25(木) 01:22:35
>>313-319
御礼が遅くなりました。すいません。

>>314
ある出力に対して二回処理を行うのではなくて、出力自体を加工するってことですね。
問題なく実行できました。
ありがとうございます。

>316, 319
find `/bin/pwd` -type f -exec sh -c 'echo `dirname {}; basename {}`' \;
find "`/bin/pwd`" -type f -exec sh -c "echo \`dirname '{}';basename '{}'\`" \;

これ両方うまくいかないんですよね。
どうなるかというと. {} って出力がfindの結果数分続きます。
dirname, filename の引数を{}として実行するとそれぞれ "."と"{}"になるので、
{}にfindの結果が入っていないような動きだと思うんですが原因が分かりません。

よく分からなかったので試しに実験してみたところ、
find `/bin/pwd` -type f -exec echo {} \;
の出力はファイル名が出力されるのに、
find `/bin/pwd` -type f -exec sh -c echo {} \;
だとfindの結果行数分の改行(Blank行が延々続く)になってしまいます。


{}が単独で置かれていなければならないような findもある、
というmanの記述を見つけたのですが、今回のケースがそれなんでしょうか?
http://www.linux.or.jp/JM/html/GNU_findutils/man1/find.1.html

いずれにせよ環境が問題な気もするんですが、どなたか回避策ご存じないですか?
ちなみにOSはAIXです。

344 :名無しさん@お腹いっぱい。:2007/10/25(木) 04:17:32
>>343
多分 find じゃなくて最後の sh に与える引数のクォートが
上手くいってないんじゃないかな。

これならどうよ?

find `/bin/pwd` -type f -exec sh -c "echo {}" \;
find `/bin/pwd` -type f -exec sh -c "echo \`dirname \"{}\";basename \"{}\"\`" \;


345 :名無しさん@お腹いっぱい。:2007/10/25(木) 12:12:46
> いずれにせよ環境が問題な気もするんですが

AIXスレでそういう特有の事情がないか聞いてみるとか。

346 :312:2007/10/26(金) 02:37:25
>>344
それでもやっぱりだめですね。

>>345
確かに。早速聞いてみます。

ありがdございました

347 :名無しさん@お腹いっぱい。:2007/10/26(金) 10:20:35
>>344
ここはうに板だ。
GNUでしかできないことを書き込むときはきちんと断りを入れよう。


348 :名無しさん@お腹いっぱい。:2007/10/26(金) 10:55:33
>>347
GNUじゃないよ。FreeBSDのfindでもうまくいく。多分、AIXのfindの問題。

349 :名無しさん@お腹いっぱい。:2007/10/26(金) 11:09:58
FreeBSDのツール軍もGNUを参考にしているものが多いからな。
ちなみに3大商用Unixでは、どれもできなかった。


350 :名無しさん@お腹いっぱい。:2007/10/26(金) 13:35:30
3大商用Unixのfindって、-print0も使えない仕様バグバージョンだろw

351 :名無しさん@お腹いっぱい。:2007/10/26(金) 14:10:33
BSD厨はなんでこうも我が強いんだろうね。
業務用とかでも全く相手にされないオモチャなのにw


352 :名無しさん@お腹いっぱい。:2007/10/26(金) 15:38:53
Unixはもともとオモチャ。

353 :名無しさん@お腹いっぱい。:2007/10/26(金) 16:38:04
find ... sh -c 'echo $1' 0 "{}" \;
ktkr

354 :名無しさん@お腹いっぱい。:2007/10/27(土) 00:02:49
-print0が必要になるのはcpio使うときだけ。paxは対応してるの見たこと無い。

355 :名無しさん@お腹いっぱい。:2007/10/27(土) 09:21:53
理解不足なのでおしえてください。
getopts でのオプション解析の使用方法は下記でよいでしょうか。
comand.sh - /etc/passwd このケースの場合は、固まるような。

例:
comand.sh -p /etc/passwd

-- オプション解析部
while getopts p: option
do
case $option in
p)
AA='a'
;;
?)
echo "usage: xxxxxxxxxx"
exit 1
;;
esac
done


356 :名無しさん@お腹いっぱい。:2007/10/27(土) 10:01:40
なんで一行で試せることを人に聞くのだ?
case /etc/passwd in p) echo p;; *) echo '*';;esac

357 :名無しさん@お腹いっぱい。:2007/10/27(土) 10:10:45
>>355
それで合ってるよ。comand.sh - /etc/passwd の場合でも別に固まらない。


>>356 は何をどう勘違いしたのか知らんが、全く頓珍漢。→ 無視で桶。

358 :名無しさん@お腹いっぱい。:2007/10/27(土) 10:23:06
>>357
どうもご支援ありがとうございます。安心しました。

359 :名無しさん@お腹いっぱい。:2007/10/27(土) 23:23:12
>>355
確か case の ? は任意の一文字だから
? 自体にマッチさせたいのならエスケープが要るよ。


360 :名無しさん@お腹いっぱい。:2007/10/28(日) 23:57:31
標準出力とエラー出力を同じファイルに書き出し、かつ、エラー出力のみを画面に表示する、
といったことがしたいのですが、方法はありますでしょうか。

361 :名無しさん@お腹いっぱい。:2007/10/29(月) 00:33:24
ありますです。

362 :名無しさん@お腹いっぱい。:2007/10/29(月) 02:37:16
>>360
% (cmd 2>&1 >&3 | tee /dev/tty) > /tmp/out 3>&1
または/dev/fd/*があるなら
% (cmd 2>&1 >&3 | tee /dev/fd/3) 3>/tmp/out

zshなら少し横着できて
% (cmd 2>&1 2>&3 >&3) 3>/tmp/out

ただし、ファイルへの出力で標準出力と標準エラー出力に別々に出力されたものの
順序を保存するのは無理。
理由は、標準エラー出力の分岐が必要だけど、それはteeのようなプロセスを
介さずにはできないから。
zshではさも分岐できるように書けるけど、裏でzshがteeの役をやっている。

363 :名無しさん@お腹いっぱい。:2007/10/29(月) 07:44:29
>>362
>zshなら少し横着できて
↑より上の行は zshじゃないんだよね?
だったら %のプロンプト使うなよ。csh系は 2>&1 とかの文法使えない糞シェルだから。


364 :名無しさん@お腹いっぱい。:2007/10/29(月) 14:12:27
すみません。bashど素人です。
ネットマスク255.255.255.0を
CIDR表記192.168.1.0/24のように置換したいのですがどうしたらいいでしょうか?


365 :名無しさん@お腹いっぱい。:2007/10/29(月) 14:16:39
http://pc11.2ch.net/test/read.cgi/linux/1184077033/273
http://pc11.2ch.net/test/read.cgi/linux/1193299060/152
http://pc11.2ch.net/test/read.cgi/linux/1136593433/452

366 :名無しさん@お腹いっぱい。:2007/10/29(月) 14:17:26
s/255\.255\.255\.0/192\.168\.1\.0\/24/

367 :364:2007/10/29(月) 14:24:08
>>366
言葉足らずですみません。
192.168.1.0/24の、24の部分を計算で取得したいと思ってます。


368 :名無しさん@お腹いっぱい。:2007/10/29(月) 14:37:47
せっかく公式教えてもらったんだからそれ使えばいいじゃん。

369 :364:2007/10/29(月) 14:47:41
すみません。中学生なのでちょっと難しいです。。。
シェルスクリプトはちょっとだけわかります。
シェルスクリプトで教えてください。

370 :名無しさん@お腹いっぱい。:2007/10/29(月) 14:51:41
未成年者がこんなとこに来ちゃいかんよ。

371 :364:2007/10/29(月) 15:00:21
難しいですかね・・・

372 :名無しさん@お腹いっぱい。:2007/10/29(月) 15:19:38
計算で取得できると知っているならまずその手順を日本語で書き下してみ。

373 :名無しさん@お腹いっぱい。:2007/10/29(月) 15:21:57
女子ですか?
男子ですか?
女子なら考えますよ

374 :364:2007/10/29(月) 15:25:07
じゃぁ女子でお願いします。

375 :名無しさん@お腹いっぱい。:2007/10/29(月) 16:18:15
awkで。多分誰かがもっといいのを書いてくれる。

awk -F. '
BEGIN {
    tbl[255] = 8; tbl[254] = 7; tbl[252] = 6; tbl[248] = 5;
    tbl[240] = 4; tbl[224] = 3; tbl[192] = 2; tbl[128] = 1;
    tbl[0] = 0
}
/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {
    result = 0
    for (i = 1; i <= 4; ++i) {
        if (!($i in tbl))
            next
        result += tbl[$i]
    }
    print result
}'

376 :364:2007/10/29(月) 18:33:06
#!/bin/bash

awk -F. '
BEGIN {
tbl[255] = 8; tbl[254] = 7; tbl[252] = 6; tbl[248] = 5;
tbl[240] = 4; tbl[224] = 3; tbl[192] = 2; tbl[128] = 1;
tbl[0] = 0
}
/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/ {
result = 0
for (i = 1; i <= 4; ++i) {
if (!($i in tbl))
next
result += tbl[$i]
}
print result
}'

すみません。これ実行してもできません。。。

377 :名無しさん@お腹いっぱい。:2007/10/29(月) 19:21:30
おいおいw
どっから説明したらいいんだ?
まず、シェルスクリプトの基本からやれや。


378 :名無しさん@お腹いっぱい。:2007/10/29(月) 20:20:36
このスレはそろそろbashとそれ以外に分けた方がいいのか?

379 :名無しさん@お腹いっぱい。:2007/10/29(月) 20:22:50
Linux板に誘導すればおk

380 :364:2007/10/29(月) 20:51:20
すみません。この質問が最後なので教えてください。
どうしたら・・・

381 :名無しさん@お腹いっぱい。:2007/10/29(月) 21:38:16
>>380
そりゃ、実行するだけじゃ何もしないさ。
標準入力から255.255.255.0とかいう入力を1行ずつ読み込んで、
24とか出力するプログラムになっている。とりあえず素で実行して
手で入力して動作を試してみろ。

それをどう使うかは自分で考えれ。
つか、シェルスクリプトの基礎の話になるから、どっかのサイトか本で
自分で勉強汁。そこまで一から教えるのは不可能だ。

382 :名無しさん@お腹いっぱい。:2007/10/29(月) 22:36:57
ちょっと頑張ってみた。これでどうだ?

 $ MASK=255.255.255.192
 $ echo -n "`echo obase=2.$MASK|tr . \;|bc|tr '0\012' '\0\0'`"|wc -c

ちょっと空白の削り方が美しくないが、かろうじて一行に収まった。

383 :364:2007/10/29(月) 22:54:51
>>382さま
ありがとうございます!大感謝です!
ちなみに結果を$CIDRに代入したいのですがどうしたらいいですか?
バカですみません。。。

384 :名無しさん@お腹いっぱい。:2007/10/29(月) 23:01:04
代入方法ならさすがに>>382を脳がウニになるまで読んで欲しいかと・・・
学生は答ではなく原理や方法を考える手間を惜しんじゃいけないでしょ。

ていうかシェルスクリプトを書く中学生とは一体??
(最近は高校生でカーネルメンテナとかいるから普通なのか・・・)

385 :名無しさん@お腹いっぱい。:2007/10/30(火) 00:40:34
本当に中学生だとしたら、かなりダメすぎ。
今後年食って頭悪くなる一方だから。

386 :名無しさん@お腹いっぱい。:2007/10/30(火) 01:02:00
寝る前のおまけ。22バイト縮めた:

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

さすがに限界?段々ゴルフになってきたな。

387 :名無しさん@お腹いっぱい。:2007/10/30(火) 08:51:55
夢で見たので逆バージョンもなんとなくチラ裏してみる:

#!/usr/bin/ruby
n=$*[0].to_i;puts [24,16,8,0].map{|i|~(~0<<n)<<32-n>>i&255}.join(".")


388 :名無しさん@お腹いっぱい。:2007/10/30(火) 18:12:45
改行コード無視のdiffってできますか?

389 :名無しさん@お腹いっぱい。:2007/10/30(火) 21:29:26
つ -w とか --strip-trailing-cr ? # 実装によるかも



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

例)MOJI='abc123onegaisimasu'
この場合「abc123」を取得したい

391 :名無しさん@お腹いっぱい。:2007/11/01(木) 02:18:07
ほれ。始まる、が行頭の意味なら微妙に要修正。
つ $ echo hogehogeabc123hogehoge | sed -ne 's/.*\(abc[0-9]*\).*/\1/p'


392 :初心者です:2007/11/01(木) 02:29:58
>>391
ありがとうございます!


393 :名無しさん@お腹いっぱい。:2007/11/01(木) 08:20:55
exprの方がそのものだと思うけどね

394 :名無しさん@お腹いっぱい。:2007/11/01(木) 13:18:41
検索と置換、grepとsedで、ともに正規表現の複数行(perlの「mオプション」)対応できますか?

395 :名無しさん@お腹いっぱい。:2007/11/01(木) 13:56:20
>>394

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

・・・って意味ですか?

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

ちなみに上記の意味ならば、sedである程度対応出来るのは知ってるけど、grepは知らね。
(perl知ってるなら、そっちを使えばいいと思う。awkでも条件満たせるだろうけど、わざわざ使う意味無)

396 :名無しさん@お腹いっぱい。:2007/11/01(木) 15:33:41
変数を局所化する local は sh ですか? それとも bash ですか?

397 :名無しさん@お腹いっぱい。:2007/11/01(木) 16:42:55
>>396
テンプレにあるPOSIXのリンクを参照。

398 :名無しさん@お腹いっぱい。:2007/11/01(木) 17:05:26
>>395
すみません。その通りです。
sedでどのようにしてできるのでしょうか?

399 :396:2007/11/01(木) 19:38:47
>>397
アドバイスありがとです。ざっと読みましたが言及されていないので
bash 拡張のようですね。man bash もしてみましたが・・・


400 :395:2007/11/02(金) 10:26:30
>>398

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

$ cat a.txt
aaaa
bbbb
cccc
dddd
$ sed ':loop
N;s/\(^.*\)\n\(.*$\)/\2\
\1/;$!b loop' a.txt
dddd
cccc
bbbb
aaaa

401 :名無しさん@お腹いっぱい。:2007/11/02(金) 20:37:21
質問です。
resultやrvalをみなさんはなんと読んでいますか?

402 :名無しさん@お腹いっぱい。:2007/11/02(金) 20:38:09
>>401
UNIXに関する言葉のひらがな読みスレッド
http://pc11.2ch.net/test/read.cgi/unix/1001358861/

403 :名無しさん@お腹いっぱい。:2007/11/03(土) 16:32:39
長文質問です。スマソ

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

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

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

だだ上記のように親ディレクトリの名前が変更されているのと、違う親ディレクトリ名で同じファイル名が存在するので
単純にgrepするのではうまくいかないのでこんなかんじで作ってみました。

404 :403:2007/11/03(土) 16:33:23
続きです。
for i in `cat $KEY_LIST`
do
key=`echo "$i" | awk -F/ '{print$NF}'` #処理A
much=`grep "/$key$" $LIST | wc -l`
if [ "$much" -eq 1 ] ; then
((ok++))
else
key=`echo "$i" | awk -F/ '{b=NF-1} {print$b"/"$NF}'` #処理B
much=`grep "/$key$" $LIST | wc -l`
if [ "$much" -eq 1 ] ; then
((ok++))
else
((ng++))
fi
fi
done
echo "OK $ok"
echo "NG $ng"

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

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

さらに処理C〜処理Gを追加すればokになるのですが、実際のリストは20階層くらいあり
うまくループで作れないものかと思っています。よろしくお願いします。


405 :名無しさん@お腹いっぱい。:2007/11/03(土) 19:29:48
>>403
こんなので使えますか?

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

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

}
ng++
}
END {
printf("%04d\n%04d\n", ok, ng)
}

406 :405:2007/11/03(土) 19:32:45
すまん、最後が切れた

' $KEY_LIST

407 :405:2007/11/03(土) 19:47:13
すいません、間違っていた。
忘れてください。

408 :名無しさん@お腹いっぱい。:2007/11/03(土) 20:19:57
>>403
どうもよくわからん。行いたい処理じゃなくて、目的から説明できる?
同一ファイルの重複検査ならmd5sumとってsort+uniqとか、不可思議な
パス名の切り貼り検索以外の解決策があるのではないかという気がする。

409 :405:2007/11/03(土) 22:10:30
>>408
私は純粋に頭の体操と思ってチャレンジさせてもらってます。

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

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

COUNT=`awk -F/ '
{
 for(i = NF; i >= 1; --i) {
  for(j = i; j <= NF; ++j) {
   if(j == 1) {
    sizeOfArray = split($j,array," ")
    result = array[sizeOfArray]
   }
   else if(j == i) result = $j
   else result = result"/"$j
  }
   system("grep -c " result" ""'$LIST'")
   result = ""
 }
  system("grep -c ""'$A'"" ""'$LIST'") # 全部が一致する可能性も有るので無理やりゼロになるぐれっぷを実行
} ' $KEY_LIST`
続く。

410 :405:2007/11/03(土) 22:14:14
続き
echo $COUNT | awk 'BEGIN {RS = " "}
{
 if($0 == 0) {
  if(tmp == 1) ok++ # ゼロになる直前の検索ヒットが一つだけならok
   else if(tmp > 1) ng++
}
 tmp = $0
}
END {
 printf("%04d\n%04d\n", ok, ng)
}'

411 :403:2007/11/03(土) 22:52:55
>>405
おお!ありがとうございます。

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

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

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

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

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

412 :405:2007/11/03(土) 23:24:34
>>411

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

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

>>409 の解釈が妥当かどうかはともかく、
考え方として、はこっちの方がマシでしょう。

413 :名無しさん@お腹いっぱい。:2007/11/04(日) 18:24:36
>>403 なんか良く分からんが、おもしろそうなので作った。
#!/bin/sh
for i in `cat $KEY_LIST`
do
key=`basename $i`
while echo ${i} | grep "/" > /dev/nill
do
much=`grep "/$key$" $LIST | wc -l`
if [ "$much" -eq 1 ] ; then
((ok++)); break
else
i=`dirname $i`; x=`basename $i` key=`echo $x"/"$key`
fi
done
if [ "$much" -ne 0 ] ; then
((ng++))
fi
done
echo "OK $ok"
echo "NG $ng"

414 :名無しさん@お腹いっぱい。:2007/11/04(日) 18:28:39
くわ途中で送信しちまった、whileの条件を"/"にしてるけどいまいちだと思うので、適当に変えてくれ。

415 :名無しさん@お腹いっぱい。:2007/11/04(日) 19:00:34
>>403
あっ、あとファイル名とかにスペース入ってるとまずいから
IFS="
"
とかした方がいいよ。

416 :名無しさん@お腹いっぱい。:2007/11/04(日) 23:03:51
>>411
1. ローカルのファイル構成をリモートのファイル構成と同じにしたい
2. できる限りローカルのファイルの再配置で転送量を削減したい
ってことだよね。別解でこんなのどう?
#!/usr/bin/ruby
# Usage: treesync this.lst that.list
# - this.lst のファイル構成を that.lst の構成に work/ 以下で再構成するシーケンスを出力する
# - this.lst/that.lst は共に find ... -type f -print | xargs md5sum > this.lst などと生成
src_p2h = Hash[*open(ARGV.shift).read.split.reverse]
dst_p2h = Hash[*open(ARGV.shift).read.split.reverse]
src_h2p = Hash[*src_p2h.to_a.flatten.reverse]
dst_p2h.each do |path, hash|
 puts "mkdir -p `dirname work/#{path}`"
 if src_h2p[hash]
   puts "ln #{src_h2p[hash]} work/#{path}"
 else
   puts "remote-get #{path} work/#{path}"
 end
end
これでローカルのa/ツリーを元に、work/フォルダ以下に最小転送量で
リモートのb/ツリーに同期したフォルダを再構成する。remote-getコマンドは自分で用意。

417 :名無しさん@お腹いっぱい。:2007/11/05(月) 05:07:01
md5かよ……。ちと牛刀すぎないか。
しかも内容同じだとみなlnだから、同期と言い難い。

同期ごとにls -iR吐いておいて、rsyncの前段として前回と比較して
lnかmvするとしておけばいいのでは。

418 :405:2007/11/05(月) 13:01:19
>>411
後から読んだら、その>>405ってのは私を指していて、
特に405のレスの事ではないみたいですね。スマソ

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

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

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

つまりwhileループを抜けた時点で無条件に((ng++))で良い様な気がします。

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

420 :名無しさん@お腹いっぱい。:2007/11/05(月) 15:40:35
>>413
>#!/bin/sh

>#!/bin/ksh
にする。


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

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



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

echo .*

だと今いるディレクトリと親ディレクトリにもマッチしてしまう。
zshだとドットファイルのみ展開してくれるけど、shだとどうなの

423 :名無しさん@お腹いっぱい。:2007/11/06(火) 16:00:47
>>422
http://www.nurs.or.jp/~asada/FAQ/UNIX/section2.11.html

環境によっては、ls -A とか。

424 :名無しさん@お腹いっぱい。:2007/11/06(火) 16:02:58
あるファイル(例えばa.txt)の特定の行(例えばN行目)に
文字列を書き込むにはどのようにすればよいのでしょうか?

425 :名無しさん@お腹いっぱい。:2007/11/06(火) 16:09:11
>>424
環境によっては
sed -i 'Nihoge' a.txt

426 :名無しさん@お腹いっぱい。:2007/11/06(火) 16:21:52
>>423
ありがとう。FAQでしたか

427 :名無しさん@お腹いっぱい。:2007/11/07(水) 18:02:48
ディレクトリにファイルがあるかどうかの分岐ってどうしてます?
いろいろやり方はあると思いますが、何か定番ってあるのでしょうか?


428 :名無しさん@お腹いっぱい。:2007/11/07(水) 18:32:09
if [ -f "$dir/$file" ] とかじゃなくってですか?

429 :名無しさん@お腹いっぱい。:2007/11/07(水) 19:49:25
>>428

それだと、特定ディレクトリの特定ファイルの有無。
>>427は、多分任意のディレクトリに何らかのファイルが有るかどうかと言うこと。

430 :名無しさん@お腹いっぱい。:2007/11/07(水) 19:56:42
エスパーさんあらわる

431 :名無しさん@お腹いっぱい。:2007/11/07(水) 20:11:38
>>430

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

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

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

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

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

これくらいの違いを何故理解できない?

432 :名無しさん@お腹いっぱい。:2007/11/07(水) 20:15:24
つーかエスパーに任せないで質問者本人が説明しろよ。

433 :名無しさん@お腹いっぱい。:2007/11/07(水) 20:17:37
if [ `ls -A "$dir" | wc -c` -ne 0 ]; then

ってことじゃないのか?

434 :名無しさん@お腹いっぱい。:2007/11/07(水) 22:38:56
>>431はあたま大丈夫なのだろうか……

435 :428:2007/11/08(木) 00:18:45
じゃあこうしよう。
if [ `find "$dir" -maxdepth 1 -type f | wc -l` ]; then

436 :428:2007/11/08(木) 00:22:04
あ、右辺を入れ忘れました。適当に補完お願いします。

437 :名無しさん@お腹いっぱい。:2007/11/08(木) 00:24:04
サブディレクトリの有無は定番あるけど、ファイルの有無は
結局readdirして見るしかないだろうなぁ。

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

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

何かあれば展開元パターンと違う文字列になるから条件成立しない。


438 :名無しさん@お腹いっぱい。:2007/11/08(木) 00:33:23
rmdirして成功すれば空

439 :名無しさん@お腹いっぱい。:2007/11/08(木) 00:52:33
>438
お前頭いいな

440 :名無しさん@お腹いっぱい。:2007/11/08(木) 06:29:55
>>438

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

何でだろう?

441 :名無しさん@お腹いっぱい。:2007/11/08(木) 07:43:15
>>437
それ間違い。空のディレクトリでも . と .. は必ず存在するので、
echo .* * の結果は .. . になる。


442 :名無しさん@お腹いっぱい。:2007/11/08(木) 10:53:24
>>441
しまった、bashismに染まってしまった。今は反省している。
rmdirがいちばんエレガントだね。そのフォルダにプロセスがいたら
根無し草になるというのが躊躇の原因だろうけど。

443 :名無しさん@お腹いっぱい。:2007/11/08(木) 12:28:01
rmdir() 側ではどうやって判断してるんだろ

444 :名無しさん@お腹いっぱい。:2007/11/08(木) 13:09:57
if rmdir --dry-run "$dir" 2> /dev/null; then

445 :名無しさん@お腹いっぱい。:2007/11/08(木) 13:15:38
おバカな質問ですみません。

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

として、100が表示されることを期待してるんですが、何も表示されません。。
根本がわかってないと思うのですが、このあたり、ご教示頂ければ幸いに思います。
あるいは、こういった部分に触れているサイトがありましたら、リンクを頂く形でも
幸いです。。よろしくお願い致します。

446 :445:2007/11/08(木) 13:31:06
すみません、引数とか標準入力とかが把握できてませんでした。。
ttp://oshiete1.goo.ne.jp/kotaeru.php3?q=1508581
を見てわかりました。先のtest2.shは
read line
echo $line
などとすればいいんですね。お騒がせしました。

447 :名無しさん@お腹いっぱい。:2007/11/08(木) 15:56:50
rmdirないしrmではディレクトリを空の場合に削除してしまうだろ。

448 :名無しさん@お腹いっぱい。:2007/11/08(木) 16:04:47
そんなことは当然わかってて、
消えたら作ればいいと思いつつも>>440が出てきている。

あと、>>444で。

449 :名無しさん@お腹いっぱい。:2007/11/08(木) 19:13:21
>>448
権限なかったら、ダメじゃないの?


450 :名無しさん@お腹いっぱい。:2007/11/08(木) 19:33:32
権限なかったら、そもそも消せん
ということは、判定ができんということになるな

451 :名無しさん@お腹いっぱい。:2007/11/08(木) 22:49:43
権限については、読み出し権限なければreaddirな判定だってできないから
rmdirの減点にはならないかと。

452 :名無しさん@お腹いっぱい。:2007/11/08(木) 23:02:28
ファイル有無の判定にはrがありさえすればいいのに、
親のwがないといかんというのは厳しいだろ

453 :427:2007/11/10(土) 04:04:04
みなさんありがとうです。
私は [ -z "$(ls dir/)" ] としてましたが、これだと何か問題はあるでしょうか?
しかし、定番って無いのですね。

454 :名無しさん@お腹いっぱい。:2007/11/10(土) 04:25:29
ドットで始まるものが出てこない。
if ! /bin/ls -a "$dir" | egrep -qv '^\.\.?$'; then
  echo 空っぽ
end

455 :名無しさん@お腹いっぱい。:2007/11/10(土) 10:20:35
>>453
ドットファイルがあると判定を誤る。

[ $(ls -a) != 2 ]

456 :名無しさん@お腹いっぱい。:2007/11/10(土) 10:50:15
find dir -maxdepth 0 -empty
ってだめなんだっけ

457 :名無しさん@お腹いっぱい。:2007/11/10(土) 12:53:48
環境依存

458 :名無しさん@お腹いっぱい。:2007/11/10(土) 20:14:03
ドットの問題は ls -A でいいじゃん。
ls -a なんてするから . と .. を除外する余分な処理が増える。

459 :名無しさん@お腹いっぱい。:2007/11/10(土) 21:23:19
case `ls -A "$dir"` in '') echo 空ディレクトリ;; esac

↑が、モストエレガント

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

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

ヒントだけでも良いのでアドバイスお願いします。

461 :名無しさん@お腹いっぱい。:2007/11/11(日) 01:35:13
ヒント: >>1 ・csh/tcshのシェルスクリプトは推奨されません。

462 :名無しさん@お腹いっぱい。:2007/11/11(日) 01:49:37
>>460
確か一行じゃできんかったような.
sh -c "while true; do ; ps -ef ; sleep 60 ; done"
じゃ駄目かw

463 :名無しさん@お腹いっぱい。:2007/11/11(日) 04:00:30
>>460
 シェルはBournシェル(sh)で書け。(昔、cshで書いて苦労した)
 クォートできないケースが多々存在するわ、
 標準エラーはパイプに流し込めないわ、
 最悪なのが、ファイルを閉じることができないこと。

あと、コンソール入力が一行入力 $< 以外、つかいものにならんから、ユーザ入力が必要なときに苦労するぞ

464 :名無しさん@お腹いっぱい。:2007/11/11(日) 08:06:24
Csh Programming Considered Harmful でぐぐれ。

465 :名無しさん@お腹いっぱい。:2007/11/11(日) 09:24:02
>>462
do のあとに ; いらんけどな。

466 :名無しさん@お腹いっぱい。:2007/11/14(水) 10:50:21
質問させて下さい

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

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

このスクリプトがbreakできないのですが、どこに間違いがあるのでしょうか?
/bin/bash を zsh に変えれれば動きます。

467 :名無しさん@お腹いっぱい。:2007/11/14(水) 11:23:34
内側の while がサブシェルで実行されてるから。親シェルから見たら、
break 2 ではなくふつーにサブシェルが終了したようにしか見えない。

468 :名無しさん@お腹いっぱい。:2007/11/14(水) 11:48:18
>>467
シェルの実装違い。

似たものに
while read〜do〜done < FILE
これについても各種シェルで動きが違う。


469 :名無しさん@お腹いっぱい。:2007/11/14(水) 22:54:11
>>466
↓ここも参照しる。
http://blog.goo.ne.jp/cars-kitahefu/e/4190a337427d7a8cfcb5a62f515c6936


470 :466:2007/11/15(木) 02:30:33
ありがとうーーーーー
なんじゃそりゃという話でした…

471 :名無しさん@お腹いっぱい。:2007/11/15(木) 18:33:38
とあるファイル(XXX.txt)を元に、AAAからZZZまでの
連番のファイルを作りたいんだけど、
なんかいい手ある?

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

個人的には、↑みたいなので簡単に出来るかと思ったけど
${ABC}にハメるAAA,AAB,AAC〜ZZZのリストが
作れなくて。
助けてエロい人。

472 :名無しさん@お腹いっぱい。:2007/11/15(木) 18:49:30
>>471
for in in {A..Z}{A..Z}{A..Z}
do
:


473 :471:2007/11/15(木) 18:55:57
>>472
スマソ、言葉足らずだった。
ウチのシステムsolaris8でbash-2.03なんだ。うん。
{A..Z}って、bash-3.0からの拡張機能だったような。

474 :名無しさん@お腹いっぱい。:2007/11/15(木) 18:57:49
for i in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
を3回まわせばいいじゃん。

475 :471:2007/11/15(木) 19:54:07
>>474
言わんとしてることがイマイチ汲み取れなんだ。ごめん。
アホな俺にも分かるようにもうちょいとkwsk説明してくれん?

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

こう、ネストしろとか…じゃないんだよな。

476 :名無しさん@お腹いっぱい。:2007/11/15(木) 20:32:50
for i in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
do
for j in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
do
for k in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
do
cp XXX.txt $i$j$k.txt
done
done
done

477 :471:2007/11/15(木) 20:39:19
>>476
本気でありがとう神様

478 :名無しさん@お腹いっぱい。:2007/11/18(日) 03:10:54
<a href="http://xxx">
http://xxx だけ抜き出したいのですが、ズバッと一つのコマンドで
できないでしょうか?

479 :名無しさん@お腹いっぱい。:2007/11/18(日) 07:07:46
echo '<a href="http://xxx">' | gawk '{gsub("^.*< *a +href *= *\"", "");gsub("\" *>.*$",""); print}'

480 :名無しさん@お腹いっぱい。:2007/11/18(日) 08:09:36
echo '<a href="http://xxx">' | cut '-d"' -f 2

481 :名無しさん@お腹いっぱい。:2007/11/18(日) 11:18:48
expr '<a href="http://xxx">' : '.*"\(.*\)".*'


482 :名無しさん@お腹いっぱい。:2007/11/18(日) 17:37:56
>>479-481
478がどういうのを求めているか知らんが、それだと汎用性がなくて使えないのでは?
というかexprって計算以外にも使えるんだ

483 :無名:2007/11/18(日) 20:05:48
汎用性?

echo '<a href="http://xxx">' | sed 's/[^"]*"\(.*\)".*/\1/'

484 :名無しさん@お腹いっぱい。:2007/11/18(日) 20:17:38
>>482
汎用的にアンカー抜き出したいんなら、素直にHTMLパーサが利用できる
言語使えや

485 :名無しさん@お腹いっぱい。:2007/11/19(月) 02:13:59
perlを使うのは反則なんだろうな。

perl -e 'for ($val = "AAA"; $val ne "AAAA"; $val++) { print $val, "¥n";}'


486 :名無しさん@お腹いっぱい。:2007/11/19(月) 08:23:44
道具は便利に使うべきだな

487 :名無しさん@お腹いっぱい。:2007/11/19(月) 08:52:11
これで十分
perl -e 'print "$_\n" for "AAA".."ZZZ"'

488 :名無しさん@お腹いっぱい。:2007/11/19(月) 09:56:22
>>482
汎用性求めてるならそう書いてくれないと。

489 :名無しさん@お腹いっぱい。:2007/11/20(火) 23:47:47
Bournシェルで月日を引数にして対応した12星座を表示する
シェルを作成したいのですがどのような構文を使用すれば
良いか教えて頂けないでしょうか。よろしくお願いします。

490 :名無しさん@お腹いっぱい。:2007/11/20(火) 23:49:42
宿題は自分でやれよ

491 :名無しさん@お腹いっぱい。:2007/11/20(火) 23:58:04
>>489

if fi else test echo -eq -ge -le -a $1 $2


492 :名無しさん@お腹いっぱい。:2007/11/21(水) 00:05:40
・シェルスクリプトのことをシェルってゆーな


493 :名無しさん@お腹いっぱい。:2007/11/21(水) 01:06:18
Bournシェルで月日を引数にして対応した12星座を表示する
シェルを作成したいのですがどのような構文を使用すれば
良いか教えて頂けないでしょうか。よろしくお願いします。

494 :名無しさん@お腹いっぱい。:2007/11/21(水) 01:07:48
宿題は自分でやれよ

495 :名無しさん@お腹いっぱい。:2007/11/21(水) 01:30:51
まあまあ、そんな不親切にせんでも。

>>493
構文としては順序構文と条件文でできるんじゃない?

496 :名無しさん@お腹いっぱい。:2007/11/21(水) 01:54:44
`date +%j` とか使うとif文が書きやすいかもしれない。


497 :名無しさん@お腹いっぱい。:2007/11/21(水) 06:52:41
シェルってゆうな。クズ。

498 :名無しさん@お腹いっぱい。:2007/11/21(水) 07:13:30
Bournシェルってなんですか?

499 :名無しさん@お腹いっぱい。:2007/11/21(水) 21:36:16
>498
>>1 参照


500 :名無しさん@お腹いっぱい。:2007/11/21(水) 21:43:34
>>499
アフォか? >>1 のどこに書いてあるのかと。

501 :名無しさん@お腹いっぱい。:2007/11/21(水) 22:00:33
>>498はどうみても>>493への突っ込みだが
>>499はtypoにも気づかず流れも読めなかったのだろうね

502 :名無しさん@お腹いっぱい。:2007/11/23(金) 15:22:11
呼んだ?
⊂二二二( ^ω^)二⊃ ブーン

503 :名無しさん@お腹いっぱい。:2007/11/24(土) 07:02:18
BournシェルってBシェル?
マジレス頼む。

504 :名無しさん@お腹いっぱい。:2007/11/24(土) 09:23:11
マジレス: そのようなシェルは存在しません。

505 :名無しさん@お腹いっぱい。:2007/11/24(土) 11:05:49
「Bourne」な。

506 :名無しさん@お腹いっぱい。:2007/11/24(土) 19:48:21
pdkshのviモードで、カーソルキー使えないですよね。

カーソル移動にはhjklを使えってことなんでしょうけど、でもviクローンなんかはカーソル有効になってるのも多いですよね。いい方法ないかなぁ。




507 :名無しさん@お腹いっぱい。:2007/11/26(月) 13:01:12
鯖管理者にスクリプト渡すときは、shスクリプトだとOKで
perlだとNGってことありますね。perl読み書きできない管理者多いし。
shスクリプトの場合は「読めない香具師が悪い」が正論として通る。

# ある程度の規模のものは perl, python, ruby で何とかしたい…
# ただの愚痴でした。

508 :名無しさん@お腹いっぱい。:2007/11/26(月) 16:54:12
>>487
かめれすだが、
perl -le 'print for "AAA".."ZZZ"'
で十分

509 :名無しさん@お腹いっぱい。:2007/11/26(月) 23:16:16
>>507
そうかなあ、用途によっちゃperlで作るけどね。
ただ鯖管理用途?だとシェルスクリプトのほうがシンプルにできると思うけど

510 :名無しさん@お腹いっぱい。:2007/11/27(火) 15:00:07
二つの時刻の間の秒数を取りたいのだが、なんかいい手ある?

今の時間から明日の15時までの秒数、とかが知りたいのだが。

時刻はどちらも date コマンドの出力を前提に考えているけど、
少々なら事前にフォーマットをいじれる。でも UNIX TIME で
記録するのは勘弁な。


511 :名無しさん@お腹いっぱい。:2007/11/27(火) 15:12:44
>>510
普通に、

expr `date +%s -d 'tomorrow 15:00'` - `date +%s`

512 :名無しさん@お腹いっぱい。:2007/11/27(火) 23:19:54
>>507
511じゃないけど、これをperlでやるとなるとかなり面倒くさい。
だから鯖管理者にいやがられるんじゃないかな。

513 :名無しさん@お腹いっぱい。:2007/11/28(水) 12:29:41
>>512
そらぁシェルでかけるのをわざわざperlで書いたら怒られるだろ。

もっとこう、複雑なフィルタとか、DB使うとか、簡単でいいからメニューが欲しいとかいう
要求があるときにperlとかすんなり使わせてくれよということじゃないの?


514 :名無しさん@お腹いっぱい。:2007/11/29(木) 02:15:11
99.9%は/bin/shで書けるのに、残り一箇所だけちょいと面倒なテキストとか
システム処理があって、

 hogehoge | perl -e '
 ...
 ' | fugafuga

みないなことをする必要が出たりすると、#!/usr/bin/perl で書いた方が
きれいかも・・・と悩むことが極稀にあるな。もっともそうすると

 $foo = `hogehoge`
 system("fugafuga")
 open("| herohero")

とかなって、今度は #!/bin/sh で書いた方がきれいかも・・・と悩むのだけど

515 :名無しさん@お腹いっぱい。:2007/11/29(木) 06:18:04
どっちにしようか悩むときはあるね

516 :510:2007/11/29(木) 15:09:20
>>511 サンクス。

動かないなぁと悩んでたら、GNU の date じゃないと -d がないのね。
Mac で試してたんできがつかなかった..orz。

ターゲットマシンは Linux で問題なく動作しますたので、この方法で
いきます。


517 :名無しさん@お腹いっぱい。:2007/11/29(木) 22:43:51
0が真なのはどーして?
非常に気持ち悪いんですけれど。
何か理由があるんでしょうか?

518 :名無しさん@お腹いっぱい。:2007/11/29(木) 22:59:28
???

519 :名無しさん@お腹いっぱい。:2007/11/29(木) 23:10:57
>>517
もともとエラーコードだから。
エラーなしが 0 。だから 0 が真。

520 :名無しさん@お腹いっぱい。:2007/11/29(木) 23:24:55
エラーが起きたら
どんな原因でエラーになったのか調べなきゃいかんからな。

521 :名無しさん@お腹いっぱい。:2007/11/30(金) 00:59:52
昔のcshはCと同じ方法で0と非0を解釈したから
&&や||が逆転してやりづらかったとかとか。


522 :名無しさん@お腹いっぱい。:2007/12/04(火) 16:36:46
シェルを始めようとしてる者です。
テキストエディタで、
#!/bin/sh
echo Hello World
って書いて、名前を付けて保存をして、
プロパティで実行属性にチェックを入れて、
ファイルのアイコンをクリックしたんですけど、
何も出てきません。何か設定が要るのでしょうか?

523 :名無しさん@お腹いっぱい。:2007/12/04(火) 17:37:52
アホな方ですか

524 :名無しさん@お腹いっぱい。:2007/12/04(火) 18:40:58
ここは酷いインターネットですね

525 :名無しさん@お腹いっぱい。:2007/12/04(火) 22:51:08
>>522
「OSは何ですか」という質問を期待しているのだろうか?

526 :名無しさん@お腹いっぱい。:2007/12/04(火) 23:18:49
>>522
拡張子を .command にする。

どうだ?

527 :名無しさん@お腹いっぱい。:2007/12/05(水) 20:18:44
>>522
echo Hello World じゃなくて、
xmessage Hello World にしてみろ

528 :名無しさん@お腹いっぱい。:2007/12/05(水) 22:59:26
つか

echo "Hello World"

って、誰も指摘せんの?
俺、空気読めてない?

529 :名無しさん@お腹いっぱい。:2007/12/05(水) 23:02:42
おしい。
echo Hello World を、
echo Hello World にしても、間隔が広くなりません、という質問だったらよかった。

530 :名無しさん@お腹いっぱい。:2007/12/05(水) 23:03:19
あれ?
Hello World

531 :名無しさん@お腹いっぱい。:2007/12/05(水) 23:04:58
半角空白の連続って縮められちゃうのか

532 :名無しさん@お腹いっぱい。:2007/12/06(木) 00:23:08
つっこんだら負けかなと思っている

533 :名無しさん@お腹いっぱい。:2007/12/06(木) 00:45:46
>>531
オマイそんなこと知らないで
よく今までスクリプト組めたな

罰として、まずモナスクリプト書け
等幅フォント用とモナフォント用だ

534 :531:2007/12/06(木) 00:50:49
いや、半角空白の連続が消える、ってここ(2ch)の話。

535 :名無しさん@お腹いっぱい。:2007/12/06(木) 01:16:01
そういう時はこう書く
Hello World
Hello  World
Hello   World

536 :名無しさん@お腹いっぱい。:2007/12/06(木) 07:50:42
>>527
できました!! xmessageにしたらシェルが出ました
でも本には echoって書いてあったんですよ。ミスプリでしょうか?

537 :名無しさん@お腹いっぱい。:2007/12/06(木) 08:52:37
そういうネタはいいから。

538 :名無しさん@お腹いっぱい。:2007/12/09(日) 21:07:10
シェルスクリプトでキー入力なんかを実行できますか?(bash)
例えば、moreコマンドなんかの後のスペースキーだとかを

more /hoge/a.txt <<EOF
???
???
???
EOF

なんかで出来ないものでしょうか?
よろしくお願いします。


539 :名無しさん@お腹いっぱい。:2007/12/09(日) 21:17:20
expect使え。

540 :名無しさん@お腹いっぱい。:2007/12/10(月) 13:18:59
シェルは日常使い、fortranは全くの初心者の質問です。
1000回程度のループ計算なんですが、計算式部分はfortranでサンプル拝借、代入&出力処理をシェルで書いてみました。
なんとなく出来上がったんですが、ひとつ疑問が浮上し、すぐに解決出来ないのでアドバイス下さい。

fortran90で全て書いた場合と、どの程度速度は劣るのでしょうか?

541 :名無しさん@お腹いっぱい。:2007/12/10(月) 13:43:38
このスレで聞くのが適切だと考えた理由は何ですか?

542 :540:2007/12/10(月) 14:34:13
シェルスクリプトに精通しているのはこのスレの住人だからです。
他のスレではシェルを使っている人がいるか居るのか定かではありません。
僕のような2通りの方法で書いて比較した経験のある方がいらっしゃるのでは?
という淡い期待を持って質問した次第です。
すみません。スレ違いならこの質問は脚下でいいです。

543 :名無しさん@お腹いっぱい。:2007/12/10(月) 20:39:20
シェルってゆうな。クズ。

544 :名無しさん@お腹いっぱい。:2007/12/10(月) 21:16:20
>>542
 気になるなら自分で実測するのが確実。
(shの走る環境の、CPU性能メモリ量の差は非常に幅広いため、答えがない)

545 :名無しさん@お腹いっぱい。:2007/12/10(月) 21:22:53
同じ環境でのshとfortranとの比較だから、
CPU、メモリの差による違いは直接関係ないと思うが。

546 :名無しさん@お腹いっぱい。:2007/12/10(月) 21:32:37
>>545

>>542で「僕のような2通りの方法で書いて比較した経験のある方が」と言っている。

CPUやメモリ量が異なる環境での結果と、質問者の環境での結果を、比較しても無意味だ。
(ARM上の結果とCell上の結果を比較しても意味なかろ)


547 :名無しさん@お腹いっぱい。:2007/12/10(月) 21:43:10
>>546
どんなCPU/メモリ環境であろうが、
shとFortranとの速度差は同じような傾向になる。

よって、「CPU性能メモリ量の差は非常に幅広い」としても、
それは質問の本質には関係ない。答えはある。

548 :名無しさん@お腹いっぱい。:2007/12/10(月) 21:47:29
>>546
ARM上のshとFortranとの比較データがあれば、
それはCell上のshとFortranとの速度差(比)を推定する手がかりになる。
よって、大いに意味ある。

549 :名無しさん@お腹いっぱい。:2007/12/10(月) 21:52:02
fortranで書いた計算部分とループの部分の時間比を考えないのは
ゆとり教育の成果か?

550 :名無しさん@お腹いっぱい。:2007/12/11(火) 14:32:22
教えてください。
bshで、あるテキストを2行ごとに1行にまとめたいのです。
たとえば、
$ cat aaa.txt
aaa
bbb
ccc
ddd
eee
fff



$ cat bbb.txt
aaa bbb
ccc ddd
eee fff

にしたいのです。
sedで置換したり、whileで回したりとかいろいろあるでしょうけど
確かコマンド一つで出来た記憶があるのです。

$ cat aaa.txt | コマンド . . > bbb.txt

うろ覚えですが、そのコマンドにパラメータを二つ(ドットを二個)で、
2行を1行にまとめる。。。だったような気がするのですが、
知っている人いたら教えてください。

551 :名無しさん@お腹いっぱい。:2007/12/11(火) 14:40:28
>>550
paste - - か?
あと、cat | じゃなく < でおk。

552 :名無しさん@お腹いっぱい。:2007/12/11(火) 14:44:12
そうです!!
pasteです。完全に思い出しました! そうですね、ハイフンですね。
すばやいレスありがとうございました。

553 :名無しさん@お腹いっぱい。:2007/12/11(火) 18:00:20
cat /tmp/test.txt | gawk 'NR%2 {s = $0} !(NR%2) {print s" "$0}'

554 :名無しさん@お腹いっぱい。:2007/12/11(火) 18:04:40
これテンプレに入れといてくれ。
http://www.netmeister.org/misc/useless_use.pdf

555 :名無しさん@お腹いっぱい。:2007/12/12(水) 01:57:08
教えてください。
A
B
C
とあって、
2行目の下(この場合はBの下)に
BB
を入れて、
A
B
BB
C
とする
指定行数の下に文字列を挿入する
シェルスクリプトを作りたいのですが、
なにか良いアイデアはないでしょうか?


556 :名無しさん@お腹いっぱい。:2007/12/12(水) 02:22:17
指定行(2行目)の後に文字列(BB改行)を挿入するには、

sed '2a¥
BB
' < old > new

のようにすればできる。

行と挿入する文字列を変数展開するようにすればいいんじゃね?


557 :名無しさん@お腹いっぱい。:2007/12/12(水) 02:22:57
oldの前の<はいらなかった。


558 :名無しさん@お腹いっぱい。:2007/12/12(水) 22:55:42
cat /tmp/test.txt | awk -vSTR='BB' -vL=2 '{print} NR==L{print STR}'

559 :名無しさん@お腹いっぱい。:2007/12/13(木) 02:40:12
文字列処理についての質問です。

以下のHTMLタグがあるとします。
<option name=myname value="a1">b1</option>
<option name=myname value="a2">b2</option>
<option name=myname value="a3">b3</option>

上記の中から文字列処理を行い、以下の結果を導き出したいです。
a1,b1
a2,b2
a3,b3

このようにするにはどのように処理すればよろしいでしょうか?

よろしくお願いいたします。


560 :名無しさん@お腹いっぱい。:2007/12/13(木) 03:12:04
cat /tmp/test.html | perl -nle '/value="([^"]+)">([^<]+)</ && print "$1,$2"'

561 :名無しさん@お腹いっぱい。:2007/12/13(木) 08:25:29
htmlに微妙に変わっててわろたが、どっちもcatはいらん

>>559
ほんとうにこの例だけなら、
sed -e 's/.*="//' -e 's/">/,/' -e 's/<.*//'

562 :名無しさん@お腹いっぱい。:2007/12/14(金) 00:10:27
diffとawkを使って、10秒ごとにサーバに接続しているユーザ情報を取得し、ユーザのログインログアウトを監視するシェルスクリプトを教えてください

563 :名無しさん@お腹いっぱい。:2007/12/14(金) 00:14:43
宿題は自分でやりなさい

564 :名無しさん@お腹いっぱい。:2007/12/14(金) 01:21:16
お願いします
m(__)m
全然分からなくて…

565 :名無しさん@お腹いっぱい。:2007/12/14(金) 01:40:44
diffとawkの知識だけじゃできないなあ
wとかwhoとかlastとか調べてみるといいかもしれん

566 :名無しさん@お腹いっぱい。:2007/12/14(金) 01:48:27
>>559
そういうのは普通E4X

var x = <html>
<option name="myname" value="a1">b1</option>
<option name="myname" value="a2">b2</option>
<option name="myname" value="a3">b3</option>
</html>;
for each (var opt in x.option) {
print("" + opt.@value + "," + opt);
}

じゃなかったらXSLT
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/">
<xsl:apply-templates select="*"/>
</xsl:template>

<xsl:template match="option">
<xsl:value-of select="@value"/>,<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>

567 :名無しさん@お腹いっぱい。:2007/12/14(金) 01:50:22
#!/bin/sh

while true; do
  if [ ! -f /tmp/last.txt ] ; then
    touch /tmp/last.txt
  fi
  mv /tmp/last.txt /tmp/last.txt.old

  last > /tmp/last.txt

  diff /tmp/last.txt.old /tmp/last.txt
  sleep 5
done

基本はこんな感じか。これでもログイン/ログアウトの度に反応がでる。
あとは画面を生diffの結果から、も少し整形する必要があるわな。

< user pts/3 192.168.0.1 Fri Dec 14 01:43 still logged in
---
> user pts/3 192.168.0.1 Fri Dec 14 01:43 - 01:43 (00:00)

行の頭からログイン時刻までを一本の文字列にしてawkとかの連想配列のキーにして、
ログアウト時刻(またはstill logged inn)を保持しておくか...
あとlastのお尻の方はだんだん削られていくから、これも何とかする必要があるな。

568 :名無しさん@お腹いっぱい。:2007/12/14(金) 02:00:24
あるいはもう面倒くさいから

  diff /tmp/last.txt.old /tmp/last.txt > /dev/null 2>&1

  if [ $? -ne 0 ] ; then
    clear
   cat /tmp/last.txt
  fi

こうやっちゃうとかな。監視コンソール風。

569 :名無しさん@お腹いっぱい。:2007/12/14(金) 03:19:03
>>567
また俺のIPがサンプルに使われてる(´・ω・`)
攻撃の的になるからやめてよ


570 :名無しさん@お腹いっぱい。:2007/12/14(金) 03:38:51
つまらんボケにはつっこむ気も起きん

571 :名無しさん@お腹いっぱい。:2007/12/14(金) 04:26:20
>>569
最近、インターネットにアクセスできないと思ったらお前のせいかー


572 :名無しさん@お腹いっぱい。:2007/12/14(金) 09:18:48
●でログインしてもここの過去スレにアクセスできないんですが、
過去スレ保存している人いませんかね?

573 :名無しさん@お腹いっぱい。:2007/12/14(金) 11:52:49
1から8までとってあるよ。

574 :名無しさん@お腹いっぱい。:2007/12/15(土) 01:59:33
適当な場所が見つからなかったので@wikiに作ってみました。
http://www32.atwiki.jp/shellscript/
よかったらここにアップしていただけないでしょうか。

575 :名無しさん@お腹いっぱい。:2007/12/16(日) 11:59:59
find / -regex "/home/[a-z0-9\-]/text/[a-z0-9.\-]\.txt" > text_list
で /home/***/text/***.txt
を探しているのですが、
どうもかなり遅めでload averageもあがりやすいようです。
ls あたりで代替策を探してるのですが、
ls /home/*/text/*.txt
あたりが良いかなと思ったのですが、*は/も含むと聞いて困ってます。
(試したところ、速度はfindと比べてかなり早かったのですが。。。)

どなたか助言お願いします。

576 :名無しさん@お腹いっぱい。:2007/12/16(日) 13:07:30
> *は/も含むと聞いて困ってます。
ヤキいれてあげるから、そういうデタラメを教えた奴を連れてきなさい。

577 :名無しさん@お腹いっぱい。:2007/12/16(日) 13:13:56
>>575
locate (+grep)とか。


578 :名無しさん@お腹いっぱい。:2007/12/16(日) 15:13:40
>>576
-regexの * は / も含むよw

ヤキいれられるのはオマエww

579 :名無しさん@お腹いっぱい。:2007/12/16(日) 15:21:47
>>578
日本語読めない低脳は引っ込んでいなさい。-regexの*の事ではない。

> ls /home/*/text/*.txt
> あたりが良いかなと思ったのですが、*は/も含むと聞いて困ってます。

580 :名無しさん@お腹いっぱい。:2007/12/16(日) 21:15:33
find -regex "...*..."
の場合、*は/を含む(ディレクトリ階層を縦断する)

ls */*
の場合、*は/を含まない(/で区切られたディレクトリ階層だけを探す)

581 :名無しさん@お腹いっぱい。:2007/12/16(日) 23:34:21
すみません。FreeBSDですが
文字列「aaa」と書いた1.txtをsedで「bbb」に変えて保存したい。
どのようにしたらいいでしょうか?


582 :名無しさん@お腹いっぱい。:2007/12/16(日) 23:38:27
sed -i -e 's/aaa/bbb/' 1.txt

583 :581:2007/12/16(日) 23:51:33
>>582
-eが必要だったのか!でも-eは複数コマンドのオプションだと思ってた。
とにかくありがとう!

584 :名無しさん@お腹いっぱい。:2007/12/17(月) 01:04:43
たびたびすみません。FreeBSDですが
文字列「aaa\taaa」←水平タブ入りが書いてある1.txtを
文字列「bbb\tbbb」に変えて保存したい。
どうしたらいいでしょうか?
エスケープシーケンス入りの文字列の扱いがわからない。。。


585 :名無しさん@お腹いっぱい。:2007/12/17(月) 03:28:20
sed -i -e 's/aaa/bbb/g' 1.txt

タブ・エスケープは関係ない。/gをつけるとマッチしたもの全てを置換する(globalのg)。
gなしだと最初の一個だけ

586 :584:2007/12/17(月) 05:11:44
>>585
じゃ、じゃあ

文字列aaaを

aaa
bbb

のように改行付きで置換したいとき

sed -i -e 's/aaa/aaa\nbbb/g' 1.txt
としても改行されません。
FreeBSDのsedはエスケープシーケンス使えない?


587 :名無しさん@お腹いっぱい。:2007/12/17(月) 06:24:56
% cat /tmp/1.txt
aaa
% sed -e 's/aaa/aaa\nbbb/g' /tmp/1.txt
aaa
bbb
% sed --version
GNU sed 4.1.1版

Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE,
to the extent permitted by law.
(後略)

588 :573:2007/12/17(月) 09:51:07
>>574
アップロードしてみました。
shellscript.tar.bz2

589 :573:2007/12/17(月) 10:00:25
8が最後まで入ってなかったのと、まちがえて現行スレまで入れてしまったので、
アップロードし直した(shellscript_.tar.bz2)

590 :名無しさん@お腹いっぱい。:2007/12/17(月) 10:30:05
>>586
\を前置して改行をそのまま書く。

% echo aaa|sed 's/aaa/aaa\
bbb/'

591 :名無しさん@お腹いっぱい。:2007/12/18(火) 03:47:42
すいません。

scriptコマンドでコマンドログをとりたくて、ログイン時に自動的に呼び出されるよう
profileに書きましたが、ターミナルを終了する時にexitを何回も打たなくてはならないのが
気持ち悪いです。

例えば、一回のexit入力で、scriptとログインシェルの2回分を実行するというのは可能ですか?


592 :名無しさん@お腹いっぱい。:2007/12/18(火) 07:11:01
>>591
exec script

593 :名無しさん@お腹いっぱい。:2007/12/18(火) 07:42:32
>>592

ありがとう

594 :名無しさん@お腹いっぱい。:2007/12/18(火) 20:27:05
ファイルを読んでそのフィールドの一部分でuniqしたいんですけど、
どうすればよいですか?

APPLE,150円
APPLE,140円
APPLE,180円

とあったら、1フィールド目のみでuniqして先頭の行を出力したいです。
もちろん値段もほしいです。
ご教示お願いします。

595 :名無しさん@お腹いっぱい。:2007/12/18(火) 20:29:22
>>594
perl かなんかで書いちゃった方が早いんじゃね。

596 :名無しさん@お腹いっぱい。:2007/12/18(火) 20:31:18
awk 'BEGIN {FS=","} {if (foo != $1) {print}; foo = $1}'

597 :名無しさん@お腹いっぱい。:2007/12/18(火) 20:34:35
>595,596
早っ! ご教示ありがとございます
awkにします

598 :名無しさん@お腹いっぱい。:2007/12/18(火) 21:00:26
知ったかの >>595 が不憫。

599 :名無しさん@お腹いっぱい。:2007/12/18(火) 21:04:49
別に awk でできないとは言ってないよ。

600 :名無しさん@お腹いっぱい。:2007/12/18(火) 22:02:22
cat /tmp/file | perl -nle '$foo ne (@foo=(split/,/))[0] && (print, $foo=$foo[0])'

601 :名無しさん@お腹いっぱい。:2007/12/18(火) 22:25:21
久々に「catが無駄です」

602 :名無しさん@お腹いっぱい。:2007/12/18(火) 22:26:41
まあいいじゃん

603 :名無しさん@お腹いっぱい。:2007/12/18(火) 23:53:32
>>595
しね

604 :名無しさん@お腹いっぱい。:2007/12/18(火) 23:57:25
>>595=>>599
しね
二度と現れるなボケ

605 :名無しさん@お腹いっぱい。:2007/12/19(水) 00:46:05
awkがスクリプト言語と知らなかった598が顔を真っ赤にして暴れるスレ

606 :595:2007/12/19(水) 00:54:10
なんかマズいこと言ったか?
よく知らないシェルスクリプトでがんばるより
便利で得意な言語で書いちゃった方が早いこともあるよ、
ってだけの話なんだけど。

607 :名無しさん@お腹いっぱい。:2007/12/19(水) 00:57:45
>>605
>>598じゃねーよw
おまえ、二度と現れるなと言っただろ?w

608 :名無しさん@お腹いっぱい。:2007/12/19(水) 01:01:44
>>595
おまえまだわかんねーのかよ?
おまえが言ってることは「ググレカス」と同レベル
どんな質問でも当てはまってしまうアホな回答。

609 :名無しさん@お腹いっぱい。:2007/12/19(水) 01:06:00
595じゃないが、>>608がなんで暴れてるのかよくわからん

610 :名無しさん@お腹いっぱい。:2007/12/19(水) 01:07:07
頭悪いからだろ。

611 :名無しさん@お腹いっぱい。:2007/12/19(水) 01:48:57
>>608じゃないが
>>595は自演が下手だな
こんな時間に過疎スレで1分後にレスって明らかに自演。

612 :595:2007/12/19(水) 02:03:18
>>611
いや、>>595>>599>>606しか書いてないけど。

613 :名無しさん@お腹いっぱい。:2007/12/19(水) 02:19:31
perlには-aというオプションもあってだな。


614 :名無しさん@お腹いっぱい。:2007/12/19(水) 02:41:34
perlにはa2pという支援ツールがあってだな。

615 :名無しさん@お腹いっぱい。:2007/12/19(水) 02:49:04
awkのカーニハン本は言語の説明は1章だけで終わりで
あとは応用例だが、
perlのラクダ本は電話帳みたいな本が上下2巻。クックブックは別にある。
よってawkの勝ち

616 :名無しさん@お腹いっぱい。:2007/12/19(水) 02:57:18
perlは大体わかるけどawkはさっぱりです。


617 :名無しさん@お腹いっぱい。:2007/12/19(水) 03:12:02
>>615
awkの原典は、初学者が手にするとちょっとな。途方にくれるというか何というか。高い本なのに。
perlのラクダ本はその点は抜かりなく、初心者もすんなりと中に入り込んでいける。
awkの入門書で良書というと、ASCIIのawk256倍本くらいしか思いつかない。俺は今でも愛用してるけど、
あんな昭和の時代の本、いまどき手に入るはずもなく

618 :名無しさん@お腹いっぱい。:2007/12/19(水) 03:17:31
SED&AWKも忘れないで by おら

619 :名無しさん@お腹いっぱい。:2007/12/19(水) 03:49:30
>>618
その本初心者でもわかりやすい?

620 :名無しさん@お腹いっぱい。:2007/12/19(水) 10:07:59
>>594
perl -aF, -nle '$X{$F[0]} or print; $X{$F[0]} = 1'

621 :名無しさん@お腹いっぱい。:2007/12/19(水) 12:19:59
perlって見ためが汚いねw

622 :名無しさん@お腹いっぱい。:2007/12/19(水) 12:39:17
sedの置換について質問
タブ(\t)は置換できるのですが改行(\n)が置換できません。
例えば # cat a.txt
aaa
bbb
aaa(タブ)bbb

3行目の(タブ)区切りは置換できるけど1行目と2行目にマッチした文字を置換できません。
sedじゃ無理?こういうのawkでできたりしますか?


623 :名無しさん@お腹いっぱい。:2007/12/19(水) 12:47:27
>>622
sedについてはこちらへ

sed
http://pc11.2ch.net/test/read.cgi/unix/1085730992/

624 :名無しさん@お腹いっぱい。:2007/12/19(水) 12:56:24
cat /tmp/a.txt | awk '{sub("$", "<CR>"); sub("\t", "<TAB>"); print}'

625 :名無しさん@お腹いっぱい。:2007/12/19(水) 13:09:34
だから、catが(ry
ファイル名を前にもってきたいなら、せめて、
< /tmp/a.txt awk ...
と書け。

626 :名無しさん@お腹いっぱい。:2007/12/19(水) 13:21:07
>>554読んどけ。

627 :名無しさん@お腹いっぱい。:2007/12/19(水) 15:50:37
>>621
そうか?

628 :名無しさん@お腹いっぱい。:2007/12/19(水) 21:32:17
質問です。

a.txtの内容
----------
aaa
bbb
ccc
bbb
----------

このa.txtを
----------
aaa
bbb
ccc
ddd
----------
↑のようにa.txtを置換して保存したい。
この文字は何行目にあるか不明だとして
一番下のbbbをdddに置換することはできますか?sedでもawkでもいいのです。
2chなのになぜかたらい回しにされてるのですがよろしくお願いします。


629 :名無しさん@お腹いっぱい。:2007/12/19(水) 22:00:52
#!/bin/sh
ed a.txt << EOS > /dev/null
\$a

.
?bbb?c
ddd
.
\$d
wq
EOS
いったん末尾に1行挿入するのがコツ

630 :628:2007/12/19(水) 22:06:31
1行のコマンドで出来ないものでしょうか?


631 :名無しさん@お腹いっぱい。:2007/12/19(水) 22:33:42
>>619

かなり、とっつきは悪い。
特にsed編は、使用目的がtroffマクロの置換とか、プリンタ整形言語の整形とか、訳分からん。
awk編はまあ、用例も身近なのが結構有るけど・・・

でも、内容は極めて濃い。
金を出して購入し、何度も読み返す価値は有ると思う。

632 :名無しさん@お腹いっぱい。:2007/12/19(水) 22:37:34
>>622

いっている意味が良く分からんが、
エスパーすると、それはawkよりsedの方が得意だと思う。

633 :名無しさん@お腹いっぱい。:2007/12/19(水) 22:44:44
awk '/bbb/{bbb=i};{l[i++]=$0};END{l[bbb]="ddd";for(j=0;j<i;j++){print l[j]}}'


634 :628:2007/12/19(水) 22:52:17
>>633
ありがとう御座います!
あなた様をずっと待ってました・・・!


635 :628:2007/12/19(水) 22:57:16
>>633
それをa.txtに保存するにはどうしたらいいでしょうか?
awkは呪文のようでまったくわかりません。。。


636 :名無しさん@お腹いっぱい。:2007/12/19(水) 22:59:58
>>634
おいおい、>>633 じゃ大間違いだと思うがww

637 :名無しさん@お腹いっぱい。:2007/12/19(水) 23:05:57
>>633 は、一番最後に現れた bbb の行を無条件に ddd に置換しているだけ。

そうじゃなくて、>>628 のやりたいのは、
「ccc<改行>bbb」を「ccc<改行>ddd」に置換したいということだろ?
複数行に渡る置換をしたいということ。

sedスレの方に、すでに解答が出てるよ。1行コマンドで行ける。

638 :名無しさん@お腹いっぱい。:2007/12/19(水) 23:09:21
% cat /tmp/a.txt
aaa
bbb
ccc
bbb

aaa
bbb
ccc
ccc
bbb

aaa
bbb
ccc
bbb
% cat /tmp/a.txt | perl -e '($_ = join("", <>)) =~ s/(aaa\nbbb\nccc\n)bbb/$1ddd/g; print '
aaa
bbb
ccc
ddd

aaa
bbb
ccc
ccc
bbb

aaa
bbb
ccc
ddd

639 :628:2007/12/19(水) 23:13:40
>>637
そうでしたか。
答えはsedスレの何番目ですか?

640 :名無しさん@お腹いっぱい。:2007/12/19(水) 23:31:14
そうでしたか。ってwww
お前さんは自分が直面している問題を自分で把握してないのか?wwww

sedではないが別解がひとつ上にある。"aaa改行bbb改行ccc改行bbb"を
全て"〜ddd"に痴漢する

641 :名無しさん@お腹いっぱい。:2007/12/21(金) 02:21:54
>>617
ふつーに見かけるぞ? >awk256倍
しかしこの本が初心者向けかどうかはちと首をひねるがな。


642 :名無しさん@お腹いっぱい。:2007/12/21(金) 14:28:09
すみません質問です。
ファイルにひとつフィールド列(固定文字)を足したいんですが、
while read do でループより簡潔に書きたいんです。
paste file1 file2 のfile1には固有文字を入れている感じです
お願いします

643 :名無しさん@お腹いっぱい。:2007/12/21(金) 14:37:23
642です。
awkっての使えばいいことに気がつきましたすみません

644 :名無しさん@お腹いっぱい。:2007/12/22(土) 00:04:45
「っての」と言う語感が無縁な事象に対してと思えるのに、
「気がつく」のだから、相当な洞察力だな。

645 :名無しさん@お腹いっぱい。:2007/12/22(土) 00:20:23
このスレ(というか板)、ひょっとして精神年齢が相当ひくい?
学校の宿題とか新人研修の課題を聞きに来る子供ばっかり?

646 :名無しさん@お腹いっぱい。:2007/12/22(土) 01:56:01
>>645
つ 鏡

647 :shell:2007/12/22(土) 12:45:37
shell初心者です。

変数 TODAY=20071212(任意指定)として1970-01-01 00:00:00基準からの
経過時刻を秒数で表示したいのですが、方法はありませんか?

648 :名無しさん@お腹いっぱい。:2007/12/22(土) 12:46:41
つ date -d ... +%s


649 :shell:2007/12/22(土) 12:48:50
質問2つ目

text.txtに
11 11 11 111 222 333 E
33 44 666 6666 E
と2行記入しているのですが、これを1行ずつ変数に代入できるスクリプトはありますか?
行の空白は半角スペースで最後にEは表示されています。行中の文字は任意の文字列です。


650 :shell:2007/12/22(土) 12:49:54
dateは本日の日付を求めるshellじゃなかったでしたっけ?
自分で指定した日付で求めたいです。

651 :名無しさん@お腹いっぱい。:2007/12/22(土) 12:59:52
つ man date -> "-d dateexpr" # MS-DOSかよ!>本日の日付

652 :名無しさん@お腹いっぱい。:2007/12/22(土) 13:08:24
>>650
「dateは本日の日付を求める…」違います。

せっかく >>648 で正解を教えてもらっているのに、礼も言わずに
そういうことを言う人には質問する権利はありません。

はい、次の方どうぞ



653 :名無しさん@お腹いっぱい。:2007/12/22(土) 13:10:36
$ cat /tmp/test.txt | while read str; do
> echo "[$str]"
> done
[11 11 11 111 222 333 E]
[33 44 666 6666 E]
$

654 :名無しさん@お腹いっぱい。:2007/12/22(土) 13:12:04
>>649
つ read hoge; read fuga

655 :shell:2007/12/22(土) 22:55:46
今スレ開きました。
試してみます。

ありがとうございます。

「dateは本日の日付を求める…」違うですか...
調べます。

656 :名無しさん@お腹いっぱい。:2007/12/22(土) 23:09:02
「開きました」キター
何でもウィンドウの隠喩w

657 :名無しさん@お腹いっぱい。:2007/12/22(土) 23:15:08
>>656
DOS時代(ニフ)の頃からある表現なので、
ファイルオープンからきた「開く」だと思ってたけど?違うの?

658 :名無しさん@お腹いっぱい。:2007/12/23(日) 02:42:27
>>657
いちいち相手しないほうがいいっすよ。
貶すことしかできないやつってどこにでもいますから。
まあこういうやつに限って現実では貶されまくってるわけですけどね。


659 :名無しさん@お腹いっぱい。:2007/12/23(日) 18:22:15
/home/hoge/fuga/
/home/hoge/fuga/.data
が本来セットであるはずなんですが、
設定ミスで、一部ユーザには
/home/hoge/fuga/
はあっても
/home/hoge/fuga/.data
がありません。

.dataが存在しないフォルダを簡単に調べる方法はないでしょうか。

660 :名無しさん@お腹いっぱい。:2007/12/23(日) 19:03:27
>>659
for dir in /home/*/fuga
do
[ -f $dir/.data ] || echo $dir
done

661 :名無しさん@お腹いっぱい。:2007/12/24(月) 08:08:48
文字列に対して、$oldから$newの置換をしたい場合、
echo $line|sed -e s/$old/$new/ だと、
$oldや$newが'/'を含んだ時にエラーになってしまうから、
bashの${line/$old/$new}を使ってしまうのだけど、
他にポータブルないい方法ないでしょうか。

662 :名無しさん@お腹いっぱい。:2007/12/24(月) 08:33:45
変数がどの文字を含むか予め予期できないとなると、
「,」に逃げるとかはできないしな

663 :名無しさん@お腹いっぱい。:2007/12/24(月) 10:22:22
コマンドインジェクション可能だから未検証の文字列をコマンドとしてsedに与えてはいけない。

664 :名無しさん@お腹いっぱい。:2007/12/24(月) 12:30:10
うーん、そうなのですか。
line, old, newがそれぞれ実在のパス(フルパス、相対パス、パスの一部のいずれか)
だと保証できる場合はどうでしょうか。
そもそもsedだと置換え前の文字を正規表現と扱ってしまうから、
期待しないマッチングが発生する可能性もあるけれども。。。
適当なスクリプトに、3つの引数を与えて
その中で処理させたほうがいいのかなぁ。

665 :名無しさん@お腹いっぱい。:2007/12/24(月) 14:16:55
実在のパスでも、Ctrl-A (0x00) 以外のすべての文字が
パスとして使用可能だからなぁ、、

666 :名無しさん@お腹いっぱい。:2007/12/24(月) 14:50:27
>665
これ本当ですか?
Ctrl-Aと/以外はファイルやディレクトリ名に使えるってこと?
横から質問で申し訳ない

667 :名無しさん@お腹いっぱい。:2007/12/24(月) 14:52:42
CTRL-Aは0x01なので嘘です。

668 :名無しさん@お腹いっぱい。:2007/12/24(月) 14:59:37
CTRL+SPC

669 :名無しさん@お腹いっぱい。:2007/12/24(月) 15:20:48
Ctrl+@だな。それ以外は本当。

670 :名無しさん@お腹いっぱい。:2007/12/25(火) 17:49:34
ファイル名にCtrl+Gを含めたら、lsの度に激しくうるさい件について

671 :名無しさん@お腹いっぱい。:2007/12/25(火) 18:00:35
?に置き換わってうるさくない件について

672 :名無しさん@お腹いっぱい。:2007/12/26(水) 00:06:34
普通--show-control-charsって常に有効にするだろ

673 :名無しさん@お腹いっぱい。:2007/12/26(水) 00:32:28
そんなls手が腐るから普通触らない。

674 :名無しさん@お腹いっぱい。:2007/12/26(水) 03:49:58
半導体業界はcshスクリプトとかtclスクリプトばっか。
ときどき転職したくなる。

675 :名無しさん@お腹いっぱい。:2007/12/26(水) 10:48:21
CADとかもtcl使っているの多いね。
プラグインとかだけでなく、サービス起動スクリプトまでtcl使っているのがあるし。


676 :名無しさん@お腹いっぱい。:2007/12/26(水) 11:38:44
TCLは、もともと集積回路設計ツール内蔵スクリプト言語の
ベースとなる拡張可能なスクリプト言語として開発されたからね。
だから半導体の世界では多い。
独自言語使わないで済むのはTCLのおかげ。

Tkとくっついてから他の世界にも普及した。


677 :名無しさん@お腹いっぱい。:2007/12/27(木) 11:54:46
すみません、
#!/usr/bin/ksh
PALALLEL(){
mp=$!; sp=$$
echo "ぱられる ${mp} ${sp}"
}

PALALLEL &
PALALLEL &

とやったとき最初のmpが取れないんですがどうするべき?

ご教示おねがいします


678 :名無しさん@お腹いっぱい。:2007/12/27(木) 11:58:48
>>677
当たり前だろ。
最初のPALALLEL()にとっては、$!は存在しないから。

679 :名無しさん@お腹いっぱい。:2007/12/27(木) 12:07:29
あ。、そうか(終了直後か
・・有難うございました(汗

680 :名無しさん@お腹いっぱい。:2007/12/29(土) 19:59:29
ある環境変数が定義されているか否かを判定したいんですがどのように判定すればいいんでしょうか?
zshだとif [[ -z $EMACS ]]のようなやりかただと警告がでて嫌なのです

681 :名無しさん@お腹いっぱい。:2007/12/29(土) 20:37:24
[ "${var+defined}" = "defined" ] && echo defined

682 :名無しさん@お腹いっぱい。:2007/12/30(日) 02:56:40
あるファイルをgrepした結果を配列としてforeachに引き渡したいのですが、うまくいきません。

grepする内容
-------------------------------
ex xxx
aaa
ex yyy
bbb
ex zzz
-------------------------------
ここからexで始まる行のみをgrepで抽出する(xxx,yyy,zzzは同じディレクトリのメンバ名)

-------------------------------
ex xxx
ex yyy
ex zzz
-------------------------------

これをawkでメンバ名だけ抽出しfileに書き込む
awk '{print $2}' >file

各メンバの行数を表示
foreach i (file)
wc -l $i
end

とやるとfileの行数(この場合3)と出てしまいます。
本当はメンバxxx,yyy,zzzの行数を表示したいのですが、どのようにすればよろしいでしょうか?
fileにはメンバ名が出力されています。よろしくご教授ください。
tcshを使用しています。


683 :名無しさん@お腹いっぱい。:2007/12/30(日) 04:59:50
`cat file`

既にcshで書かれたプログラムをメンテする必要があるとか、
cshが強制されてるでもなければ、
bshにしときなさい。

684 :名無しさん@お腹いっぱい。:2007/12/30(日) 10:27:30
>>682
>>1
> ・csh/tcshのシェルスクリプトは推奨されません。
> (理由は「csh-whynot」でググれ)

685 :名無しさん@お腹いっぱい。:2007/12/30(日) 10:37:16
682を見るにスクリプトを書くよりは対話的に使ってる上での質問じゃないかと
思うが。馬鹿の一つ憶えも程々にしてはどうか。

686 :名無しさん@お腹いっぱい。:2007/12/30(日) 10:40:38
ならスレ違いだな。消えろ。

687 :名無しさん@お腹いっぱい。:2007/12/30(日) 10:43:40
tcshで対話的といえば、foreachとかの対話的使いかたが分からん。
やむなく仕事でtcsh使ってるが、
ループ処理の時だけbash起動してる俺。

688 :名無しさん@お腹いっぱい。:2007/12/30(日) 11:21:51
>>682
$ sh -c 'for i in `cat file`; do wc -l $i; done'

689 :名無しさん@お腹いっぱい。:2007/12/30(日) 11:39:34
>>681
ありがとうございます
ぱっと見、なにが行われてるかよくわかりませんでしたが
一応bashのmanに載ってる書式なんですね


690 :名無しさん@お腹いっぱい。:2007/12/30(日) 12:12:19
>>689
[[ -z "$EMACS" ]] でよかろう。

691 :名無しさん@お腹いっぱい。:2007/12/30(日) 18:26:58
>>689
bash依存じゃない。POSIX準拠だ。

692 :682:2007/12/30(日) 22:03:40
682です。
皆様ありがとうございました。
仕事の環境がtcshを使うので>>1は読んでいましたが質問させていただきました。
また、対話形式でもなく(対話でもいいのですが)、スクリプトで実行したかったんです。
初心者の為、頂いた回答でも分らない部分がありますが、
年明け会社で試してみます。
ありがとうございました。


693 :名無しさん@お腹いっぱい。:2007/12/30(日) 23:18:24
>>687
簡単な使い方の例を挙げると、

% foreach i ( * )
と入力すると、ループ中を示すプロンプトが出てくるので、
foreach? (ここで変数$iを使った文)
foreach? :
foreach? end

みたいに実施する。

例えば拡張子が.logなファイルがある場所で、
% foreach i ( *.log )
foreach? echo "ファイル名 $i 、行数=`wc -l $i`"
foreach? echo "--- 先頭10行 ---"
foreach? head $i
foreach? echo "--- 末尾10行 ---"
foreach? tail $i
foreach? end

こんなことするときに便利なりよ。


694 :名無しさん@お腹いっぱい。:2007/12/31(月) 00:21:27
>>693
bashみたいに foreach i ( * ) ; do echo $i; end # do は要らないんだろうけど
みたいには使えないの?
強制的に対話モードになってしまうのが嫌なの。

695 :名無しさん@お腹いっぱい。:2007/12/31(月) 16:44:41
>>690
それだと、$EMACS が空文字列の場合にも
未定義と判断されてしまう。

>>681 は、空文字列の場合でも、定義済みかどうかをちゃんと判断できる。

696 :名無しさん@お腹いっぱい。:2008/01/04(金) 00:49:17
sedで "s/aaa/$bbb/" とした場合、$bbbの中に & があると
& が一致した箇所に置換されます
これを変数の中で bbb=\& とエスケープしないでそのまま置換させたいのですが
いい方法はないでしょうか?
またはsedじゃなくても正規表現を無視して置換するコマンドってあります?

697 :名無しさん@お腹いっぱい。:2008/01/04(金) 18:00:48
シェルを使ってまだ1ヶ月ですが、宜しくお願いします。

やりたいことは1.5GBもあるファイルをgzipを使って圧縮したいのですが、
レンタルサーバーのため負荷が高いせいか途中でkillされてしまい、
圧縮が最後まで出来ません。何か解決策をご教授いただけないのでしょうか?
宜しくお願いします。
gzip fileName

698 :名無しさん@お腹いっぱい。:2008/01/04(金) 18:10:12
>>697
分割して圧縮?

699 :名無しさん@お腹いっぱい。:2008/01/04(金) 18:55:23
>>697
レンタル鯖のルールがよくわからんが、ファイルの大小に関係なくファイル圧縮の
CPU使用率なんてタカが知れているから、おそらくCPU時間を測っていて、タイムアウト的に
討ち取られていると思う(CPU負荷は小さいがCPU時間は長くなる)

というわけで>>698の言う通り、splitして分割圧縮するしかないな。

700 :名無しさん@お腹いっぱい。:2008/01/04(金) 19:09:51
対話的なシェルの使い方はスレ違い。レン鯖板にでも行ってしまえ。

701 :名無しさん@お腹いっぱい。:2008/01/04(金) 19:37:54
シェルにはAシェル系、Bシェル系、Cシェル系、と種類があるようですが、
僕のPCのシェルはXtermというものみたいです。
これは、シェル系に当てはめると何シェル系なんでしょうか?

702 :名無しさん@お腹いっぱい。:2008/01/04(金) 19:39:36
釣りは他所でやれ、な?

703 :江戸っ子:2008/01/04(金) 21:34:59
んなこと知ぇるけぇー!

704 :名無しさん@お腹いっぱい。:2008/01/04(金) 23:11:46
>>701
マジレスするとxtermはshellじゃない。

705 :名無しさん@お腹いっぱい。:2008/01/05(土) 00:18:57
シェルにはAシェル系、Bシェル系、Cシェル系、と種類があるようですが、
僕のPCのシェルはTeraTermというものみたいです。
これは、シェル系に当てはめると何シェル系なんでしょうか?


706 :次の患者さんどぞー:2008/01/05(土) 00:30:07
>>701
Xシェル

>>705
Tシェル

わからない場合はグーグルで検索して調べること

707 :名無しさん@お腹いっぱい。:2008/01/05(土) 01:31:18
マジレスするとashもbsh系

708 :名無しさん@お腹いっぱい。:2008/01/05(土) 08:59:59
>>697
ddで先頭から順に適当な長さずつ切り出しながら | gzip -c >> file.gz に繋ぐ。
dd if=file bs=適当 skip=0 count=1 | gzip -c > file.gz
dd if=file bs=適当 skip=1 count=1 | gzip -c >> file.gz
dd if=file bs=適当 skip=2 count=1 | gzip -c >> file.gz
...

709 :名無しさん@お腹いっぱい。:2008/01/05(土) 09:05:05
>>706
せんせー、ktermは?

710 :名無しさん@お腹いっぱい。:2008/01/05(土) 09:54:28
そのネタあんまりおもしろくないよ。

711 :名無しさん@お腹いっぱい。:2008/01/05(土) 10:16:01
>>709
ひねりが足りない。

712 :名無しさん@お腹いっぱい。:2008/01/05(土) 10:42:03
昭和シェルしか使ったこと無いな

713 :名無しさん@お腹いっぱい。:2008/01/05(土) 17:02:33
スクリプトの中で

n=2 の時は
command "$1" "$2"
n=4 の時は
command "$1" "$2" "$3" "$4"
というように、変数nに応じて引数の数を変える処理をしたいと思ってます。
command "$1" ... "$n"
どうすれば実現できるでしょうか?

714 :名無しさん@お腹いっぱい。:2008/01/05(土) 17:13:03
echo $#

715 :名無しさん@お腹いっぱい。:2008/01/05(土) 17:13:27
って、command "$@" でいいんかな?

716 :名無しさん@お腹いっぱい。:2008/01/05(土) 17:20:44
あるコマンドの引数に変数をしようとしているのですが、
'があるため展開されずに困っているのですが、
どうすればいいでしょうか?
----------------------------------------
hensu=123
command arg='${hensu}'
----------------------------------------

717 :名無しさん@お腹いっぱい。:2008/01/05(土) 18:11:44
>>708
それ、gzファイルが切れ目なくくっついちゃって、解凍できなくないか?

718 :名無しさん@お腹いっぱい。:2008/01/05(土) 18:17:37
>>716
'を使わない。

719 :名無しさん@お腹いっぱい。:2008/01/05(土) 18:34:06
>>717
知らないなら試せよ。

720 :名無しさん@お腹いっぱい。:2008/01/05(土) 19:42:03
>>718
レスありがとうございます。
いや、'を使わないとcommandの処理が正常に終了したいので、
どうにかして'付きで渡したいんです。宜しくお願いします。

721 :名無しさん@お腹いっぱい。:2008/01/05(土) 19:57:50
>>720
'で囲まれるとパラメーター置換は行われない。'で囲む事とパラメーター置換を行う事は排他。

722 :名無しさん@お腹いっぱい。:2008/01/05(土) 20:11:42
>>721
教えていただいて、ありがとうございます。難しいですね。
そうしたら、例えば、phpでいうと、
"'" . $hensu . "'"
のような文字列を結合することってできますか?

723 :名無しさん@お腹いっぱい。:2008/01/05(土) 20:11:44
"を使う

724 :名無しさん@お腹いっぱい。:2008/01/05(土) 20:12:36
>>720
$hensu を展開した上で、commandには ' ' を付けて渡したいということだろ?
だったら、

command arg=\'$hensu\'

>>721
知らないなら黙ってればいいのに。

725 :名無しさん@お腹いっぱい。:2008/01/05(土) 20:19:31
>>708
初めて知った
gzipはパイプ前段でddが動いてることも、>>でシェルが同じファイルに追加書きしてることも
わからないと思うんだけど、どうやって同じファイルを分割圧縮してるんだ?

726 :名無しさん@お腹いっぱい。:2008/01/05(土) 20:43:53
>>724
ハイハイ>>722見て後出し。>>721の何処が正しくないんだ言ってみろクズ。

727 :名無しさん@お腹いっぱい。:2008/01/05(土) 20:50:33
>>726
' ' で囲んだ上でパラメータ置換を行なうことはできる。排他ではない。

728 :名無しさん@お腹いっぱい。:2008/01/05(土) 21:08:09
arg="'${hensu}'"

クォートで渡すとhensuに空白文字があったときに面倒なことになる気がす

729 :名無しさん@お腹いっぱい。:2008/01/05(土) 21:34:54
>>727
>>724は囲んでいるのではなく、'を連結しているだけ。 しかも>>728が指摘しているとおり無様。

>>728は一見囲んでいるようには見えるが、arg="'${hensu}''"でも通るので却下。

730 :名無しさん@お腹いっぱい。:2008/01/05(土) 21:37:28
追記:
>>728>>722の回答としては正しい。

> 'で囲まれるとパラメーター置換は行われない。
の反例としては却下。

731 :名無しさん@お腹いっぱい。:2008/01/05(土) 21:42:10
>>725
dd if=file bs=適当 skip=0 count=1 | gzip -c > 1.gz
dd if=file bs=適当 skip=1 count=1 | gzip -c > 2.gz
dd if=file bs=適当 skip=2 count=1 | gzip -c > 3.gz
cat ?.gz > file.gz

とやったfile.gzでも、gzip -dで全体が解凍できたわ。一方gzipをcompress/uncompressに
変えたら、ファイル蛾物故割れて解凍できなかった。圧縮時は単なるファイルの連結でも、
解凍時にgzipが連結ファイルであることを認識して、続きを解凍してくれてるんだな。


732 :名無しさん@お腹いっぱい。:2008/01/05(土) 23:03:18
>> 'で囲まれるとパラメーター置換は行われない。
>の反例としては却下。
却下

733 :名無しさん@お腹いっぱい。:2008/01/05(土) 23:57:08
>>732
↓これへの反論も出来ない池沼は黙ってればいいのに。
>>728は一見囲んでいるようには見えるが、arg="'${hensu}''"でも通るので却下。

734 :名無しさん@お腹いっぱい。:2008/01/06(日) 00:07:54
>>733
それがどうした。
却下

735 :名無しさん@お腹いっぱい。:2008/01/06(日) 12:52:56
指定ディレクトリ内の容量チェックについて、
du -sh 以外で高速な方法はないでしょうか。

ファイル数や容量が多い場合、
du -sh にかなり時間がかかることが多いためです。

736 :名無しさん@お腹いっぱい。:2008/01/06(日) 20:28:38
>>735
それらファイルの所有者を測定用ユーザにしてquotaを設定しとく

737 :名無しさん@お腹いっぱい。:2008/01/07(月) 02:33:08
変数に変数を入れたいです。

n=1
var${n}=foo
echo var1=foo

直接はできないっぽいんですが、こういう時の上手い手ってありますか?


738 :名無しさん@お腹いっぱい。:2008/01/07(月) 02:59:13
>>737
eval var$n=foo

739 :737:2008/01/08(火) 02:38:23
>>738
目から鱗でした

740 :名無しさん@お腹いっぱい。:2008/01/08(火) 16:30:29
shスクリプトを作成して、inetd経由で叩こうとしてますが、
shスクリプトの中で、readで読んだ変数に改行コードらしきコードが入っていて、
うまく処理が動きません。

シェル変数 AAA,BBBの最後の1バイトを取ってあげれば動くと思うんですが、
どうやれば良いでしょうか?

以下がサンプルのスクリプトです。
コマンドラインで起動すると、PATH_VARは、キーボードから入力した2つの文字列が
'/'で連結されて表示されるのですが、これをinetd経由でtelnetから起動すると、
PATH_VARが変な文字(シェル変数AAAが設定されない?)となってしまいます。

#!/bin/sh
read AAA
read BBB
PATH_VAR="$AAA/$BBB"
echo $PATH_VAR



741 :名無しさん@お腹いっぱい。:2008/01/08(火) 16:38:40
>>740
readで読み込むと、改行コードは自動的に取り除かれる。
問題になってるのは、改行 \n じゃなくて 復帰 \r (^M) じゃないのかな

^M を取り除くには tr とか使う。

742 :名無しさん@お腹いっぱい。:2008/01/08(火) 16:44:33
>>740

read AAA
read BBB
PATH_VAR=`echo "$AAA/$BBB" | tr -d '\015'`
echo $PATH_VAR

743 :名無しさん@お腹いっぱい。:2008/01/08(火) 16:59:36
>>742
THXです。
おっしゃる通り、改行ではなく復帰でした。
だから、PATH_VARを表示した時に、AAAが表示されなかったんですね。
大変助かりました、どうもありがとうございました。

改修バージョンはこんな感じになりました。
#!/bin/sh
read line ; AAA=`echo $line | tr -d \\\r`
read line ; BBB=`echo $line | tr -d \\\r`
PATH_VAR="$AAA/$BBB"
echo $PATH_VAR


744 :名無しさん@お腹いっぱい。:2008/01/08(火) 17:48:07
なんかおかしい、制御文字? と思ったら、hexdump -Cに食わせてみると良い。

745 :名無しさん@お腹いっぱい。:2008/01/08(火) 19:03:22
>>753
そういうやり方もありですね。

>>745
echo $AAA | hd
ってやるとちゃんと制御コードが確認出来ました。

シェル変数の中身ってこうすればHEXでみれたんですね。
\とか、"とか、'とか、`とかをシェル変数に突っ込むときに、
いつも困ってたんですが、良いこと聞きました。
ありがとう。


746 :名無しさん@お腹いっぱい。:2008/01/09(水) 13:39:56
hd -c

747 :名無しさん@お腹いっぱい。:2008/01/09(水) 13:45:28
hdコマンドというのは FreeBSD方言なわけだが、、

よりポータブルには、od -Ax -t x1 だな。

748 :名無しさん@お腹いっぱい。:2008/01/17(木) 00:04:48
コンマで区切った各データを変数に入れるにはどうしたらいいんでしょうか?


749 :名無しさん@お腹いっぱい。:2008/01/17(木) 00:23:08
IFS=,
read v1 v2 v3

750 :名無しさん@お腹いっぱい。:2008/01/17(木) 01:03:42
bash 限定
read -d ,

751 :名無しさん@お腹いっぱい。:2008/01/17(木) 03:52:18
シェルの話じゃないかもしれませんが、もし適当なスレがあったら誘導してくださいませ

find . -type f -regex ".*\.[ch]\(pp\|xx\)?"
で*.cppとか.hだけを列挙できるわけですが
updatedbの--findoptionsに
updatedb --findoptions='-type f -regex ".*\.[ch]\(pp\|xx\)?"' --localpath='./' --output='/home/someone/sources.db'
などと同様に指定してもうまくフィルタリングされません(上のコマンドで生成されたものを使うと普通にディレクトリ名や要らないファイルが引っかかる)
どうにかupdatedbで生成されるデータベースの内容をコントロールする手は無いんでしょうか?

752 :名無しさん@お腹いっぱい。:2008/01/18(金) 00:42:15
>>751
そんなオプションがあるんだ。
プラットフォームは何?

クォートに問題がある気がするんだけど、これならどう?
--findoptions="-type f -regex \".*\.[ch]\(pp\|xx\)?\""



753 :名無しさん@お腹いっぱい。:2008/01/18(金) 22:20:53
実際にどういう引数がfindに渡っているか調べればいい。
OSによって違うだろうけど道具はあるはず。
多少牛刀な気もするがシステムコールのトレースとか。

754 :名無しさん@お腹いっぱい。:2008/01/19(土) 00:57:26
牛刀ってなに?
おっぱいが牛みたいな可愛い女の子剣士?

755 :名無しさん@お腹いっぱい。:2008/01/19(土) 02:36:19
>>754
1. 「牛をぶった切るための刀」
2. 「牛刀をもって鶏を割く」の略
3. 「おっぱいが牛みたいな可愛い女の子剣士」

好きなの選べ

756 :名無しさん@お腹いっぱい。:2008/01/19(土) 02:55:18
実際にどういう引数がfindに渡っているか調べればいい。
OSによって違うだろうけど道具はあるはず。
多少おっぱいが牛みたいな可愛い女の子剣士な気もするがシステムコールのトレースとか。

757 :名無しさん@お腹いっぱい。:2008/01/19(土) 10:17:30
システムコールのトレースは牛刀。

実装によるが、updatedbからのfindの呼び出しが、絶対PATHじゃないなら、
findの偽物スクリプトを作って、PATHを先に通して
引数を表示させれば良い。

#!/bin/sh
echo "$@"

みたいな。

絶対PATHの場合はちょっと厄介だが、
/usr/bin/findを一時的にリネームして、偽物findスクリプトに置き換える。

758 :名無しさん@お腹いっぱい。:2008/01/19(土) 10:51:51
新しめのupdatedbはfindを呼ばなくなってた…みたいなオチではありませんように

759 :名無しさん@お腹いっぱい。:2008/01/19(土) 10:53:30
>>757

>絶対PATHの場合はちょっと厄介だが、
>/usr/bin/findを一時的にリネームして、偽物findスクリプトに置き換える。
 客先でそれやった馬鹿がいた。しかも本番環境で……
 cronで動いていた業務処理が止まり、大騒ぎに。

760 :名無しさん@お腹いっぱい。:2008/01/19(土) 11:01:09
>759 ちゃんと本物にも渡すようにしとくのがたしなみだよなwww
#!/bin/sh
echo $@
find $@

761 :名無しさん@お腹いっぱい。:2008/01/19(土) 11:12:19
そもそも、本番環境の/usr/binの下に変更を加えちゃダメでしょ?
そ〜ゆ〜のは、テスト環境でやるもの。

762 :名無しさん@お腹いっぱい。:2008/01/19(土) 11:18:48
>>761 どこから本番環境とかテスト環境とかがでてきたんだ?


763 :名無しさん@お腹いっぱい。:2008/01/19(土) 12:02:32
>>760
それ、スクリプト無限ループw 釣りか?
あと、$@ は "$@" にしないと $@ の意味をなさない。

764 :名無しさん@お腹いっぱい。:2008/01/19(土) 12:30:00
>763 ループはネタのつもりだったが,クオーテションは素だったwww恥ずかしいwww

765 :名無しさん@お腹いっぱい。:2008/01/19(土) 13:17:50
すぐに終わるもんじゃなし、 手で実行して、psで分かるだろw

766 :名無しさん@お腹いっぱい。:2008/01/19(土) 13:26:50
まさかシステムコールのトレースが牛刀だといって757みたいな馬鹿が出てくるとは
思いもよらなかった。
execをすり替えてロギングするライブラリ作ってLD_PRELOADあたりを
想定していたんだが。

767 :名無しさん@お腹いっぱい。:2008/01/19(土) 13:40:24
>>766
LD_PRELOAD だと、コンパイルが必要。
シェルスクリプトでできるものはシェルスクリプトで済ませる方がエレガント。

まさかとは思うが、>>766 は wrapper scriptの類を、
いちいちexecv() とかで書いてコンパイルしてるのかな?

768 :名無しさん@お腹いっぱい。:2008/01/19(土) 13:50:17
>>767 /etc/libmap.conf
つか, あるもん使えばいいんじゃね?


769 :名無しさん@お腹いっぱい。:2008/01/19(土) 13:52:31
>>768
それと、「コンパイル不要」とがどう結び付くんだよ。
あと、FreeBSD限定の話をされてもな

770 :名無しさん@お腹いっぱい。:2008/01/19(土) 14:40:32
>>767
そんな面倒な事しなくても DTrace 使えば良いじゃない

771 :名無しさん@お腹いっぱい。:2008/01/19(土) 17:16:19
シェルスクリプトの本で実用例の多い本ってありませんか?

772 :名無しさん@お腹いっぱい。:2008/01/19(土) 17:28:10
>>762

>>759
> 客先でそれやった馬鹿がいた。しかも本番環境で……

773 :名無しさん@お腹いっぱい。:2008/01/19(土) 17:39:20
>>770
それこそおっぱいが牛みたいな可愛い女の子剣士だろ

774 :名無しさん@お腹いっぱい。:2008/01/19(土) 17:47:03
おっぱいが剣みたいな可愛い女の子牛士

775 :名無しさん@お腹いっぱい。:2008/01/19(土) 23:12:58
おっぱいスキデス

Cron+Cシェルで
  http://www.hoge.com/hoge.php 
を実行するのを書かなきゃいけなくなってしまいました。

1:同一サーバー内の、hoge.phpを実行するにはなんて書けばいいでしょうか?
 SHELL=/bin/csh
 ** Cronの設定 **
  /home/*****/www.hoge.com/hoge.php

2:外部のサーバー(これもCシェル)からからの場合は、http〜と直接書けるのでしょうか?
 SHELL=/bin/csh
 ** Cronの設定 **
http://www.hoge.com/hoge.php #OK?

776 :名無しさん@お腹いっぱい。:2008/01/19(土) 23:42:58
知識がスクリプト以前に、コマンドライン未満なんだが… とりあえずwgetのマニュアルでも読んで。

777 :名無しさん@お腹いっぱい。:2008/01/19(土) 23:49:02
釣りだろ、ちょっと面白かった。

778 :名無しさん@お腹いっぱい。:2008/01/19(土) 23:52:42
ちゃんと hoge.com にドメイン借用許可もらってるんだろな

779 :名無しさん@お腹いっぱい。:2008/01/19(土) 23:53:08
まず、cshを捨てる技術から憶えよう。

780 :775:2008/01/20(日) 00:35:39
>>779
わかった、じゃぁ、tcshつかうよ

781 :775:2008/01/20(日) 01:03:14
(o*。_。)oペコッ

解決しました。 wgetのそういう使い方もあるんですね。
Cshなのは、鯖屋さんの関係です。

782 :名無しさん@お腹いっぱい。:2008/01/25(金) 22:42:49
ポータブルに乱数を得るにはどうするのが一番いい?
使えそうなのはawkくらいだが、こいつは秒が変わる前に二度呼ぶと
同じ値を返してしまう。
awk 'BEGIN{srand();print rand()}'
$RANDOMはbash依存。jotはBSD系。/dev/randomもあるかどうかわからん。
perl -e 'print rand()'が一番ましだろうか。

783 :名無しさん@お腹いっぱい。:2008/01/25(金) 22:50:06
>>782
exprで乱数計算。

784 :名無しさん@お腹いっぱい。:2008/01/26(土) 00:42:39
452 名前:login:Penguin[sage] 投稿日:2008/01/16(水) 22:47:32 ID:HQvmxN1E
dateのmanを見ていたら、

 %N nanoseconds (000000000..999999999)

というのがあった。こんな感じ

% echo -n `date +%N`
431218994 % echo -n `date +%N`
857494685 % echo -n `date +%N`
269031777 % echo -n `date +%N`
803351248 % echo -n `date +%N`
195538275 % echo -n `date +%N`
538357509 % echo -n `date +%N`
058776188 %

453 名前:login:Penguin[sage] 投稿日:2008/01/16(水) 23:09:59 ID:PJonPFmQ
jotはたぶんBSD系限定だよな。
jot -r 10 1 6

/dev/urandomは10進数テキストで得るのがめんどーだろうか。 
dd if=/dev/urandom bs=2 count=1 2>/dev/null | od -vd

左カラムがじゃまだな。 sed 1q |cut -f2 -d' ' とかで削るか。

454 名前:login:Penguin[sage] 投稿日:2008/01/16(水) 23:21:36 ID:KAlEWwYc
>452,453 なるほど.date +%Nはいい感じ.
jot便利そうだよ,jot.犬にもこんなの欲しいな.
ありがとう

455 名前:login:Penguin[sage] 投稿日:2008/01/16(水) 23:24:18 ID:HQvmxN1E
od -t u1 /dev/urandom | awk '{print $2;exit}'

785 :名無しさん@お腹いっぱい。:2008/01/26(土) 09:53:03
おいおい、date +%N はポータブルじゃないよ。GNU限定かな。

786 :名無しさん@お腹いっぱい。:2008/01/26(土) 10:44:55
awk 'BEGIN{srand(('`sh -c 'echo $$'`+`date +%s`');rand();print rand()}'
でどうよ。
余計なrand()一発は、FreeBSDの実装で、srand直後のrandがおかしいため。
+%sもない前時代までポータブルにしないといかんか?


787 :名無しさん@お腹いっぱい。:2008/01/26(土) 11:19:04
>>786
じゃあ、date +%s がない Solaris10 は前時代のOSなんだw

788 :名無しさん@お腹いっぱい。:2008/01/26(土) 12:24:46
>>787
シーラカンスだろ

789 :名無しさん@お腹いっぱい。:2008/01/26(土) 14:52:38
>>788 は Solaris1.xと混同してる悪寒。

790 :名無しさん@お腹いっぱい。:2008/01/26(土) 15:07:36
*BSDとlinuxでさえ動けば,他のUNIX使ってる人は自分で勝手になんとかしてくれると思うwww

791 :名無しさん@お腹いっぱい。:2008/01/26(土) 23:11:38
rm -rコマンドを使用して、「*.txt」以外の
全てのディレクトリ・ファイルを削除したい
http://virus.okwave.jp/qa2500406.html

こいつは馬鹿なの?
http://virus.okwave.jp/user.php3?u=296068

というかなんでこれが良解答なの?

792 :名無しさん@お腹いっぱい。:2008/01/26(土) 23:26:41
*.txt以外のファイルを取得する部分は
find . ! -name '*.txt'
でいいかな?

793 :名無しさん@お腹いっぱい。:2008/01/26(土) 23:45:55
そもそも*.txtがあるディレクトリは削除できないので、
> rm -rコマンドを使用して、「*.txt」以外の
> 全てのディレクトリ・ファイルを削除したい
という要求は実現不可能。*.txtを含むディレクトリは除外なら

find . -depth -not -name '*.txt' -a \( -type d -a -empty -o -type f \) -exec rm -rf '{}' ';'

794 :名無しさん@お腹いっぱい。:2008/01/29(火) 23:10:16
>>791
> というかなんでこれが良解答なの?

一般人しかいないQAサイトじゃそんなもんだろ。

795 :名無しさん@お腹いっぱい。:2008/01/30(水) 03:01:04
while read のファイル読み込み処理の中で <enter>の入力待ちさせたい時って
みんなどうやってる?
普通に read DUMMY 入れたらバッファである<STDIN>から一行取られて終わり
だよね。
forで回避 or 子shellに分ける以外に俺の行く道はないんすかね?

==== hoge.sh START ================
#!/bin/sh
cat << EOF > ./hoge.list
AAA
BBB
CCC
DDD
EOF

while read i
do
 echo "$i"
 echo "<push enter>"
 read DUMMY
done < ./hoge.list
==== hoge.sh END ======================


ちょっと気になってググったら
ttp://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=34340&forum=10&2
>試しましたが、できましたよ。
とか回答してるやつがいた。

まじすか?

796 :名無しさん@お腹いっぱい。:2008/01/30(水) 04:29:25
>>795
/dev/ttyを使えばプロセスの制御端末から読める。
read _ </dev/tty

例:
head foo.txt |sh -c 'i=1;while read -r l; do printf "%3d: %s\n" $i "$l";i=$((i + 1)); read _ </dev/tty; done'

797 :名無しさん@お腹いっぱい。:2008/01/30(水) 05:04:54
>>795
>>796 の方が素直だが、別の fd を用意する方法もある。
例えば、ファイルを fd3 から読むのなら、こんなかんじ。

exec 3< "./hoge.list "
while read i 0<&3
do
 echo "$i"
 echo "<push enter>"
 read DUMMY
done

798 :795:2008/01/30(水) 09:17:51
>>796 >>797
おおー その手がありましたか。
ありがとうございます。


799 :名無しさん@お腹いっぱい。:2008/02/01(金) 21:46:35
別段困っているわけではないのですが、

~/.forwardをバックアップするスクリプトを書いてたのですが、

最初これでいいかなと思ったのですが、
cd /home; tar cvf /tmp/tmp.tar */.forward

よく考えたらユーザ数が非常に多い環境ではエラーになります。
それで試行錯誤して、こうしたのですが、

( cd /home ; find . -name .forward -maxdepth 2 -print | tar cvf /tmp/tmp.tar -T - )

エレガントではない。もっと綺麗な書き方はないですかね。

800 :名無しさん@お腹いっぱい。:2008/02/01(金) 21:48:51
補足。 -maxdepth を指定しているのは、各ユーザの
ホーム直下以外に .forward というファイルがあるから
です。

801 :名無しさん@お腹いっぱい。:2008/02/01(金) 21:55:29
それで充分だと思うが.
というかエレガントでないとも思わないが.

802 :名無しさん@お腹いっぱい。:2008/02/01(金) 21:58:01
find の -maxdepth と、tar の -T がポータブルじゃないのがノンエレガントだな。

803 :799:2008/02/01(金) 23:22:55
>>801
コマンドの長さが2倍になったのが気に入らなかったのです。

>>802
そこまで気が回らなかった。

804 :名無しさん@お腹いっぱい。:2008/02/01(金) 23:41:07
気が回らなかったっていうより気にする必要がなかったんじゃないの。
状況限定だろうし。あえていうなら-Tよりは-Iの方がポータブル?

805 :799:2008/02/01(金) 23:53:10
>>804 気にする必要がなかったんじゃないの

いやま、それを言うなら、うちはユーザ数が400名程度だから、
事実上、これでも全く問題ないわけなんです。

cd /home; tar cvf /tmp/tmp.tar */.forward

shellの引数の最大値は幾つぐらいだったか忘れたけど、数千のオーダーだろうし。

806 :名無しさん@お腹いっぱい。:2008/02/02(土) 00:18:03
cpio使え。

807 :名無しさん@お腹いっぱい。:2008/02/02(土) 07:19:21
質問です。
以下のように変数にスペースを含む文字列(ファイル名)を入れ、それを
別の変数の定義に使おうとしています。

FILE="foo bar.txt"
FLAGS="-l $FILE"
ls $FLAGS

しかしこれだとうまくいきません。

foo: No such file or directory
bar.txt: No such file or directory

ほかに FLAGS="-l \"$FILE\"" とか ls "$FLAGS" とか試しましたが
間違いでした。
どう書けばいいのでしょう?

808 :名無しさん@お腹いっぱい。:2008/02/02(土) 07:41:41
>>807
FLAGS="-l '$FILE'"

だけどその例だと
FLAGS="-l"
ls $FLAGS "$FILE"
の方が適当なんじゃないの。

別解としては
FLAGS='-l "$FILE"'
eval ls $FLAGS

809 :名無しさん@お腹いっぱい。:2008/02/02(土) 08:29:20
>>807
>しかしこれだとうまくいきません。
これはこれで、うまくいってるよ。
No such file or directory(そんなファイルやディレクトリはないよ)
と言われてるんだから、単にカレントディレクトリに foo と bar.txt が無いだけだよ。

正しくは >>808 の言う通りだと思う。

810 :名無しさん@お腹いっぱい。:2008/02/02(土) 10:19:27
FILE="foo bat.txt"
set -- -l
set ${1+"$@"} "$FILE"

ls ${1+"$@"}

811 :名無しさん@お腹いっぱい。:2008/02/02(土) 10:44:29
>>810
明らかに1つ以上 setしてるんだから、${1+"$@"} なんて書き方する必要なし。
"$@" だけでOK。

あと、引数が0の場合であっても現行のシェルなら "$@" ですべてOK。
${1+"$@"} という書き方はもう古いので、そろそろ撲滅すべし。

812 :名無しさん@お腹いっぱい。:2008/02/02(土) 11:12:57
これ
set -- -l
と、これ
FILE="foo bat.txt"
と、これ
set ${1+"$@"} "$FILE"
ls ${1+"$@"}
が、別々のモジュールになるかも知れないので、安全な方に倒すのが当然だね。
お前のプログラムってバグだらけだろう。

> ${1+"$@"} という書き方はもう古いので、そろそろ撲滅すべし。
Solaris10ではまだ必要。

813 :名無しさん@お腹いっぱい。:2008/02/02(土) 11:34:33
>>812
>Solaris10ではまだ必要。

嘘書くな。Solaris10上で、$# = 0 の状態で "$@" が問題なく消えてくれる
(空文字列が残らない)ことは確認済み。

${1+"$@"}が必要なようなシェルは今は残っていない。

814 :名無しさん@お腹いっぱい。:2008/02/02(土) 11:50:01
>>813
条件はSolaris10じゃなかった。
set -uされている状態で使われる可能性がある場合。

815 :名無しさん@お腹いっぱい。:2008/02/02(土) 12:04:03
>>814
言うと思った。set -u の話なんて誰もしてない。後出し乙

結論: ${1+"$@"} は不要

816 :名無しさん@お腹いっぱい。:2008/02/02(土) 12:06:40
> 言うと思った。set -u の話なんて誰もしてない。後出し乙
これを後出しと言わずして、何を後出しといおうか… 大笑い。

817 :名無しさん@お腹いっぱい。:2008/02/02(土) 12:13:13
むしろ、Solaris で set -u の時 "$@" がおかしくなるのは
Solarisのバグだと思うぞ。

そもそも set -u なんてすることは滅多にないし、そういう意味でも "$@" 推奨。

818 :名無しさん@お腹いっぱい。:2008/02/02(土) 12:21:52
元の質問は >>807 なわけだ。
そこには、
引数が0個の場合とか、
シェルスクリプトが別ファイルにわかれる場合とか、
set -uする場合とか、
一切書いていない。

勝手な条件を後出しで付け加えたのは >>810

さらに言うと、>>810 の方法では位置パラメータが破壊されるから
そもそも setを使うのは効果的じゃない。そんなことしなくてもできるし。

819 :名無しさん@お腹いっぱい。:2008/02/02(土) 12:38:45
>>817
ashでも
@: parameter not set
という警告がでるが。
> そもそも set -u なんてすることは滅多にないし、そういう意味でも "$@" 推奨。
お前perlでuse strictしないの? ダメな奴だな。

>>818
後出しでケチつけていくのがみっともない。しかも致命的な欠陥の指摘じゃないから反論される。

> さらに言うと、>>810 の方法では位置パラメータが破壊されるから
破壊されても問題ない場合や、シェルファンクションで使える。

> そもそも setを使うのは効果的じゃない。
根拠なし。

> そんなことしなくてもできるし。
別解という言葉を調べてみることをお勧めする。

820 :名無しさん@お腹いっぱい。:2008/02/02(土) 12:44:48
>>819
$ ash
$ set -u
$ echo $#
0
$ echo "$@"

$

問題なしw

821 :名無しさん@お腹いっぱい。:2008/02/02(土) 12:54:11
$ uname -a
FreeBSD orz 8.0-CURRENT FreeBSD 8.0-CURRENT #1: Tue Jan 29 01:35:03 JST 2008 root@:/usr/obj/src/sys/orz i386

$ sh
$ set -u
$ echo $#
0
$ echo "$@"
@: parameter not set

実例が提示されたので、以下は嘘。
> ${1+"$@"}が必要なようなシェルは今は残っていない。

822 :名無しさん@お腹いっぱい。:2008/02/02(土) 12:59:31
>>821
だから、set -u の話は後出し

> ${1+"$@"}が必要なようなシェルは今は残っていない。

のは、"$@" が "" (空文字列) に展開されるような古いシェルのこと。

よって、
> ${1+"$@"}が必要なようなシェルは今は残っていない。
は、正しい。

823 :名無しさん@お腹いっぱい。:2008/02/02(土) 13:06:51
> のは、"$@" が "" (空文字列) に展開されるような古いシェルのこと。
ハイハイ、後出し。wwww

> ${1+"$@"}が必要なようなシェルは今は残っていない。
これは嘘。

824 :名無しさん@お腹いっぱい。:2008/02/02(土) 13:14:38
>>812 では、
${1+"$@"}が必要な理由として、

set -- -l と FILE="foo bat.txt" と、set ${1+"$@"} が
別々のモジュールになるかも知れないので、

と言っている。
これは、引数が0個になる場合があるから、と言う意味に他ならない。

それに対する反論として、
>>813 で、${1+"$@"} は不要と言っている。

その「後」で、>>814 が set -u の話を持ち出している。

よって、>>814 の set -u が後出し。

あと、未だに set -u で "$@" がエラーになる FreeBSDもバグ持ちと言うことだな。

825 :名無しさん@お腹いっぱい。:2008/02/02(土) 13:20:24
>>807が前提条件全部出さないのが悪い。

826 :名無しさん@お腹いっぱい。:2008/02/02(土) 13:27:40
・set -- -l と FILE="foo bat.txt" と、set ${1+"$@"} が別モジュールになる。
・set -uで警告が出る(ので回避する)
は排他じゃない。

>>811は、${1+"$@"}を空文字列への展開を避けるためと思い込んで、突っ込み(>>811)を
入れたのはいいが、set -uでの警告を知らなかったため、しどろもどろで反論を続けている。
かなり見苦しいぞ。www

> あと、未だに set -u で "$@" がエラーになる FreeBSDもバグ持ちと言うことだな。
FreeBSDだけじゃなく、Solaris10でも同じように警告が出るぞ。

ところで、お前が試したashって何処のashだよ。
ash -> bashじゃねーのか? www

827 :名無しさん@お腹いっぱい。:2008/02/02(土) 14:21:04
ちょっとここまでの流れを誰かわかりやすく説明してくれwwww

828 :名無しさん@お腹いっぱい。:2008/02/02(土) 14:42:22
>>810 位置パラメータを用いた別解をだす。
>>811 ${1+"$@"}という記法に因縁つける。
>>810 反論のついでに「お前のプログラムってバグだらけだろう。」と煽る。>>812
>>811 必死の再反論を試みるが迎撃され、逃亡。 <<=== 今ココ

829 :名無しさん@お腹いっぱい。:2008/02/02(土) 15:06:57
${1+"$@"}の意味がわからない俺は間違いなくゆとりlinux使い\(^o^)/

830 :名無しさん@お腹いっぱい。:2008/02/02(土) 15:35:02
ウチの社内標準では、「${1+"$@"}は過剰品質。簡潔な記述として"$@"を使うこと」
となってる。実際、ラッパーの類とか、皆 "$@"で書かれてるよ。

831 :名無しさん@お腹いっぱい。:2008/02/02(土) 16:04:20
>>810 位置パラメータを用いた別解をだす。
>>811 ${1+"$@"}という記法に因縁つける。
>>810 反論のついでに「お前のプログラムってバグだらけだろう。」と煽る。>>812
>>811 必死の再反論を試みるが迎撃され、逃亡。
>>811 噴飯物の社内標準を持ち出す。 <<=== 今ココ

832 :名無しさん@お腹いっぱい。:2008/02/02(土) 16:09:10
set -u が問題なら、

set +u
hoge "$@"

って記述すれば委員じゃないの? 何がそんなに問題なの?

833 :名無しさん@お腹いっぱい。:2008/02/02(土) 16:09:49
で,どっちのほうが正しいんだ?
ポータビリティと簡潔さのトレードオフだとは思うんだけど.

834 :名無しさん@お腹いっぱい。:2008/02/02(土) 16:14:45
FreeBSDの /bin/shの件は send-pr よろしこ。

835 :名無しさん@お腹いっぱい。:2008/02/02(土) 16:23:08
仕様というか、文法的には、$@ は、0個の場合も含む位置パラメータに展開される
特殊パラメータとして定義されている。
この定義は、たとえ位置パラメータの個数が0個の場合でも変わらない
(=未定義にはならない)ので、
$@は、位置パラメータの個数が0個の場合でも定義されていると考えられる。
よって、set -u 状態での $@ の参照を、
「未定義パラメータの参照」とみなしてしまう一部のシェルの実装は
バグと考えて良い。

836 :名無しさん@お腹いっぱい。:2008/02/02(土) 16:25:45
>>832
冗長な記述を否定するために、より冗長な記述を持ってきても説得力ないぞ。
しかも戻すために処理後にset -u必要だし。
いや、nounsetが設定されていることを確認しないといかんな。

if set -o | egrep 'nounset *on' >/dev/null 2>&1; then
set +u
hoge "$@"
set -u
else
hoge "$@"
fi
こうか? www

>>833
噴飯物の社内標準がなければ${1+"$@"}と書いても5文字増えるだけだ。

>>834
お前がやれ。理由は「社内標準が守れないから」とでもしとけ。www

837 :名無しさん@お腹いっぱい。:2008/02/02(土) 16:33:04
$@ に限らず、$# $! $? などの「特殊」パラメータはすべて unsetできない。
unsetできるのはシェル変数だけ。
それとは別に、「位置」パラーメータは未設定の場合もあり得る。

そして、$@は、「位置」パラーメータではなく
「特殊(←ここ重要)」パラメータであるということ。

set -u はそもそもシェル変数や「位置」パラーメータのように、
未設定である場合があり得るパラメータに対してチェックするためのもの。
その set -u が、「特殊」パラメータである $@ に反応してしまうのはおかしい。

838 :名無しさん@お腹いっぱい。:2008/02/02(土) 16:35:51
>>837
いや、その説明だと、特殊パラメータの $! は、バックグラウンド起動歴が
なければ未設定になるから、説明にならない。

>>835 の説明の方が正しいんじゃないか?

839 :名無しさん@お腹いっぱい。:2008/02/02(土) 16:39:38
うん、じゃあ。その説を世界中のシェル開発者に納得させて全部修正させてから。
↓こう主張してね。
> あと、引数が0の場合であっても現行のシェルなら "$@" ですべてOK。
> ${1+"$@"} という書き方はもう古いので、そろそろ撲滅すべし。

840 :名無しさん@お腹いっぱい。:2008/02/03(日) 04:03:25
${1+"$@"} としなくても済む環境ならそれでいいだろうけど
ウチでは set -u 必須としてて環境的に ${1+"$@"} せざるを得ないんで

> 結論: ${1+"$@"} は不要

と言われても全然結論じゃないんだけどな "$@"にしたら問題起きるんで書き直しだし

まぁ言語仕様的には "$@" で問題起きない方が正しいのかもしれんが
シェル開発者や仕様企画者の集まりっていうならともかく
元々伝統的な方法でもあるんで必死こいて ${1+"$@"} を否定する意味が分からない


841 :名無しさん@お腹いっぱい。:2008/02/03(日) 07:40:37
>>840
set -u 必須ってどんな環境?

俺の認識では、set -u はあくまでデバッグ用であって、
本番スクリプトでset -uを記述するなんてあり得ないんだけどな。

で、set -u必須だったとして、例えば、あるオプション変数がセットされてれば
使うけど、セットされてなければ黙って無視したいような場合、

hoge_command $HOGE_OPT

って書いちゃ駄目なんだよね? (不便だな)
いちいち
hoge ${HOGE_OPT+HOGE_OPT}

って書くのかなw

842 :名無しさん@お腹いっぱい。:2008/02/03(日) 08:20:12
>>841
hoge ${HOGE_OPT+HOGE_OPT}
わらた
タイプミスで初期化してない変数を見てしまうバグが未然に防げる可能性があるだろ

843 :名無しさん@お腹いっぱい。:2008/02/03(日) 08:42:59
>>842
つねに ${HOGE_OPT+$HOGE_OPT} って書かなければならないルールになっちゃうから、

${HOGE_OPT+$HOGE_ORT} っていうタイプミスすると防げない。

844 :名無しさん@お腹いっぱい。:2008/02/03(日) 08:58:04
>843 中身がないときはifでよけて書けばいいんじゃね?

845 :名無しさん@お腹いっぱい。:2008/02/03(日) 08:59:22
>>844
中身がないかどうかを set -u の状態で ifで判定ってできる?

846 :名無しさん@お腹いっぱい。:2008/02/03(日) 09:09:30
空文字列か何かで初期化?

847 :名無しさん@お腹いっぱい。:2008/02/03(日) 09:16:38
>>846
シェルスクリプト内部で定義する変数なら最初空文字列で初期化でいいけど、
起動時に環境変数で渡される変数だと、
結局セットされてるかどうかの判定が必要になるからあまり意味ないね

848 :名無しさん@お腹いっぱい。:2008/02/03(日) 09:25:25
set -u 環境では、
if [ -n "$HOGE" ]; then
みたいなよくやる書き方もできないわけだ。

いちいち
if [ -n "${HOGE+$HOGE}" ]; then
って書くのかな?

あるいは最初にいちいち
: ${HOGE=}
とかするのかな。いずれにしても不便だなw

849 :名無しさん@お腹いっぱい。:2008/02/03(日) 09:30:58
>>848
[ -n "${HOGE+$HOGE}" ]
なんてしなくても、
[ -n "${HOGE-}" ]
で十分。

ところが、いつも${HOGE-}する癖がつくと結局 set -u の意味がなくなる。

rm -i をaliasしても無意味なのと似てる。

850 :名無しさん@お腹いっぱい。:2008/02/03(日) 09:46:07
>>829
俺は意味は分かるし、見かけたこともあるが、
なぜそんな冗長な書き方をしていたのかは
今の流れで初めて分かった。

で、set -u のバグがあるのは FreeBSD だけ?

851 :名無しさん@お腹いっぱい。:2008/02/03(日) 11:13:41
>>849

素人さんにプロのテクニックを教えてやろう。
set -uはタイプミスを検出するために使うんだよ。全ての変数は明示的に初期化する。
従って未定義の変数はタイプミスだ。

852 :名無しさん@お腹いっぱい。:2008/02/03(日) 11:49:24
>>851
なるほど。
一つ賢くなった気がする。

853 :名無しさん@お腹いっぱい。:2008/02/03(日) 11:55:26
>>851
その説明だと、未定義の場合もアリのスクリプトが書けない。
変数を他から引き継ぐ場合、初期化するわけにもいかない。
定義済みかどうかの判定がどこかで必要になる。
で、定義済みかどうかの判定自体が set -u に引っかかるから、
>>849 が指摘してるように冗長な記述が必要になる。
そこまで代償を払って set -u する必要もなかろう。

854 :名無しさん@お腹いっぱい。:2008/02/03(日) 12:09:06
>>853
> 変数を他から引き継ぐ場合、初期化するわけにもいかない。
> で、定義済みかどうかの判定自体が set -u に引っかかるから、
未定義ならば代入という記法があるので問題ない。(何度も出ているが${parameter=word})
いい加減に負け認めて引っ込みなよ。見苦しい。

>>810 位置パラメータを用いた別解をだす。
>>811 ${1+"$@"}という記法に因縁つける。
>>810 反論のついでに「お前のプログラムってバグだらけだろう。」と煽る。>>812
>>811 必死の再反論を試みるが迎撃され、逃亡。
>>811 噴飯物の社内標準を持ち出すも撃破される。
>>811 ムキになって反論するも、無知をさらけ出す結果に陥る。 <=== 今ココ

855 :名無しさん@お腹いっぱい。:2008/02/03(日) 12:10:30
>>854
>未定義ならば代入という記法があるので問題ない。

だから、その記述が冗長といってるんじゃないかw

856 :名無しさん@お腹いっぱい。:2008/02/03(日) 12:16:23
>>855
全ての変数は初期化するといってるだろ。
これが冗長だというならperlでも冗長だからuse strictしてないんだろうな。
「お前のプログラムってバグだらけだろう。」 www

857 :名無しさん@お腹いっぱい。:2008/02/03(日) 12:17:16
宗教論争の様相を呈してまいりました.
つうわけでアンケート.

変数は使うときまで宣言しない派?最初に宣言しとく派?

858 :名無しさん@お腹いっぱい。:2008/02/03(日) 12:20:39
シェルスクリプトは、あらかじめ変数宣言しないでも
その場ですぐ使えるのがメリットだろ。
堅苦しく変数宣言必須にするならメリット半減だな。

859 :名無しさん@お腹いっぱい。:2008/02/03(日) 12:21:08
そのアンケートは的外れ。

860 :名無しさん@お腹いっぱい。:2008/02/03(日) 12:28:27
シェルスクリプトで変数宣言するのは
関数のローカル変数を設定する時ぐらいだな。


861 :名無しさん@お腹いっぱい。:2008/02/03(日) 12:28:45
set -u 派の人って、#!/bin/sh -u で記述してるの?
それとも本文に set -u 入れてるの?
あまり見かけないけど

862 :名無しさん@お腹いっぱい。:2008/02/03(日) 12:33:57
>>858
キミのしょぼいスクリプトを基準に語られても困る。

863 :名無しさん@お腹いっぱい。:2008/02/03(日) 12:36:43
例外?何それみたいな使い捨てスクリプトも書けるし
ずっと使っていくようなものも書ける
その幅の広さがシェルスクリプトのいいところじゃね?

864 :名無しさん@お腹いっぱい。:2008/02/03(日) 13:47:22
横槍だが、そもそも${1+"$@"}がどういう意味なのか
わからないから、なぜそう書くのか理解できない。

865 :名無しさん@お腹いっぱい。:2008/02/03(日) 13:57:57
${parameter+word}という記法はparameterがセットされている場合はwordに展開される。
なので、${1+"$@"}は位置パラメーター$1がセットされていると"$@"に展開される。

866 :864:2008/02/03(日) 14:51:45
>>865
ありがとう。manには:+しかなかったから別物だと思った。
見なおしたら"If the colon ( :) is omitted〜"って文があった。
www.cs.princeton.edu/~jlk/kornshell/doc/man88.html

867 :名無しさん@お腹いっぱい。:2008/02/04(月) 21:43:38
>>811 ほら調べてやったぞ。SUSE 9, Redhat 4, Solaris10, Service for UNIX 3.5
警告でないのはRedhat 4のashだけだ。FreeBSD 8も合わせてバグ報告しとけ。www
★SUSE LINUX Enterprise Server 9 (x86_64) p3
$ /bin/ash -cu 'echo "$@"'
/bin/ash: @: parameter not set
$ /bin/ksh -cu 'echo "$@"'
/bin/ksh: @: parameter not set
★Redhat 4 u5
$ /bin/ash -cu 'echo "$@"'

$ /bin/ksh -cu 'echo "$@"'
/bin/ksh: @: parameter not set
★Solaris10 8/07
$ /bin/sh -cu 'echo "$@"'
/bin/sh: @: parameter not set
$ /bin/ksh -cu 'echo "$@"'
/bin/ksh: @: parameter not set
$ /usr/xpg4/bin/sh -cu 'echo "$@"'
/usr/xpg4/bin/sh: @: parameter not set
★SFU(Service for UNIX) 3.5
$ /bin/sh -cu 'echo "$@"'
/bin/sh: @: parameter not set
$ /bin/ksh -cu 'echo "$@"'
/bin/ksh: @: parameter not set

868 :名無しさん@お腹いっぱい。:2008/02/04(月) 21:46:31
>>867
もはやこれは愛だな

869 :名無しさん@お腹いっぱい。:2008/02/04(月) 22:03:43
Kシェルスクリプトについての質問です。

file1に入っている文字を、file2の中で検索し、あればエラーなしという
スクリプトを書きたいのですが、どなたかご教授願えないでしょうか?

file1には以下のような文字が200行程度、入っています。
aaa 12345678
bbb 12345678
ccc 12345678

file2には以下のような文字が300行程度入っております。
aaa 09876543
bbb 09876543
ccc 09876543
ddd 09876543

このfile1に入っている頭3文字の行全てを、file2の頭3文字にあるかないか、
といったスクリプトを書きたいのですが、シェルの基本程度しかしらず
悪戦苦闘をしております。なにとぞ、ご教授願いますよう、お願いします。

870 :名無しさん@お腹いっぱい。:2008/02/04(月) 22:11:16
>>869
kshじゃなくても、普通のshで書けるね。


#!/bin/sh

while read key other
do
if grep -q $key file2; then
echo "$key は file2にある"
else
echo "$key は file2にない"
fi
done < file1

871 :869:2008/02/04(月) 22:16:58
Kシェルが社内標準になっちゃったんです…
さらに運悪くジョブ管理までやらされるはめに。
ご迷惑をおかけしますが、何卒よろしくお願いします

872 :名無しさん@お腹いっぱい。:2008/02/04(月) 22:17:48
kshは下位互換性ないの?

873 :名無しさん@お腹いっぱい。:2008/02/04(月) 22:18:56
>>871
だったら #!/bin/ksh って書けばいいだけだよ。

あと、grep -q $key は grep -q "^$key" の方がいいかな。

874 :名無しさん@お腹いっぱい。:2008/02/04(月) 22:19:52
shでできることは、ほぼそのまま変更せずにkshでもできる。

875 :869:2008/02/04(月) 22:20:57
>>872
あるんですが、今後はKシェルで書けとの命令が上から下りまして…

876 :名無しさん@お腹いっぱい。:2008/02/04(月) 22:24:19
>>875
こいつ、ネタか?
この場合、kshで書いても shと全く同じものになるんだよ。

それとも、何か最低限 ksh専用の文法を使わなけりゃいかんのかよ?

877 :869:2008/02/04(月) 22:32:56
皆様、ありがとうございます。
丁寧に答えてくださり、まことに感謝しております。

>>876
何分Kshの事を全然知らなくて…
Goto文が書けないやら、色々戸惑っている最中です。
もし何かまたわからない事がありましたら、ご質問させていただきます。

今回は本当にありがとうございました。

878 :名無しさん@お腹いっぱい。:2008/02/04(月) 22:41:33
横レスで便乗質問です。
偶然ですが、>>870 と同じようなスクリプトを書くために悪銭苦闘しています。
とりあえず /bin/shでではできたんですが、
今後はbashシェルで書けとの命令が上から下りまして…
>>870 をbashシェルで書くとどのようになりますでしょうか、ご教授ください。
なお、#!/bin/shを#!/bin/bashに変えただけでは却下され、
何か最低限bashシェル専用の文法を使わなければ上司が納得してくれません。

879 :名無しさん@お腹いっぱい。:2008/02/04(月) 23:26:50
あっそ

880 :名無しさん@お腹いっぱい。:2008/02/04(月) 23:44:18
>>878
なぜsh互換ではNGでbash専用でないとダメなのか
その上司を問いつめて、結果をこのスレに書き込んでみ?

881 :名無しさん@お腹いっぱい。:2008/02/05(火) 00:49:39
おれのエスパー予想では、話題を変えようとしている>>811の涙目自演。

882 :名無しさん@お腹いっぱい。:2008/02/05(火) 02:11:40
>>878
まず
ttp://search.luky.org/linux-users.9/msg06102.html
とか嫁

883 :名無しさん@お腹いっぱい。:2008/02/05(火) 02:30:35
>>878
test とか [ を [[ 記法にでも変えたら?


884 :名無しさん@お腹いっぱい。:2008/02/05(火) 03:10:05
ttp://www.nicovideo.jp/watch/sm2217336
うっう〜

885 :名無しさん@お腹いっぱい。:2008/02/05(火) 07:15:24
>>883
testも[もないんだが、>>870 には。

886 :名無しさん@お腹いっぱい。:2008/02/05(火) 09:47:50
その気になればいくらでも変態的記法で書き換えられるぞ。w
こんなの趣味でも書かないけどな。w

#!/bin/bash

while read line
do
 grep "${line:0:3}" file2 &> /dev/null
 if $[ $? == 0 ] ; then
  echo "$key は file2にある"
 else
  echo "$key は file2にない"
 fi
done <<< "$( < file1 )"

887 :名無しさん@お腹いっぱい。:2008/02/05(火) 09:49:48
あ、間違えた。
けど、こんなの使わないからいいか。w


888 :名無しさん@お腹いっぱい。:2008/02/05(火) 10:19:41
互換性がなかったらシェルスクリプトの良さの3割を失なってると思うんだ…

889 :名無しさん@お腹いっぱい。:2008/02/05(火) 10:33:29
そうでもないよ。

890 :名無しさん@お腹いっぱい。:2008/02/05(火) 10:56:19
むしろ使い捨ての方が圧倒的に多いよなw
他の環境どころか、明日はもう動かなくていいやつとか。

891 :名無しさん@お腹いっぱい。:2008/02/05(火) 12:31:07


892 :名無しさん@お腹いっぱい。:2008/02/06(水) 13:18:18
$ find $HOGE -not -regex ".*#.*" -not -name "*~" -not -name "*svn*" -name "*.[ch]*"
のようなものの-not -regex ".*#.*" -not -name "*~" -not -name "*svn*"の部分だけを再利用したいんですが
ignore_backup="-not -regex \".*#.*\" -not -name \"*~\" -not -name \"*svn*\""
のようにして
$ find $FOO $ignore_backup -name "*.el"
としてもうまくフィルタリングしてくれないようです
何が良い方法はありませんか?


893 :名無しさん@お腹いっぱい。:2008/02/06(水) 13:33:03
evalれば?

894 :名無しさん@お腹いっぱい。:2008/02/06(水) 14:01:27
\"取るとか

895 :名無しさん@お腹いっぱい。:2008/02/06(水) 14:10:12
アドバイスありがとうございました。
evalすると言う手でなんとかしました
zsh,bashでしか確認してませんがとりあえずこんな感じでいけました
この方針なら内部で他の変数を参照する予定の無い文字列はsingle quoteにした方がよさそうですね
# dot files
ignore_bkup='-type f -not -regex ".*#.*" -not -name "*~"'
eval "$find $HOME -maxdepth 1 $ignore_bkup -regex '.*\/\..*'"


896 :名無しさん@お腹いっぱい。:2008/02/06(水) 14:19:36
普段は ' で、展開したい時だけ "

897 :名無しさん@お腹いっぱい。:2008/02/06(水) 19:47:26
質問があるのですが、
引数にlistという文字列がある場合には、lsコマンドを実行する
これを実行するにはどういう構文をつくればいいのでしょうか?

898 :名無しさん@お腹いっぱい。:2008/02/06(水) 20:05:04
>>897
for arg in "$@"
do
case $arg in
list)
ls;;
esac
done

899 :名無しさん@お腹いっぱい。:2008/02/06(水) 20:22:09
>>898
ありがとうございます

900 :名無しさん@お腹いっぱい。:2008/02/06(水) 23:46:40
>>898
$args → "$args"

901 :名無しさん@お腹いっぱい。:2008/02/06(水) 23:47:18
>>900
お前馬鹿だろ

902 :名無しさん@お腹いっぱい。:2008/02/07(木) 00:30:09
>>878
> 何か最低限bashシェル専用の文法を使わなければ上司が納得してくれません。

お前に必要なのは不要な文法ではなくて新しい職。

903 :名無しさん@お腹いっぱい。:2008/02/07(木) 04:59:08
902と意味するところは多分違うが表面的には同意。

904 :名無しさん@お腹いっぱい。:2008/02/07(木) 09:35:36
(1)
$ echo .string | sed -e s/^\\\\.//
.string

(2)
$ AAA=.string
$ BBB=
$ BBB=`echo "$AAA" | sed -e s/^\\\\.//`
$ echo $BBB
string


(1)(2)で結果が違ってくるのですがこれはなぜでしょうか。


905 :名無しさん@お腹いっぱい。:2008/02/07(木) 09:48:23
`〜`
を使っているから。


906 :名無しさん@お腹いっぱい。:2008/02/07(木) 09:49:18
BBB=`echo "$AAA" | sed -e 's/^\\\\.//'`

907 :名無しさん@お腹いっぱい。:2008/02/07(木) 09:55:55
BBB=`echo "$AAA" | sed -e s/^\\\\\\\\.//`

908 :名無しさん@お腹いっぱい。:2008/02/09(土) 01:16:11
BBB=`echo "$AAA" | sed -e s/^\\\\\\\\\\\\.//`

909 :名無しさん@お腹いっぱい。:2008/02/11(月) 14:50:12
すみません。
unixのwc -lコマンドと同等のものを
perlやawkの一行野郎にしたいのですがうまくいきません

perl -ne 'while (<>) { print cnt}' file1
お願いします

910 :名無しさん@お腹いっぱい。:2008/02/11(月) 14:55:30
一行野郎ってなに?

911 :名無しさん@お腹いっぱい。:2008/02/11(月) 14:58:34
ワンライナーのことか。
awk使いたいだけなら、
cat file1 | cat -n | tail -1 | awk '{print $1}'
でいいじゃん。

912 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:00:28
>>911 アフォか。無駄過ぎ。いろんな意味で。

913 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:03:27
無駄ってのは
cat file | cat -n
ってところかい?
それは最初のcatは、catじゃなくても他の部分から取れるようにしてるのだが。

914 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:03:40
>>909
awk 'END{print NR}' file

915 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:04:54
>>913
無駄ってのは、>>914 でできるのにわざと冗長な方法を書いていること。

916 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:05:56
>>909をみてる感じでは、一行づつ数えたいんだと理解したのだが…。

917 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:08:23
wc -lは複数ファイルを引数に与えられるが、そこまで同等なのか、標準入力だけでよいのか。
要求をはっきりしたまえ。

もっとも、↓これなら完璧だが。
perl -e 'exec "wc", "-l", @ARGV'

918 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:09:44
そんなことより、>>909がなぜ行数を数えて出力できると思ったのか
みんなで考察してみようぜ。

まず、どこから急にcntが出て来たのか。

919 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:11:25
一つのファイルだとも複数のファイルだともストリームからだとも言ってないんだから、
>>911でいいじゃないか。
思い付いたようにシンプルに済ませるのがShellScriptでしょ。

920 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:12:23
すみません。909です。
サーバ環境のコードに合わない文字コードのファイルだと
wcコマンド使えないので他に代用したいというのが背景です。

目的はファイルの行数を単にカウントするだけです。

921 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:18:32
何言っちゃってんの?

922 :名無しさん@お腹いっぱい。:2008/02/11(月) 15:28:57
と、>914さんの方法で解決できました!
みなさんありがとうございました

923 :名無しさん@お腹いっぱい。:2008/02/11(月) 16:58:29
やっぱり >>911 はアフォだったね。

awkなら、>>914 が解として最善だが、wcの文字コードの問題なら、
LANG=C LC_ALL=C wc -l
としても解決できるはず。

924 :名無しさん@お腹いっぱい。:2008/02/11(月) 17:11:58
阿呆とは思わんけど、ちゃんと情報を聞いてから答えるべきだったね。
それは>>914もそうだが。

925 :名無しさん@お腹いっぱい。:2008/02/11(月) 17:23:15
>>924
そんな必要ない。最初の質問情報だけで最適解を出すのが良い。
それで求めているものと違っているなら質問者が再度質問してくるだけだから。
それより問題なのは、最適解を知らないくせに質問者に追加情報だけ出せという奴。
(で、たいてい追加情報が出てきても最適解を答えられないw)

926 :名無しさん@お腹いっぱい。:2008/02/11(月) 17:41:27
>>925 == >>914か?
もし複数のファイルを対象にしたいとか>>914の解とは違ってたら、情報を小出
しにするなとか言い出すんだろうなw

まぁ、そんなことより追加情報が出る度に解を出して良くってのはものすごい
効率が悪いな。 最初に情報を聞き出してから普通は何かを作るだろ。
仕様が不十分なままにコード書き始めて、途中で仕様がひっくり返ったら全部
作り直しだろ。


927 :名無しさん@お腹いっぱい。:2008/02/11(月) 17:41:00
>>925
そのとおりだ

928 :名無しさん@お腹いっぱい。:2008/02/11(月) 17:45:28
ぐだぐだ言わずにとりあえずコード書けってこと?

929 :名無しさん@お腹いっぱい。:2008/02/11(月) 17:48:56
>>925は自分の解が最適だと思ってるのか:-)
適してるならまだしも、最適って。
別に>>911でも解としては間違ってないわけで、
なんでそんなに自分の解に自信を持ってるのかと。

930 :名無しさん@お腹いっぱい。:2008/02/11(月) 17:54:51
逆に、質問を変えて >>911 の解が最適になるようにしようとしてもできない。
awkを使うなら、cat -nだけでなくtail -1の機能もawk側でできるから、
わざわざ多段パイプにするのが無駄。
逆に、cat -n|tail -1にするなら、最後までawkを使わずに処理するべき。(cutとかで)

931 :911:2008/02/11(月) 17:55:43
なんか騒いでるみたいだけど…。

perl -e 'while(<>){} print "$.\n"' file1
行数数えるだけならこうかな。

最適っていうなら、「Perlやawk」でって言ってるんだから、Perlでの最適な答えも出して上げれば良いのに。
もちろん、上の解が最適だとは思わないけどね。
他にもやり方は色々あるし、毎行処理してる時点で最適ではないし。
(awk {END}もそうだけど。)

932 :911:2008/02/11(月) 17:56:59
>>930
awkを使って。 って書いてあるから、awkを使っただけなんだけど…。
awkはあんまり使わんから、とりあえずできればって思っただけなんだけど。
まぁ、自分はそんなに自信があって言ったわけじゃないからねスマンね。

933 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:04:11
確かに無駄に毎行処理するのは(>>914は最後のみ実行だが、それまでも内部処理される)よろしくないな。
>>914 最適な解を望む。 最適な解だぞ。

934 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:07:05
>>932
だから、awkを使ってっていってるのに、
なんで awk側でできる cat -n や tail -1 相当の処理を
awk側でやらないのかってこと。

>>930 の最後の行で言ってる、「最後までawkを使わずに処理するべき」ってのは、
「cat -n | tail -1」を使う以上は、ってこと。
で、それだと「awkを使う」という質問に適合しないから、
>>911 は解にならないと言いたいわけ。

935 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:08:05
perl -lne 'END{print$.}' < file
かな。


936 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:09:37
>>934
それだとお前の最適って言う言葉も最適ではないから解ではないな。

937 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:14:55
元質問者は >>922 で、>>914 を使って解決したんだからそれでいいじゃん。

で、>>920 で言ってるように、本当は wc -l を使いたかったけど、
それだと日本語環境で文字コードが解釈されてエラーになるのが問題なんだから、

>>923 が言うように、
LANG=C LC_ALL=C wc -l
が最適解だね。

938 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:18:55
tmp]$ time perl -lne 'END{print$.}' < tmp
89232

real 0m0.359s
user 0m0.327s
sys 0m0.011s
tmp]$ time perl -e 'while(<>){} print "$.\n"' tmp
89232

real 0m0.273s
user 0m0.236s
sys 0m0.010s

tmp]$ time awk 'END{print NR}' tmp
89232

real 0m0.150s
user 0m0.126s
sys 0m0.009s

tmp]$ perlcc -B tmp.pl; time ./a.out tmp
89232

real 0m0.286s
user 0m0.263s
sys 0m0.000s

やっぱりawkが早いな。

939 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:19:55
>>937
awk, Perlを使っての解がしりたかったみたいだから、wcは最適じゃないな。

940 :938:2008/02/11(月) 18:20:42
っていうか、バイトコンパイルしたら遅くなっちった。

941 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:30:05
>>939
>>920 欲嫁。質問者はwc使いたかったけど使えなかったから仕方なくawkまたはperlで
ということだから、>>923 のwcが最適だね。

942 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:35:26
コントロールコードが入ってたりしてwcが使えないのが原因だったらどうするの?
勝手に想像するのは良くないよ。
>>924欲嫁

943 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:37:51
>>942
> コントロールコードが入ってたりしてwcが使えないのが原因だったらどうするの?

そんなのありえるの? 具体的には?

944 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:38:27
>>942
コントロールコードが入っていても LANG=C なら wcは無問題。
実際に試してから言おうね。

945 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:41:01
>>944
全てのコントロールコードで試したの?
そのファイルをくれないかな。

946 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:44:45
>>945
墓穴ほってるよww

そんなの、たとえば
dd if=/dev/random bs=1024k count=1 | LANG=C wc -l

で検証できる。ファイル用意する必要なし。

947 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:47:29
コントロールコードなら有限だから楽勝だな。

948 :945:2008/02/11(月) 18:47:55
俺は全てのコントロールコードで試したとは言っていないが?
君が、
> 実際に試してから言おうね。
って言ったんじゃないの?
randomで出したところで、全てのコントロールコードは試してないよね。
実際に試してないのに言っちゃったの?

949 :945:2008/02/11(月) 18:49:46
>>946
あと、それはどうやって正確に行数を数えてることを実証するの?
どこかに書き出して、自分で数えたりしてるの?

950 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:51:27
意外に最初想像したよりもおもしろい展開になったな

951 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:52:24
>>948
コントロールコードって、全部で32個(DELも入れると33個か?)だけって知ってる?

952 :945:2008/02/11(月) 18:52:59
tmp]$ dd if=/dev/random bs=1024k count=1 > tmp_r

tmp]$ cat tmp_r | LANG=C wc -l
0
tmp]$ cat tmp_r | perl -e 'while(<>){} print "$.\n"'
1
tmp]$ cat tmp_r | awk 'END{print NR}'
1
tmp]$ cat tmp_r | perl -lne 'END{print$.}'
1


ものすごい影響されてるが…。


953 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:53:37
以降、>>945 がいつまで自分の無知をさらけだすか見守りたいと思います。

954 :名無しさん@お腹いっぱい。:2008/02/11(月) 18:55:43
>>952
ワロタwwwwww
>>951は自分の発言すら試してなかったのか?w
それともたまたまうまくいっただけか

955 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:00:40
>>952 では別の問題が発生してるみたいだね。
/dev/randomじゃなくて /dev/urandomでやるべき。
/dev/randomを ddで吸い出すと、十分なエントロピーがなくて
ほとんどがゼロで埋まってるものと思われ。

それとは別に、wc -lでは、最後の改行がない行を数えないが、
awk 'END{print NR}'では数えるから、行数が1ずれる。

その点は、>>945 が最初指摘していたコントロールコードの問題とは違うので、
勘違いしないように。

956 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:04:10
>>952
だいたい、1MBも乱数で取ったのに '\n' が1つしかない時点で
その実験自体がおかしいことに気づけww 乱数になってない。

957 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:06:04
952の人気はすばらしい

958 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:06:49
乱数なんだから1個でどこがおかしいんだよ。
しかもファイルがおかしいにしても、今回はwcが扱えないことはわかったでしょ。

959 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:06:53
改行コード(\n) = 1行
ということなら、この場合やはり LANG=C wc -l の計数表示が正しいということになる。
awk 'END{print NR}' では、最後の不完全な行までカウントしてしまう。

そういう意味で、やはり LANG=C wc -l が最適ということになるな。

960 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:09:54
実験してみた。

$ echo -n a > file
$ LANG=C wc -l < file
0
$ awk 'END{print NR}' < file
1

ということだ。LANG=C wc -l の方が正しいな。

961 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:10:33
では、>>914は自信満々だったけど正しくなかったのか。
最適とか言ってたのに残念。

962 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:12:19
>>959
違うだろ
改行がある限り2行

963 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:13:10
>>961
>>914 は wcを使わないという時点では最適だろ。
で、あとでwcを使わなかった理由が質問者から示されたから、
それならLANG=Cでということで、wcが最適になっただけのこと。

964 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:13:51
定義問題だな
wcのmanではああなっているから

965 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:14:30
では、結局新しい情報がでてきてもそれに答えられなかった>>914は最適じゃないでしょ。
次々に新しい解を出すのが>>914の言う最適な解なんだから。

966 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:15:26
最適最適って言ってるけどさ,最適ってどういうこと?タイプ数が最小なものってこと?

967 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:15:50
>>914に聞いてくれ。

968 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:16:20
いいからそろそろ次スレよろ

969 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:18:13
じゃあ>>970が次スレを立てる

970 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:19:33
立ててきます

971 :名無しさん@お腹いっぱい。:2008/02/11(月) 19:25:06
シェルスクリプト総合 その10
http://pc11.2ch.net/test/read.cgi/unix/1202725267/

972 :名無しさん@お腹いっぱい。:2008/02/11(月) 20:25:21
このスレでダメだという指摘が出来ないものが最適。

973 :名無しさん@お腹いっぱい。:2008/02/11(月) 21:55:14
なんかいいスレだな。wktk

974 :名無しさん@お腹いっぱい。:2008/02/11(月) 22:31:36
というか、awkはスレ違い。
シェルならシェルだけでやれ。

975 :名無しさん@お腹いっぱい。:2008/02/11(月) 22:52:08
シェルだけでやる場合の最適解

n=0; while read dummy; do ((n++)); done < file ; echo $n

976 :名無しさん@お腹いっぱい。:2008/02/11(月) 23:06:41
>>975
bash依存。失格。

977 :名無しさん@お腹いっぱい。:2008/02/11(月) 23:33:04
じゃあこれでどう?
シェルだけということで、exprすら使わないようにしたよ

set --; while read dummy; do set "$@" a; done < file ; echo $#

978 :名無しさん@お腹いっぱい。:2008/02/11(月) 23:46:18
>>977
set -- はシェル実装依存。shift $# の方が確実だな。

979 :名無しさん@お腹いっぱい。:2008/02/12(火) 00:10:10
/bin/sh
だけでできるようにしてくれや。

980 :名無しさん@お腹いっぱい。:2008/02/12(火) 01:22:43
祭りに乗り遅れた。。

981 :名無しさん@お腹いっぱい。:2008/02/12(火) 07:24:15
>>979
>>977 は /bin/shだけでできる。

982 :名無しさん@お腹いっぱい。:2008/02/12(火) 07:46:07
>>977の動作のしくみがわからない俺わろた

983 :名無しさん@お腹いっぱい。:2008/02/12(火) 21:26:24
読むたびに位置パラメータ(知らなければコマンドライン引数みたいなものと思え)
にaという文字を追加。
最後に位置パラメータの「個数」(=aを追加した回数=行数)を表示。



984 :名無しさん@お腹いっぱい。:2008/02/12(火) 21:50:09
>>977
行末に \ がある行があると計数ミスするなぁ

985 :名無しさん@お腹いっぱい。:2008/02/13(水) 16:33:50
というか、wc (オプションなし)だと確かに LANG=C以外の時エラーが出るが、
wc -l とか wc -c だと、そもそも単語に分ける必要ないから文字コードも見ないし、
LANG=C にする必要ないぞ。
wc -l オプション付けてるのに LANG=C が必要なのって、どこの wcコマンド?

986 :名無しさん@お腹いっぱい。:2008/02/14(木) 22:16:07
>>977
それ、1万行とか10万行とかあってもちゃんと動作するんだろうか?
というか、$#の上限ってどこかで決まってるんだろうか?

987 :名無しさん@お腹いっぱい。:2008/02/14(木) 22:25:48
とりあえず上限調べて、予想するとかソース読むとか

988 :名無しさん@お腹いっぱい。:2008/02/14(木) 22:32:48
ボーンでは9が上限

989 :名無しさん@お腹いっぱい。:2008/02/15(金) 02:42:56
${10}

990 :名無しさん@お腹いっぱい。:2008/02/15(金) 07:27:00
>>989
だからぁ、ボーンでは ${10} は使えないんだよ。

991 :名無しさん@お腹いっぱい。:2008/02/15(金) 08:19:41
>>989

$ /bin/sh
$ uname -sr
SunOS 5.10
$ echo ${10}
bad substitution


知らないくせに余計な突っ込みするなよw

992 :名無しさん@お腹いっぱい。:2008/02/15(金) 08:31:15
shiftしても引数を9個以上とれないってこと!?

993 :名無しさん@お腹いっぱい。:2008/02/15(金) 08:44:59
shiftすれば行けるだろ。${10}は行けないけど。

994 :名無しさん@お腹いっぱい。:2008/02/15(金) 22:14:21
ash 0.3.8で
while :; do
set -- "${@}" a
echo $#
done
の出力が15000越えるところまでは見た。
これ以上元祖に近いシェルは手元にないので勘弁。

別に$10とかに直接アクセスできる必要はないんだよな。



995 :名無しさん@お腹いっぱい。:2008/02/15(金) 22:39:28
たしかに$1から$9をとばして$10だけが必要になる場面が想像できない
俺は極端には$1とshiftだけでもやっていけるな

996 :名無しさん@お腹いっぱい。:2008/02/15(金) 23:04:11
位置パラメータをコマンド引数として解釈する場合は ${10}とか要らないが、
set を配列代わりに使う用法では、${10}以上の要素に直接アクセスできないとな。
でも、結局Bourneでは使えない方法だから用途は限られる。

997 :名無しさん@お腹いっぱい。:2008/02/15(金) 23:15:51
今回は数を数えるためだけに使ってるからいいよね。


998 :名無しさん@お腹いっぱい。:2008/02/16(土) 01:42:35
行カウントコードの別案出してみる:

 $ (IFS='
 > '; IFS= set -- `cat foo`; echo $#)

どんな状況でも機能するのかはちょっとあれだが・・・

999 :名無しさん@お腹いっぱい。:2008/02/16(土) 06:58:04
h

1000 :小倉優子 ◆YUKOH0W58Q :2008/02/16(土) 06:58:38
1000ならジュースでも飲むか

1001 :1001:Over 1000 Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。

261 KB
★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)