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

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

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

1 :ミスターシェル:2006/09/07(木) 13:00:11
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>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 でトレースしましょう。

2 :ミスターシェル:2006/09/07(木) 13:01:14
□前スレや過去スレ:
シェルスクリプト総合 その6
http://pc8.2ch.net/test/read.cgi/unix/1143302182/
シェルスクリプト総合 その5
http://pc8.2ch.net/test/read.cgi/unix/1137801629/
シェルスクリプト総合 その4
http://pc8.2ch.net/test/read.cgi/unix/1131026501/
シェルスクリプト総合 その3
http://pc8.2ch.net/test/read.cgi/unix/1124889646/
シェルスクリプト総合 その2
http://pc8.2ch.net/test/read.cgi/unix/1113664637/
シェルスクリプト総合 その1
http://pc8.2ch.net/test/read.cgi/unix/1101820646/

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

□他板の関連スレ:
【sed】シェルスクリプト総合@LINUX Part2【awk】
http://pc8.2ch.net/test/read.cgi/linux/1154578200/
【Shell】どのシェル使ってる?【Script】
http://pc8.2ch.net/test/read.cgi/linux/1067330754/

3 :ミスターシェル:2006/09/07(木) 13:02:10
□初心者向けリンク
「誰にでも」シリーズ
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 :ミスターシェル:2006/09/07(木) 13:03:23
□最近のシェルスクリプト本(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 :ミスターシェル:2006/09/07(木) 13:06:03
□関連書籍と関連リンク:

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/

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

□シェルスクリプトでよく使うコマンド:
制御・条件判定系: [,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 :名無しさん@お腹いっぱい。:2006/09/07(木) 13:11:37
>>1
スレ立て乙です。

8 :名無しさん@お腹いっぱい。:2006/09/07(木) 15:48:22
うむッ

9 :質問:2006/09/07(木) 17:25:28
お願いします。

awkの中で変数を使いたいんですが出来ません。
例えば

#!/bin/sh
a=xyz
awk '/^${a}/{print $2}' abc


行き詰まってしましました。
解決策を教えてください。

10 :名無しさん@お腹いっぱい。:2006/09/07(木) 17:36:00
>>9
awk '/^'"${a}"'/{print '"$2"'}' abc


11 :名無しさん@お腹いっぱい。:2006/09/07(木) 17:38:38
>>10
$2 は awk側の変数だろ。

awk '/^'"${a}"'/{print $2}' abc

12 :名無しさん@お腹いっぱい。:2006/09/07(木) 17:48:58
>>9
せっかくシェルスレなんだからawk何か使わずに
シェルだけでやれ。


#!/bin/sh

a=xyz
while read f1 f2 f3
do
case "$f1" in
"$a"*) echo "$f2";;
esac
done < abc

13 :名無しさん@お腹いっぱい。:2006/09/08(金) 01:47:20
>12
前スレから見てるけど、改良や改善などの挙げ句どのみち何らかの
スクリプト言語になっちまうのは、避けられない宿命っぽいよ。

14 :名無しさん@お腹いっぱい。:2006/09/08(金) 01:57:38
awkまではセーフ。

15 :名無しさん@お腹いっぱい。:2006/09/08(金) 03:53:42
sedも含めてあげようじゃないか


16 :名無しさん@お腹いっぱい。:2006/09/08(金) 16:10:48
whoamiもOK

17 :名無しさん@お腹いっぱい。:2006/09/08(金) 16:20:30
>>16
つながりがよくわからんが、Solarisにはwhoamiコマンドが無かった希ガス。

18 :名無しさん@お腹いっぱい。:2006/09/08(金) 16:30:26
なかったらどうだと言うんだ。

19 :名無しさん@お腹いっぱい。:2006/09/08(金) 16:33:49
なかったらOKとは言えないだろ。

20 :名無しさん@お腹いっぱい。:2006/09/08(金) 16:47:14
Solarisにない物は不可。

21 :名無しさん@お腹いっぱい。:2006/09/08(金) 17:22:09
Solarisにある物は可。

22 :名無しさん@お腹いっぱい。:2006/09/08(金) 17:35:35
>17
whoamiは
sunOS 5.7には無かった
sunOS 5.9には有った

who am i
はどちらでも使える。

5.8は使ってないからわからん。

23 :名無しさん@お腹いっぱい。:2006/09/08(金) 17:38:02
whoami と who am i は意味が違うわけだが。
su して who am i しても、su前の一般ユーザーが表示されるはず。

24 :名無しさん@お腹いっぱい。:2006/09/08(金) 17:43:54
>23
いや それはもちろんわかってるって w
ネタとして遊んで欲しかった・・・

25 :名無しさん@お腹いっぱい。:2006/09/08(金) 18:38:36
#!/bin/sh
ps u | awk '$2 == '`echo $$`' {print $1}'


26 :名無しさん@お腹いっぱい。:2006/09/08(金) 18:40:35
>>25
echoが無駄です。$$ だけで桶。

27 :名無しさん@お腹いっぱい。:2006/09/08(金) 18:46:46
シェルでやるならこうか

ps u | while read f1 f2 f3; do case $$ in $f2) echo "$f1";; esac; done

28 :名無しさん@お腹いっぱい。:2006/09/08(金) 18:53:12
ps -o user | tail -1

29 :名無しさん@お腹いっぱい。:2006/09/08(金) 18:56:28
そんなことしなくても、これで一発。

ps -h -o user $$

30 :名無しさん@お腹いっぱい。:2006/09/09(土) 09:42:37
>29
それ処理系依存。Solarisじゃだめだった。

31 :名無しさん@お腹いっぱい。:2006/09/09(土) 10:56:05
じゃあこれどう?

getent passwd `id -u` | (IFS=: read user other; echo $user)


まあ、id -unが使えれば一発なんだが、Solarisだと使えないし。

32 :名無しさん@お腹いっぱい。:2006/09/09(土) 11:02:18
>>31
Solarisは id -u も使えないよ。結局 >>28 か?

33 :名無しさん@お腹いっぱい。:2006/09/09(土) 11:10:32
そこまでわかってればこれだ↓

id | (IFS='()' read f1 f2 f3; echo $f2)

34 :名無しさん@お腹いっぱい。:2006/09/09(土) 11:24:30
>>32
/usr/xpg4/bin/id -u

35 :名無しさん@お腹いっぱい。:2006/09/09(土) 11:53:15
>>34
絶対PATHを決めうちすると今度はSolaris以外で動かない。
psもポータブルじゃないし、
最もポータブルなのは >>33 か?

36 :名無しさん@お腹いっぱい。:2006/09/09(土) 12:08:21
ポータブルという意味では>>28のほうがいいかな

37 :名無しさん@お腹いっぱい。:2006/09/09(土) 12:26:59
>>36
だから、ps -o user というオプションが使えない psもあるんだって。
あと、Linuxの一部では tail -1 も使えない。tail -n 1 にしないと。

よって、>>33 が最もポータブル。

38 :名無しさん@お腹いっぱい。:2006/09/09(土) 12:41:11
>あと、Linuxの一部では tail -1 も使えない。tail -n 1 にしないと。

マジかよ……。
たしかに引数の指定のしかたは現代的ではないけど、
過去に作られたスクリプトとの互換性とか移植性とかってのは考えないんだろうか。


39 :名無しさん@お腹いっぱい。:2006/09/09(土) 12:58:55
一部ってのが何を指すのかわからん
イヌックスのその辺りのコマンドは全部GNUじゃないの?

40 :名無しさん@お腹いっぱい。:2006/09/09(土) 13:02:43
GNU coreutilsの一部のバージョンで、tail -1形式のオプションが削除されたらしい。

41 :名無しさん@お腹いっぱい。:2006/09/09(土) 13:11:10
Solarisで動けばそれでいい。

42 :名無しさん@お腹いっぱい。:2006/09/09(土) 14:37:42
>>40
あまりに不評で戻らなかったっけ?
一部のディストリビューションで独自にやってるのかな。

43 :名無しさん@お腹いっぱい。:2006/09/09(土) 21:23:28
readlinkコマンドってSolarisには無いよね?
シンボリックリンクの内容をポータブルに読むにはどうすればいい?

44 :名無しさん@お腹いっぱい。:2006/09/10(日) 20:03:31
不可能。OOoだかmozillaだかで
ls -l "$file" | sed 's/.*-> //'
というような処理をしているのを見たことがあるけど、
当然lsの実装に依存するしファイル名が->を含んでいたら終わり。
どうしても必要ならperlを呼ぶのが一番まし。

45 :名無しさん@お腹いっぱい。:2006/09/11(月) 18:26:46
埋めは荒らしの一種だage荒らし!

46 :名無しさん@お腹いっぱい。:2006/09/11(月) 20:20:29
/var が容量80%超えたら警告メール送るようなシェルスクリプトきぼん。
もうかれこれ10回くらいこれでサーバーダウンしてます(T_T)

47 :名無しさん@お腹いっぱい。:2006/09/11(月) 20:39:32
>>46
dfもフォーマットがあんまりポータブルじゃないのでアレだが、
これでどうだ?


while :
do
for i in `df -k /var`; do
case $i in
[89][0-9]%|100%) df -k /var | mail omae@example.jp;;
esac
done
sleep 60
done

でも、メール送っても根本的な解決にならないよ。

48 :名無しさん@お腹いっぱい。:2006/09/11(月) 22:21:43
1分置きにメールが送るのかよ!!
そしてこれが /var を圧迫し、結局サーバが落ちるのだった。続く

49 :名無しさん@お腹いっぱい。:2006/09/11(月) 22:45:43
>>47
100%オーバーも考えたほうがいいと思う。

50 :名無しさん@お腹いっぱい。:2006/09/11(月) 23:18:51
snmpトラップでなんとか

51 :名無しさん@お腹いっぱい。:2006/09/13(水) 15:24:45
テンプレにある
xargs の -O とか find の -printOってオプションは
どういう動き?何のマニュアルなら載ってる?

AIXにものってないよ。
AIXとかソラリスにもないのに載せる必要
あるのか?




52 :名無しさん@お腹いっぱい。:2006/09/13(水) 15:26:51
O は知らんけど 0 なら GNU のにあるよ。

53 :名無しさん@お腹いっぱい。:2006/09/13(水) 15:30:12
>>51
じゃあ逆に聞くけど、(Sambaサーバとかで)「Program Files」みたいな
スペース入りのディレクトリorファイル名がバリバリに使われてる環境で、
正しく find | xargs するにはAIXではどうやってるの?

それとも問題に気づいてない?

54 :名無しさん@お腹いっぱい。:2006/09/13(水) 17:42:03
>>51
ttp://www.linux.or.jp/JM/html/GNU_findutils/man1/xargs.1.html


55 :名無しさん@お腹いっぱい。:2006/09/14(木) 00:02:07
>>51
Solarisのxargs(1)

入力データは行の集まりとして解析されます。引数は空白文字により 区切ら
れます。xargs を使って find dir -print や ls などのコマンドの出力を、
実行対象コマンドの入力とする場合、ファイル名に空白文字や復帰改行文字が
含まれていると、処理の結果は予測できません。これを防ぐには、見つかった
各ファイル名を引用符つきの文字列に変換するスクリプトを find を使って呼
び出し、そのスクリプトを xargs にパイプでつなげるようにしてください。
なお xargs が使う引用符の規則は、シェルの規則とは異なります。同じ規則
を採用しないのは、既存のアプリケーションが現状の規則に依存しているのに
対し、シェルの構文規則はそれと互換性を持たないためです。文字列を xargs
が正しく解釈できる形式に変換 する簡単な方法は、各文字の前にバックスラッ
シュ(\fR) を付加することです。

56 :名無しさん@お腹いっぱい。:2006/09/14(木) 00:08:25
>>51
SUSv3のxargs(1)

Note that input is parsed as lines; <blank>s separate arguments. If
xargs is used to bundle output of commands like find dir -print or ls
into commands to be executed, unexpected results are likely if any
filenames contain any <blank>s or <newline>s. This can be fixed by
using find to call a script that converts each file found into a
quoted string that is then piped to xargs.

57 :名無しさん@お腹いっぱい。:2006/09/14(木) 00:26:42
質問させてください。LinuxでBASHです。(長文失礼します)

ファイル名:file_a
データ:
1,abc,b,c
2,def,e,f
3,ghi,h,i

これを先頭の数字次第で別ファイルに吐き出したいのですが、
#!/bin/sh

for REC in `cat file_a`
do
echo "$REC" >> record.dat
NUM=`cat record.dat | cut -d "," -f1`
case $NUM in
  1) cut -f1- record.dat >> text1.txt ;;
 2) cut -f1- record.dat >> test2.txt ;;
 *) echo "error";;
esac
     rm record.dat
done
--
forでfile_aを一行ずつ読んで、一時的にrecord.datに格納し、先頭の文字でcaseで振り分けるというやり方をして動かしています。
これで上記のデータであれば動くのですが、
データ:
1,a bc,b,c
2,def,e ,f
3,ghi,h,i
という風に半角スペースが入るとそこで改行と認識されるようで、一行単位で認識をしません。

何か良い方法はないかアドバイスをいただけないでしょうか。よろしくお願いします。

58 :名無しさん@お腹いっぱい。:2006/09/14(木) 00:59:14
>半角スペースが入るとそこで改行と認識されるようで、一行単位で認識をしません。

for に与える引数リストが改行区切りだなんてどこに書いてあった?
行単位で認識されると思ってるのがまず勘違い。

改行区切りで欲しければ read を使う。

while read a; do
case "$a" in
1,*) echo "$a" >> text1.txt;;
2,*) echo "$a" >> text2.txt;;
*) echo error;;
esac
done < file_a

sed -n -e '/^1,/w text1.txt' -e '/^2,/w text2.txt' file_a


59 :57:2006/09/14(木) 01:43:28
>>58さん

>for に与える引数リストが改行区切りだなんてどこに書いてあった?
>行単位で認識されると思ってるのがまず勘違い。
>改行区切りで欲しければ read を使う。

知りませんでした。
ありがとうございます、試させていただきます。

60 :名無しさん@お腹いっぱい。:2006/09/14(木) 01:55:34
>>57
区切り文字はIFSで設定する。
↓IFSを改行に設定

#!/bin/sh

IFS="
"

for rec in `cat file_a
echo $rec
done


61 :名無しさん@お腹いっぱい。:2006/09/15(金) 07:36:45
ファイル中に複数存在している特定の区切文字列で囲まれたブロックを、区切
文字列をも含んだ形で、それぞれ個別のファイルとして書き出したいと考えて
います。ファイル名は重複さえしなければどのような名称でも構いません。

なお、 bash 上で、

$ awk '/^開始/,/^終了/{print}' ~/tmp/data.txt > ~/tmp/data2.txt

のようにすることで、 data.txt 中に含まれる

開始
あああああああああああああああああああああああああ
あああああああああああああああああああああああああ
あああああああああああああああああああああああああ
終了

のブロックが、全て data2.txt に出力できることはわかりました。

しかし、これでは単一のファイルとなってしまい、目的とは異なります。

このような形で切り出したブロックを単一のファイルとしてではなく、それぞ
れ個別のファイルとして出力させるには、条件処理を追加する必要があること
はわかるのですが、どのように記述すればよいのかでつまずいています。


62 :名無しさん@お腹いっぱい。:2006/09/15(金) 08:02:35
作ろうとしているファイルの命名則がわからないと、
もしくはそれを決めないと、何とも言えん。

63 :名無しさん@お腹いっぱい。:2006/09/15(金) 08:30:21
>>61
awk使っていいなら簡単じゃん。

awk '
/^開始1/,/^終了1/{ print > "data1.txt" }
/^開始2/,/^終了2/{ print > "data2.txt" }
/^開始3/,/^終了3/{ print > "data3.txt" }
' data.txt

64 :名無しさん@お腹いっぱい。:2006/09/15(金) 09:14:54
>>62
ファイルの名称は重複さえしなければ、どんな名称でも構いません。
見つかった順に 0001.txt, 0002.txt,...のような形でも構いませんし、ラン
ダムに生成した名称でも構いません。

>>63
あっ ごめんなさい。
ファイル中に複数存在するブロックというのが、数百のオーダーで存在してい
ます。
また、区切り文字列は全て同じもの(今回の例では「開始」〜「終了」)です。


65 :名無しさん@お腹いっぱい。:2006/09/15(金) 09:39:15
情報小出し、仕様あとづけキタ。俺はパス。awkスレ行け。
シェルスクリプトと直接関係ないし。

66 :名無しさん@お腹いっぱい。:2006/09/15(金) 09:46:50
>>64
簡単じゃん。


awk '
BEGIN { n=0 }
/^開始/{ n++ }
/^開始/,/^終了/{ print > n ".txt" }
' data.txt

67 :名無しさん@お腹いっぱい。:2006/09/15(金) 10:15:44
>>65
情報を小出しにするつもりはなかったのですが、結果
としてそうなってしまいました。
書き込む前にもうちょっと冷静に読み返すべきでした。
ごめんなさい。

>>66
ありがとうございます。
ご教示頂いた方法で希望通りの処理を実現できました。


68 :名無しさん@お腹いっぱい。:2006/09/15(金) 10:39:57
終了マーカーがいるみたいだから厳密には目的と違うかもしれないけど、
csplitも使えるかな。

69 :名無しさん@お腹いっぱい。:2006/09/15(金) 15:26:51
>53 なるほどブランク入り等のファイルね。
find は大丈夫そうだけど
[root@cis_svr_p]# find . -name *bb* -exec ls -l {} \;
-rw-r--r-- 1 root system 0 Sep 15 15:16 ./xx/aa bb
-rw-r--r-- 1 root system 0 Sep 15 15:17 ./xx/aa bb dd
-rw-r--r-- 1 root system 0 Sep 15 15:17 ./xx/ aa bb dd

xargs はないと困りそうだね。

15年以上UNIXシステムに携わってるけどブランク入りファイルが
メンテナンスの対象になるシステムは見たことないや。
学校系に多いのかな。



70 :名無しさん@お腹いっぱい。:2006/09/15(金) 15:30:15
>>69
だから Sambaサーバーって言ってるだろ。
スペース入りのファイルなんて日常茶飯事的にユーザーが作るよ。

71 :名無しさん@お腹いっぱい。:2006/09/15(金) 15:47:00
Samba なんて使わんしなぁ。
Windows でかためた方が楽じゃん。

72 :名無しさん@お腹いっぱい。:2006/09/15(金) 15:59:32
最近だと、KDE/GNOMEを使ってるユーザー(シェル不使用)だと、
UNIXユーザーでも普通にスペース入りのファイル名作るよ。

73 :名無しさん@お腹いっぱい。:2006/09/15(金) 17:36:43
Windows serverライセンス料高い。

74 :名無しさん@お腹いっぱい。:2006/09/15(金) 20:02:00
>70

ちなみにユーザーが作ったファイルを
find やら xargs で何するの?


75 :名無しさん@お腹いっぱい。:2006/09/15(金) 20:05:31
学校とかなら、setuidされたshがホームに転がってたりしないかくらいは
チェックするんじゃないか。

76 :名無しさん@お腹いっぱい。:2006/09/15(金) 20:26:06
そういうディレクトリはnosuidだRO

77 :名無しさん@お腹いっぱい。:2006/09/15(金) 21:31:28
それだとsetuidというものを教えられないじゃん。

78 :名無しさん@お腹いっぱい。:2006/09/15(金) 21:44:38
tmpの掃除とか。

79 :名無しさん@お腹いっぱい。:2006/09/16(土) 00:05:52
教えるときはその時だけ、専用のディレクトリ使えばよい。

80 :名無しさん@お腹いっぱい。:2006/09/16(土) 08:23:03
いずれにしても、スペースが入ると誤動作する xargsの仕様を正当化する理由にはなってない。
find ... -print0 | xargs -0 が使えない環境では、xargsを使わず、
find ... -exec ... で個別に -exec するのが正しい。(プロセスが無駄でも)

81 :名無しさん@お腹いっぱい。:2006/09/16(土) 17:59:11
>>80
-print0がつかえず、かつファイル数が多すぎるときは?

82 :名無しさん@お腹いっぱい。:2006/09/16(土) 18:00:30
>>81
GNU findutilsを入れる。

83 :名無しさん@お腹いっぱい。:2006/09/26(火) 21:09:46
test

84 :名無しさん@お腹いっぱい。:2006/09/26(火) 21:51:53
って、コマンドだったんですね。目から鱗です。

85 :名無しさん@お腹いっぱい。:2006/10/04(水) 16:47:35
UNIXTIMEをテキストファイルに500行ほど書き込んであるのですが、
それをシェルで一括で変換したいんです。

echo ########## | awk '{print strftime("%c",$1)}' >tempuni.txt

みたいな感じで
どのようにやればいいでしょうか?

お願いします

86 :名無しさん@お腹いっぱい。:2006/10/04(水) 16:53:54
>>85
イマイチ仕様が不明確だが、

$ echo 1157601611 | date -d "1970-01-01 `cat` seconds"
Thu Sep 7 04:00:11 JST 2006

↑みたいにできればいいのかな?
タイムゾーンは別途考慮のこと。

では、後出しの仕様どうぞ


87 :名無しさん@お腹いっぱい。:2006/10/04(水) 16:56:15
シェルってゆうなクズ。

88 :名無しさん@お腹いっぱい。:2006/10/04(水) 16:59:21
「シェルで一括変換」ならOKっしょ。

89 :名無しさん@お腹いっぱい。:2006/10/04(水) 17:00:15
何かのパズルか宿題じゃなければシェルでやらない方がいい問題だな。


90 :名無しさん@お腹いっぱい。:2006/10/04(水) 17:01:41
>>86
そんな感じです。
それをファイルの中のUNIXTIMEを1行目から500行目まで一括で変換したい。

1157601611
1157601612
1157601613
1157601614
 ・
 ・
 ・
みたいにならんでます

>>87
すいません。コマンドでした。
でもシェルでも出来ると思って・・・。

91 :名無しさん@お腹いっぱい。:2006/10/04(水) 17:05:17
>>90
じゃあ、hoge.txt に
1157601611
1157601612
1157601613
1157601614

が書かれてるとして、
以下を実行


for t in `cat hoge.txt`
do
date -d "1970-01-01 09:00 $t seconds"
done

92 :名無しさん@お腹いっぱい。:2006/10/04(水) 17:12:32
>>91
ありがとう御座います。

temp.txtに書き出しながら処理するにはどうしたら良いですか?

93 :名無しさん@お腹いっぱい。:2006/10/04(水) 17:15:11
>>92
done の行を
done > temp.txt
にすればいいだろ。ただのリダイレクトだよ。

94 :名無しさん@お腹いっぱい。:2006/10/04(水) 17:17:41
というか、質問者の >>85 自体がすでに答えになってるのに、
何を質問したいのか意味不明。

>>85 のやりかたでやるなら、

awk '{print strftime("%c",$1)}' > tempuni.txt < hoge.txt

で桶。
もしかして、単に入力ファイルのリダイレクト方法を知らなかっただけ?

95 :名無しさん@お腹いっぱい。:2006/10/04(水) 18:40:49
質問です( ・ω・)∩

CSVファイルの特定のフィールドの日付を書き換えなきゃなりません。

たとえば三番目のフィールドを199912から200001のように全行書き換える
にはどうしたらいいのでしょうか。

日付計算は終わってます。${B_YEAR}${B_MONTH} →${A_YEAR}${A_MONTH}
に入れ替えたいのですがsed使ってもなかなかうまくいきません。

awkで特定のフィールドを表示する方法ならわかるのですが、特定のフィールド
を置き換えた上で他のフィールドをそのまま表示する方法がわかりません。


96 :名無しさん@お腹いっぱい。:2006/10/04(水) 18:54:49
CSVはどういう書式のCSVかによって難易度がまるで違うので
厳密な仕様をください。""中の"や,の扱いとか。

97 :名無しさん@お腹いっぱい。:2006/10/04(水) 19:59:49
>>91
date -f hoge.txtは使えないのかなあ

98 :名無しさん@お腹いっぱい。:2006/10/04(水) 20:07:02
>>97
date -f は、UNIX時間の形式(ただの数字)には対応してない。
(やってみればわかるが)
なので、>>91 で正解。

99 :名無しさん@お腹いっぱい。:2006/10/04(水) 20:27:02
>>98
cat hoge.txt |sed -e "s/.*/1970-01-01 & second/;" |date -f -
で出来た

100 :名無しさん@お腹いっぱい。:2006/10/04(水) 20:37:30
>>99
お約束の突っ込み。「catが無駄です」

101 :名無しさん@お腹いっぱい。:2006/10/04(水) 20:38:07
CVSファイルには日付とか入っています
""はないです。

YYYYMM,HOGE,0,YYYYMM,YYYYMM,------中略-------,YYYYYMM,0,0,0,0
のような感じで日付が何箇所あります。現時点では各日付の関係
がわかりません。 m(_ _)m

102 :名無しさん@お腹いっぱい。:2006/10/04(水) 20:39:40
>>99
いや、わざわざ sed 通すくらいなら >>94 でいいだろ。1プロセスで済むし。

103 :名無しさん@お腹いっぱい。:2006/10/04(水) 20:48:16
>>102
manにdate起動のオーバーヘッド云々って書いてある。

104 :名無しさん@お腹いっぱい。:2006/10/04(水) 20:51:48
>>103
欲嫁。>>94 って言ってるんだよ。dateなんて1度も起動しないよ。

105 :名無しさん@お腹いっぱい。:2006/10/04(水) 22:15:56
awkはbash以上に使えるなw

106 :名無しさん@お腹いっぱい。:2006/10/05(木) 01:02:04
WINDOWS上でシェルスクリプトを作成して、UNIXサーバー上で実行させたいのですが、
WINDOWS上でシェルスクリプト動作確認をする方法はありますか?


107 :名無しさん@お腹いっぱい。:2006/10/05(木) 01:13:36
>>106
cygwin

108 :名無しさん@お腹いっぱい。:2006/10/05(木) 01:28:44
bashからawk使えばいいじゃん

バカくせぇ

109 :名無しさん@お腹いっぱい。:2006/10/05(木) 13:16:35
>>101
cutやpasteコマンドを使うところなのかもしれないし、
シェルスクリプトとは言い難いが
perl -apF, -e '$, = ","; $/ = "\n"; splice(@F, $n, 1, $F[$n]を加工); print @F' < csvファイル
で出来ない?

110 :名無しさん@お腹いっぱい。:2006/10/05(木) 13:17:05
-apF,のとこ、pじゃないやnだ。

111 :名無しさん@お腹いっぱい。:2006/10/05(木) 23:37:13
>>95
GNU sed を使うという手もある。

例)
$ echo 'abcdef' | sed 's/a\(b\)c\(de\)f/x\1y\2z/'
xbydez


112 :名無しさん@お腹いっぱい。:2006/10/07(土) 03:06:18
>>109 >>111 ありがとぅございますっっヽ(●´∀`)人(´∀`●)ノ
Solaris環境で自分で勝手にはgnu sed使えないのですが
perlは入っているので試してみます。∩(´∀`)∩ワァイ♪

113 :名無しさん@お腹いっぱい。:2006/10/07(土) 10:54:57
シェル内の変数が0の時の挙動についておしえてください。

Windowsで使う下記のような内容のバッチファイルを作るために、
Solaris8上で簡単なスクリプトを作成しますた。


<バッチファイルの中身 (期待している実行結果)>
lha32 a D:\save\0.lzh D:\work\0\
lha32 a D:\save\1.lzh D:\work\1\
lha32 a D:\save\2.lzh D:\work\2\
 :
lha32 a D:\save\9999.lzh D:\work\9999\ (←9999部分は、実際は第1引数で指定)


<作ったスクリプト>
#!/bin/sh
COUNT=0
LAST=$1
while [ $COUNT -le $LAST ]
do
  echo "lha32 a D:\\save\\$COUNT.lzh D:\\work\\$COUNT\\"
  COUNT=`expr $COUNT + 1`
done

114 :続き:2006/10/07(土) 10:55:42
ところがこのスクリプトを実行すると、最初に実行されるCOUNT変数が0のときに
0の値が消えてしまう現象が出てしまいまつ。(´・ω・`)

<shの実行結果>
lha32 a D:\save.lzh D:\work    ←0が消えている
lha32 a D:\save\1.lzh D:\work\1\
lha32 a D:\save\2.lzh D:\work\2\
 :

試しにシェルの種類を変えてみたところ、ksh, zsh は sh と同じ挙動を示し、
bashのみ期待していた出力となりますた。

<bashの実行結果>
lha32 a D:\save\0.lzh D:\work\0\
lha32 a D:\save\1.lzh D:\work\1\
lha32 a D:\save\2.lzh D:\work\2\
 :


この現象について、
 ・何故、0が消えるのか?
 ・/bin/shを使った場合に0を表示させる方法

について教えてください。
おまいら、よろしくおながいします。

115 :名無しさん@お腹いっぱい。:2006/10/07(土) 11:39:34
man echo


116 :名無しさん@お腹いっぱい。:2006/10/07(土) 11:50:42
>>113
それは、echoコマンドの仕様が違うため。
Solarisなどの /bin/sh の echo は、bashの echo -e に相当する。

echo -e 相当だと、\ が、シェルと echoで2回解釈されるので、
単純な \ を出力させたければ、\\\\ と書かないと行けない。

よって↓で桶。

echo "lha32 a D:\\\\save\\\\$COUNT.lzh D:\\\\work\\\\$COUNT\\\\"

117 :113:2006/10/07(土) 12:08:24
>>116
回答ありがとうございますた。
\がシェルと echoで2回解釈されるとは知りませんですた…。

118 :名無しさん@お腹いっぱい。:2006/10/07(土) 12:10:55
\0になりうる場所のみ二重化すればよいから、

echo "lha32 a D:\\save\\\\$COUNT.lzh D:\\work\\\\$COUNT\\"

でもいいな。


119 :名無しさん@お腹いっぱい。:2006/10/07(土) 12:42:08
>>118
ashとかだと、\1 でも 8進数の1と解釈するから、それはお勧めできない。
すべて \\\\ にするのが吉。

120 :名無しさん@お腹いっぱい。:2006/10/07(土) 13:00:20
エスケープだらけでややこしいな。
echo時は無難な/にでもしといて |sed とかしてまとめてエスケープつけると
見やすいかも。好きずきだが。

121 :名無しさん@お腹いっぱい。:2006/10/07(土) 13:02:25
ash(´゚c_,゚` )プッ
んな中途半端なもん使うなや

それに\1になりうるのは\\$COUNTのところだけだろ。


122 :名無しさん@お腹いっぱい。:2006/10/07(土) 13:22:46
D:\\save じゃなくて、
D:\\tave とかだったら困るだろ。
\\\\ にしとけ。

123 :名無しさん@お腹いっぱい。:2006/10/07(土) 13:24:36
UNIXのコマンドは\をエスケープキャラクタとして使用するものが多い。
ディレクトリ区切りは/としておいて、最後に一括変換すればよい。

#!/bin/sh
COUNT=0
LAST=$1
while [ $COUNT -le $LAST ]
do
  echo "lha32 a D:/save/$COUNT.lzh D:/work/$COUNT/"
  COUNT=`expr $COUNT + 1`
done | tr '/' '\\'

124 :名無しさん@お腹いっぱい。:2006/10/07(土) 13:38:18
\(´゚c_,゚` )プッ
んな中途半端なもん使うなや

125 :名無しさん@お腹いっぱい。:2006/10/07(土) 19:02:19
適当に'〜'を混ぜて、\の部分をシェルには解釈させないようにすればいい。
というかむしろ変数展開部分だけ"〜"使え。ややこしいときは。

echo lha32 a 'd:\\save\\'"$COUNT.lzh" 'd:\\work\\'"$COUNT"'\\'

126 :名無しさん@お腹いっぱい。:2006/10/07(土) 20:28:15
echo に関してだけはbashがGJだとおもうな。
printf があるのに、エスケープシーケンスを解釈してしまうようなままにしとくのがいけない。
バッドノウハウの典型だな。


127 :名無しさん@お腹いっぱい。:2006/10/07(土) 20:32:36
やっぱ bash使えば直るよねぇ

128 :名無しさん@お腹いっぱい。:2006/10/07(土) 22:39:17
echoがエスケープシーケンス解釈しないのはBSD由来なわけだが。
んで、echoがエスケープシーケンスをデフォルトで解釈するビルドもできちゃう
どっちつかずなbashがGJなのかよw

129 :名無しさん@お腹いっぱい。:2006/10/08(日) 00:09:40
デフォルトは有効でもいいが、オプションで無効にできたりするといいがな。


130 :名無しさん@お腹いっぱい。:2006/10/08(日) 01:13:22
大多数のshができないものは基本無効、オプションで有効だろ?

131 :名無しさん@お腹いっぱい。:2006/10/08(日) 06:43:25
ちゃうだろ。
Solarisなどのecho(/bin/echoも含む)が、エスケープシーケンスを無効にする方法がないことをいってるんジャマイカン?


132 :95-101:2006/10/10(火) 14:04:36
m(_ _)m アリガトォ〜 ゴザイマス★

/usr/bin/sed /usr/ucb/sed /usr/xpg4/bin/sed でも動作しました。


133 :名無しさん@お腹いっぱい。:2006/10/16(月) 01:05:51
sambaで共有している関係で「スペース」の入ったdirがある状況で、
特定拡張子のファイルを一括処理しょうと思い、

for file in `find . -name "*.hoge"`
do

のようにやると、スペースごとに変数fileに入ってしまうのだが
簡単な回避方法ありますか?




134 :名無しさん@お腹いっぱい。:2006/10/16(月) 01:25:32
find . -name "*.hoge" | while read line;do echo "@ $line @";done

135 :名無しさん@お腹いっぱい。:2006/10/16(月) 01:40:44
>> 134

ありがと。勉強になりました。
while 使えば行処理できたのか〜。



136 :名無しさん@お腹いっぱい。:2006/10/16(月) 03:24:33
与える先がxargsなら
find ... -print0 | xargs -0
もあり。

137 :名無しさん@お腹いっぱい。:2006/10/17(火) 17:36:58
変数 $1111 には

aaa
bbb
ccc
ddd
eee
fff

といった文字列(6行)が入っている。


変数$2222には

bbb
ccc

といった文字列(2行)が入っている。
$2222の中身を、「1行ずつ」grepキーワードとして、


cat $1111 | grep bbb
cat $1111 | grep ccc

と個別にcatを実行したい。
どうしればいいだろう。

138 :名無しさん@お腹いっぱい。:2006/10/17(火) 17:41:22
宿題は自分で。

139 :名無しさん@お腹いっぱい。:2006/10/17(火) 17:47:04
>>137
$2222 って、2,222個目の引数のことだぞ。普通のシェル変数じゃない。
で、勝手に $hoge1 $hoge2 と置き換えさせてもらうが、答えは echoを使うこと。

echo "$hoge1" | grep bbb
echo "$hoge2" | grep ccc

ダブルクォート " " で囲むのが重要。

140 :名無しさん@お腹いっぱい。:2006/10/17(火) 17:47:43
変数$2222の値を見ながら手でコマンドを入力する。


141 :名無しさん@お腹いっぱい。:2006/10/17(火) 17:49:36
すでに >>139 が正解を書いたあとにボケたつもりの >>140 が不憫。

142 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:21:59
いや139は正解じゃないだろ... $2222でループまわすことが求められていると思うのだが。


143 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:30:25
いや、問題自体が間違っている >>137 が悪いな。
後付けで問題訂正されるより、 >>137 がもう一度正確な問題を書くまで待機した方が良さそう。

144 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:33:44
もしかしてこういうことか?


for keyword in $hoge2
do
echo "$hoge1" | grep "$keyword"
done

$hoge2のところは " " なし(←これ重要)
$hoge1のところは " " あり(←これ重要)

145 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:38:15
echo じゃなくて cat でしょ?

146 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:39:32
>>145
だから、catだと勘違いしてる >>137 の問題が間違いだろ。

147 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:41:20
>>146
勘違いかどうかわかんないじゃん。
決めつけはよくないよ。

148 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:43:56
>>145
オマエアフォだな。もし catだと、
aaa
bbb
ccc
ddd
eee
fff

という改行付き6行もある変態的なファイル名のファイルを読み込むことになるんだよ。
echoの間違いだとエスパーしてあげたのは親切と言えよう。

149 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:45:20
だからぁ、>>137 がもう一度正確な問題を書くまで待機しろ、と言っただろ。

150 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:48:00
本当に catなら、「catが無駄です」の例になるな。
↓こういうことか?

for file in $hoge1
do
for key in $hoge2
do
grep "$key" < "$file"
done
done

151 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:50:42
>>148
変態的なファイル名の可能性もあるし、
複数のファイル名が変数に格納されてるのかもしれない。
勝手な解釈しちゃいかんよ。

152 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:54:55
いや、実際に bbb とか ccc とか、grepで一致する例が含まれてるし、
変数 $1111 改め $hoge1 の内容はファイル名じゃなく、文字列そのものだろ。

>>144 のエスパー(echo)が正しいに1票。

>>150 だと、「変数 $1111には1行ずつファイル名が入ってます」とかいう表現になるはず。

153 :名無しさん@お腹いっぱい。:2006/10/17(火) 18:58:04
>>152
その可能性もあるけど、あくまで可能性。
そこは本人に言わせなきゃだめだよ。

154 :名無しさん@お腹いっぱい。:2006/10/17(火) 19:02:18
ほんにんはにげだした・・・
0ポイントのけいけんちかくとく

155 :137:2006/10/17(火) 22:47:25
>>139
あ、そうだった。1111番目のひき数って意味ではなく、ご認識の通り。
catはファイル名対象が前提なんですね。
スクリプト内での処理ですので、echoのことです。訂正します。

>>144氏ので行けそうな気がする。ありがとうございます>各位

今回は"ファイル名"というものは存在しません。


156 :137:2006/10/17(火) 22:59:57
Cygwin動かないので明日会社で試す。
というか、変な質問してしまったことに今気がついた。
迷惑かけた。

今日8時間ぐらいずっとそれで悩んでたんだ。
googleで調べるとreadって命令を見つけたのでずっとそれと格闘してた。

157 :名無しさん@お腹いっぱい。:2006/10/18(水) 10:08:51
>$hoge2のところは " " なし(←これ重要)
>$hoge1のところは " " あり(←これ重要)

これなんで?
あっても無くても同じじゃないの?

158 :名無しさん@お腹いっぱい。:2006/10/18(水) 10:13:48
>>157
word splittingが行われるので違ってくるんだな。



159 :名無しさん@お腹いっぱい。:2006/10/18(水) 10:14:10
同じじゃないよ。

160 :名無しさん@お腹いっぱい。:2006/10/18(水) 10:14:37
for keyword in $hoge2
do
echo "$hoge1" | grep "$keyword"
echo TEST
done

別人だけど、これを実行しても

aaa
bbb
ccc
ddd
eee
fff
TEST

と表示されてしまうぞ。

bbb
TEST
ccc
TEST

とならなってくれないとおかしいのでは。

161 :157:2006/10/18(水) 10:17:06
つまり、

echo $hoge1

としたのでは、
下手すると

$hoge

という文字列そのものが表示されてしまう恐れがあるってことかな。

162 :名無しさん@お腹いっぱい。:2006/10/18(水) 10:36:34
単語の分割

シェルはパラメータ展開・コマンド置換・算術式展開 (ダブルクォートの内部ではこれらの展開は行われません) の結果をスキャンし、
単語分割 を行います。シェルは IFS のそれぞれの文字を区切り文字として扱い、他の展開の結果をこれらの文字によって単語に
分割します。 IFS が設定されていないか、その値が正確にデフォルト値の <スペース><タブ><改行> ならば、 IFS 文字の任意の列
で単語が区切られます。 IFS がデフォルト以外の値を持っていれば、空白文字 (スペース および タブ) の列は単語の先頭と末尾
では無視されます。これは空白文字が IFS の値 ( IFS 空白文字) に含まれる限り成り立ちます。 IFS に含まれ、 IFS 空白文字で
はない文字は全て、隣接する任意の IFS 空白文字と一緒になってフィールドの区切りとなります。 IFS 空白文字の列も区切り文字
として扱われます。 IFS の値が空文字列であれば、単語分割は全く行われません。


明示的に指定した空の引き数("" または '')は削除されずに残ります。クォートされていない暗黙的な空の引き数が、値を持たない
パラメータを展開した結果として得られますが、これらは削除されます。値を持たないパラメータがダブルクォート内部で展開される
と、これは空である引き数となり、消されずに残ります。

展開が行われなければ単語分割も行われない点に注意してください。

163 :名無しさん@お腹いっぱい。:2006/10/18(水) 10:42:40
echo ${hoge1}

これでもいいんだよね

164 :名無しさん@お腹いっぱい。:2006/10/18(水) 11:20:16
>>163
だめ。

echo ${hoge1} と echo $hoge1 は全く同じ。

echo "$hoge1" と同じなのは、echo "${hoge1}"

165 :名無しさん@お腹いっぱい。:2006/10/18(水) 11:24:00
>>160
zsh 使ってるんじゃない?

zsh だと、$hoge2 と書いても "$hoge2" と同じに解釈される糞仕様なので、、、
shかbashでやってみろ。

166 :名無しさん@お腹いっぱい。:2006/10/18(水) 11:41:14
>今日8時間ぐらいずっとそれで悩んでたんだ。

167 :名無しさん@お腹いっぱい。:2006/10/18(水) 11:44:17
>>166
どうしたの?

168 :名無しさん@お腹いっぱい。:2006/10/18(水) 13:51:26
質問です。

ファイルに ID,ファイル名,1,sed7s/(正規表現)正規表現/正規表現/',と並べてます

for LINE in ${LINE} ; do
IFS=','
FILE="$1"
SW="$2"
CMD="$3"

case $SW in
"0" )
コピーするだけ。;;
  "1" )
cat $FILE | $CMD" > hogehoge ;;
esac
done <ファイル
echo "$hoge1" | grep "$keyword"


done <FILE

どやってみたのですがうまくいきません。
設定ファイル上にかかれた正規表現や変数を含むコマンドを実行するには
どうしたらよいのでしょうか?

169 :名無しさん@お腹いっぱい。:2006/10/18(水) 13:52:49
下記二行は間違いです
>echo "$hoge1" | grep "$keyword"
>done <FILE


170 :名無しさん@お腹いっぱい。:2006/10/18(水) 14:30:50
syslog02# cat list.txt
EAST,01,blue,192.168.1.1,3:1
EAST,03,blue,192.168.1.1,3:2
EAST,05,green,192.168.1.2,3:3
EAST,03,green,192.168.1.2,3:8
EAST,05,red,192.168.1.3,3:12

syslog02# cat 2ch_sh
#!/usr/local/bin/bash
IFS=$'';SORT=(`cat $1 | sort -t, -k3`)
IFS=$'';UNIQ=(`cat $1 | sort -t, -k3 | awk -F , '{print $3 }' | uniq`)
for keyword in "$UNIQ"
do
echo "$SORT" | grep "$keyword"
echo test  (本当はここでファイルを作成したい)
done
------------

171 :名無しさん@お腹いっぱい。:2006/10/18(水) 14:33:46
【理想】
syslog02# ./2ch_sh list.txt
EAST,01,blue,192.168.1.1,3:1
EAST,03,blue,192.168.1.1,3:2
test
EAST,05,green,192.168.1.2,3:3
EAST,03,green,192.168.1.2,3:8
test
EAST,05,red,192.168.1.3,3:12
test
【現実】
syslog02# ./2ch_sh list.txt
EAST,01,blue,192.168.1.1,3:1
EAST,03,blue,192.168.1.1,3:2
EAST,05,green,192.168.1.2,3:3
EAST,03,green,192.168.1.2,3:8
EAST,05,red,192.168.1.3,3:12
test


172 :名無しさん@お腹いっぱい。:2006/10/18(水) 19:00:48
>>168
全然駄目。shの文法を読み直す。set -xで動作を追跡することを憶える。
その上で判らない場合に出直しなさい。

条件もダメダメだし。(sed7sってなんだよ。'が閉じてねーぞ)
> ファイルに ID,ファイル名,1,sed7s/(正規表現)正規表現/正規表現/',と並べてます

173 :名無しさん@お腹いっぱい。:2006/10/18(水) 20:25:31
cshの環境で、アプリケーションログを
/backup/apl -mtime +6 -exec rm {} \;
上記のようい週次バックアップしています。

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



174 :名無しさん@お腹いっぱい。:2006/10/18(水) 21:20:47
>>170
それでできるはず。ちゃんとbash使ってる?

175 :名無しさん@お腹いっぱい。:2006/10/18(水) 22:02:08
170のやり方だと

for keyword in "$UNIQ"

でそもそも複数行一括で処理するような気がする

176 :名無しさん@お腹いっぱい。:2006/10/18(水) 22:04:51
おまえら、もう一度 "$hoge" と $hoge の違いを復習汁。

177 :名無しさん@お腹いっぱい。:2006/10/19(木) 03:50:14
過去ログを参行にもう一度挑戦しました

file
--------------------------------------------------
hoge:0:
hoge:1:sed "s/a\\(b\\)c\\(de\\)f/x\\1y\\2z/":
hoge:1:sed 's/a\(b\)c\(de\)f/x\1y\2z/':
-------------------------------------------------

hoge
------------------------------------------------
abcdef
------------------------------------------------

#!/bin/sh

while read LINE ;do
IFS=':'
set -- ${LINE}
FILE=$1
SW=$2
CMD=$3
case $SW in
"0" )
echo HOGE ;;
"1" )
cat $FILE | $CMD >hogehogehoge;;
esac
done <file


178 :名無しさん@お腹いっぱい。:2006/10/19(木) 03:51:43
sh -x ./hogehoge
+ read LINE
+ IFS=:
+ set -- hoge 0
+ FILE=hoge
+ SW=0
+ CMD=
+ case $SW in
+ echo HOGE
HOGE
+ read LINE
+ IFS=:
+ set -- hoge 1 'sed "s/a\(b\)c\(de\)f/x\1y\2z/"' ' '
+ FILE=hoge
+ SW=1
+ CMD='sed "s/a\(b\)c\(de\)f/x\1y\2z/"'
+ case $SW in
+ cat hoge
+ 'sed "s/a\(b\)c\(de\)f/x\1y\2z/"'
./hogehoge: line 13: sed "s/a\(b\)c\(de\)f/x\1y\2z/": No such file or directory


179 :名無しさん@お腹いっぱい。:2006/10/19(木) 03:52:19
+ read LINE
+ IFS=:
+ set -- hoge 1 'sed '\''s/a(b)c(de)f/x1y2z/'\''' ' '
+ FILE=hoge
+ SW=1
+ CMD='sed '\''s/a(b)c(de)f/x1y2z/'\'''
+ case $SW in
+ cat hoge
+ 'sed '\''s/a(b)c(de)f/x1y2z/'\'''
./hogehoge: line 13: sed 's/a(b)c(de)f/x1y2z/': No such file or directory
+ read LINE
+ IFS=:
+ set --
+ FILE=
+ SW=
+ CMD=
+ case $SW in
+ read LINE

180 :名無しさん@お腹いっぱい。:2006/10/19(木) 03:53:51
このようなメッセージが出て先に進みません(T-T)
どう改善すればよいのでしょうか

./hogehoge: line 13: sed "s/a\(b\)c\(de\)f/x\1y\2z/": No such file or directory

181 :名無しさん@お腹いっぱい。:2006/10/19(木) 11:10:31
>>180
そのエラーメッセージの意味がわかるように中学からやり直す。

182 :名無しさん@お腹いっぱい。:2006/10/19(木) 11:22:15
./ほげほげ: 13番線: sed "s/a\(b\)c\(de\)f/x\1y\2z/": 番号、そのようなやすり、さもなければ登録簿。

訳してみましたが、意味がわかりません。

183 :名無しさん@お腹いっぱい。:2006/10/19(木) 12:18:27
ここがおかしいのはりかいできるのですが・・・

cat $FILE | $CMD >hogehogehoge;;

$CMDの部分に実行できるコマンドを代入するほうほうはないでしょうか?



184 :名無しさん@お腹いっぱい。:2006/10/19(木) 12:38:08
>>183
お約束の、catが無駄です。

185 :名無しさん@お腹いっぱい。:2006/10/19(木) 12:41:53
「sed "s/a\(b\)c\(de\)f/x\1y\2z/"」という名前のコマンドを実行しようとして
ないと言っているのがそのエラーメッセージ。

「sed」コマンドに引数「"s/a\(b\)c\(de\)f/x\1y\2z/"」を与えるのがやりたい
ことだろうがそうはなっていないわけだ。

で、どうしてそういうことになってるかは >>162 で引用されているシェルの
マニュアルの単語分割のところをよく読め。特にお前さんの場合はIFSを
いじっているのでそこらへんも効いている。



186 :名無しさん@お腹いっぱい。:2006/10/19(木) 14:15:13
>>183
eval はどうよ

187 :名無しさん@お腹いっぱい。:2006/10/19(木) 14:32:12
>>186
よくわからずに eval 使うより
>>185 あたりを理解するのが先だな。

188 :名無しさん@お腹いっぱい。:2006/10/19(木) 23:37:29
ShellScript
  
  ↓ 日本語訳

 貝???

189 :名無しさん@お腹いっぱい。:2006/10/20(金) 02:09:28
>>185 >>186 IFSをループの外にしてevalでSolaris環境では解決しました。

ありがとう。 Cygwinでは改行コードで怒られます。

#!/bin/sh

IFS=','
while read FILE SW CMD
do

case $SW in
"0" )
echo HOGE ;;
"1" )
cat $FILE | eval $CMD >hogehogehoge;;
esac
done <file

file
-------------------
hoge,0,
hoge,1,sed 's/a\\(b\\)c\\(de\\)f/x\\1y\\2z/',
-------------------

hoge
--------------------
abcdef
------------------
hogehogehoge
------------------
xbydez
-------------------

190 :名無しさん@お腹いっぱい。:2006/10/20(金) 02:12:15
>>184 catが無駄というのは$CMD $FILE >hogehogehoge
という事でしょうか。


191 :名無しさん@お腹いっぱい。:2006/10/20(金) 08:31:26
>>190
ちょっと違います。

192 :名無しさん@お腹いっぱい。:2006/10/20(金) 09:37:21
>>190
かなり違います。


193 :名無しさん@お腹いっぱい。:2006/10/20(金) 11:11:24
>>190
つ <

194 :名無しさん@お腹いっぱい。:2006/10/20(金) 15:21:56
$FILEにファイル名が複数入っている可能性があるのならそのcatもあながち
無駄ではないかもしれない。


195 :名無しさん@お腹いっぱい。:2006/10/20(金) 16:21:00
>>194
その可能性はあり得ない。
>>189
while read FILE SW CMD

って書いてるから。よってやはり「catが無駄です」

196 :名無しさん@お腹いっぱい。:2006/10/21(土) 18:07:53
catが無駄かどうかがこんなに盛り上がるとは。

197 :名無しさん@お腹いっぱい。:2006/10/21(土) 19:36:02
freebsd の sleep 議論ってやつやね

198 :名無しさん@お腹いっぱい。:2006/10/23(月) 04:40:19
シェルスクリプトって便利で好きだけど、限度があるからperlに逃げる。
シェルスクリプトならでは、という美しいサンプルはどの辺に行けば見れますか?

199 :名無しさん@お腹いっぱい。:2006/10/23(月) 06:36:28
/etc/init.d


200 :名無しさん@お腹いっぱい。:2006/10/23(月) 08:28:02
シェルスクリプトは美しさを求めるもんじゃないと思う。

201 :名無しさん@お腹いっぱい。:2006/10/23(月) 11:14:52
工エエェェ(´д`)ェェエエ工


202 :名無しさん@お腹いっぱい。:2006/10/23(月) 13:45:43
シェルスクリプトならではのねじれ曲がったサンプルなら./configure

203 :名無しさん@お腹いっぱい。:2006/10/23(月) 16:20:35
Linuxの~/.bashrcに

unalias vi

という行を追加しました。というのは、ディフォルトのviだと、文字が緑ではなく、いろんな色でカラフルに
表示されるので、unaliasしてみたら、緑一色で表示できたので。
これでviは快適に使えるようになったのですが、別の問題が起こりました。
それは、bashを起動して別のシェルを動かした場合に.bashrcがもう一度実行されるので、
既にviはunaliasされているにもかかわらず、再度unaliasしようとして以下の警告が表示されます。

bash: line 49: unalias: vi: not found

警告が出ても、処理は問題なくできるので、気にしなければ、いいのですが、
でも気になるので、何か良い解決方法を教えてください
よろしく。

204 :名無しさん@お腹いっぱい。:2006/10/23(月) 16:42:00
>>203
単に
alias vi=
の行を.bashrcから削除すりゃいいのでは、と思ったが、
/etc/のどこかで定義されてるのかねぇ。

alias | grep '^alias vi=' >/dev/null && unalias vi

205 :名無しさん@お腹いっぱい。:2006/10/23(月) 16:44:52
alias して unalias すればいーじゃん

206 :名無しさん@お腹いっぱい。:2006/10/23(月) 16:46:31
>>203
~/.bash_profile に書けば?

207 :名無しさん@お腹いっぱい。:2006/10/23(月) 16:48:11
ちっともシェルスクリプトじゃない。

208 :名無しさん@お腹いっぱい。:2006/10/23(月) 16:49:48
だな。
続きはこっちで。

くだらねえ質問はここに書き込め! Part 133
http://pc8.2ch.net/test/read.cgi/linux/1160894184/

209 :名無しさん@お腹いっぱい。:2006/10/23(月) 16:53:27
>>205
お前頭いいな


210 :名無しさん@お腹いっぱい。:2006/10/23(月) 18:12:39
>>205
それするくらいなら、
unalias vi 2> /dev/null
でいいじゃん。メッセージを捨てるだけ。

211 :名無しさん@お腹いっぱい。:2006/10/23(月) 18:44:40
>206
この方法で解決しました。
ありがとございます。

212 :名無しさん@お腹いっぱい。:2006/10/24(火) 10:14:07
遅レスだが
>>165
> zsh だと、$hoge2 と書いても "$hoge2" と同じに解釈される糞仕様なので、、、
setopt SH_WORD_SPLIT あるいは明示的に${=hoge2}とする。

213 :名無しさん@お腹いっぱい。:2006/10/25(水) 16:35:32
第一フィールドがmm/dd/yyyy
第二フィールドがhh:mm:ss
第三フィールドが""で囲まれたアカウント名

となっている。
「アカウント名が重複しているものは、その最新日付のみを残して、
他の重複行はすべて削除」
という具合にしたい。

uniqを使えばいいのかもわからないが、やっぱりわからない。
どうすればいいだろう。

08/11/2006 14:29:50 "yamamoto"
03/03/2006 06:40:53 "yamada"
05/17/2005 07:45:07 "yamada"
07/13/2005 04:18:04 "yamada"
07/13/2005 13:17:56 "yamada"
08/04/2005 11:03:05 "yamada"
08/11/2005 05:54:56 "yamada"
08/11/2004 07:58:53 "yamada"
12/07/2005 13:54:19 "yamada"
12/22/2005 00:26:49 "yamada"
08/05/2005 02:48:41 "kinosita"
08/05/2005 11:49:58 "kinosita"
08/05/2004 11:51:45 "kinosita"
08/06/2005 04:55:50 "kinosita"
02/21/2005 16:34:40 "akie"
02/21/2006 17:20:21 "akie"
02/21/2006 17:22:56 "akie"
02/21/2005 17:41:45 "akie"
02/21/2005 17:47:14 "akie"

214 :名無しさん@お腹いっぱい。:2006/10/25(水) 16:40:07
>>213
こんなんシェルスクリプトでやりたくないな。
perl かなんかで。

215 :名無しさん@お腹いっぱい。:2006/10/25(水) 16:43:13
連想配列使える言語(awk, perl, csh)を使わない理由は?

216 :名無しさん@お腹いっぱい。:2006/10/25(水) 16:54:59
>>213
シェルで簡単にできるよ。
ちょっとパイプが多段だけど。


while read dt tm user
do
echo $dt $tm `date +%s -d "$dt $tm"` $user
done | sort -nr | uniq -3 | while read dt tm sec user
do
echo $dt $tm $user
done


ポイントは、dateで単純な秒数に変換する前処理をしてから
フィールドスキップして uniq すること。
その後で秒数フィールドを削除して元に戻してる。

GNU dateが必要かも知れない。

perl とか 連想配列とか言ってる香具師は弱もの。

217 :名無しさん@お腹いっぱい。:2006/10/25(水) 16:59:54
弱ものってなんだろ。

218 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:04:25
どうもです。
perlなどでやったほうがお手軽なんですね。
覚えがあるのがshellだけなので、やむをえず・・・。

Cygwinじゃdate -dでエラーになるので、FreeBSDで試してみます。

219 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:08:53
>GNU dateが必要かも知れない。
こんな俗物に頼る方が、頭がヨワイ。


220 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:13:42
>>219
08/11/2006 14:29:50
を、
2006/08/11 14:29:50
に変換する前処理を入れれば、
date使わなくても >>216 の方法で行けるよ。

>>216 って短時間に良くこんなシェルスクリプト組めますね。
さてはかなりのプロと見た。

221 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:33:44
>>216
>done | sort -nr | uniq -3 | while read dt tm sec user

sort -k 3 -nrだろう

222 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:36:56
>>221
まちがえた

223 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:37:14
>>216
それだと名前の順序が変わるから
> その最新日付のみを残して、他の重複行はすべて削除
を満たさない。
それと、uniq ではスキップするフィールドを指定するんだから uniq -2 だし、
uniq が削除するのは連続した場合だから名前フィールドでの sort も必要。

224 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:38:32
>>223
いや、uniq -3 は合ってるよ。1フィールドを追加してるから。

225 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:41:18
>>224
あ、そうか。ゴメン。

226 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:44:00
date で追加するフィールドを頭に持ってきて、
sort -nr | uniq -3 で最新日付だけ残して
最後に頭のフィールドを削除するのが奇麗だな。

227 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:46:13
>>226
頭のフィールドはuserだろう

228 :名無しさん@お腹いっぱい。:2006/10/25(水) 17:54:12
>>227
確かに。時間毎にユーザーがバラバラな場合も考慮するとそうだな。

229 :名無しさん@お腹いっぱい。:2006/10/25(水) 18:24:51
cat -n | \
sed 's,^[[:space:]]*\([0-9][0-9]*\)[[:space:]]*\([0-9][0-9]*\)/\([0-9][0-9]*\)/\([0-9][0-9]*\)[[:space:]]*\([^[:space:]][^[:space:]]*\)[[:space:]]*\(.*\),\6 \4/\2/\3 \5 \1 \6,' | \
sort -r | uniq -4 | sort +3n | \
sed 's,^\([^[:space:]]*\)[[:space:]]*\([0-9][0-9]*\)/\([0-9][0-9]*\)/\([0-9][0-9]*\)[[:space:]]*\([^[:space:]][^[:space:]]*\).*,\4/\2/\3 \5 \1,'

230 :名無しさん@お腹いっぱい。:2006/10/25(水) 19:17:16
連想配列サポートしている言語の方が楽じゃないかね。www

231 :名無しさん@お腹いっぱい。:2006/10/25(水) 19:25:04
>>230
シェルスクリプトでの回答例が出ている後でそんなこと言っても,みっともないだけw

232 :名無しさん@お腹いっぱい。:2006/10/25(水) 19:28:24
まとめてみた。

while read dt tm user; do
echo $dt $tm $user `date +%s -d "$dt $tm"` $user
done |sort -k 3 -r |uniq -4 |cut -d" " -f 1-3

233 :名無しさん@お腹いっぱい。:2006/10/25(水) 19:38:07
>>232
date の -d オプションは標準ではない
入力ファイルの順序が保存されてない

234 :名無しさん@お腹いっぱい。:2006/10/25(水) 20:08:50
>>233
dateを使わない方法は >>220 が示している。
入力ファイルの順序は、もともとの質問では問うていない。

235 :名無しさん@お腹いっぱい。:2006/10/25(水) 20:30:23
>>234
> dateを使わない方法は >>220 が示している。
>>219-220 抜かしたらまとめにならんだろ。
> 入力ファイルの順序は、もともとの質問では問うていない。
元の質問は「他の重複行はすべて削除」ね。入力ファイルから重複行を削除した
ものは当然に入力ファイルの順序が保存されてる。
順序を変えていいのは順序は問わないと明記されてる場合だけ。

236 :名無しさん@お腹いっぱい。:2006/10/25(水) 20:44:28
いや、もともとの >>213 の質問の意図からすると、
各ユーザ毎に最新時刻の行だけを抜き出したら、
それらの行全体が時刻順にソートされていた方が都合がいいだろう。
そういう意味でも、たまたま入力された順序にユーザーが並ぶ必要は全くない。

237 :名無しさん@お腹いっぱい。:2006/10/25(水) 21:17:50
>>232
09/09/2001 00:00:00 "name"
09/10/2001 00:00:00 "name"

238 :名無しさん@お腹いっぱい。:2006/10/26(木) 00:59:01
sed で文字列を抽出して sh の変数に入れたいんですが、
抽出させたい文字列が二つあります。
一回の sed で二つの出力を二つの変数に入れるのにはどうしたらいいですか?
なんか read を使えばできそうな感じなのですが、
なかなか難しくてできていません。

239 :名無しさん@お腹いっぱい。:2006/10/26(木) 01:48:30
>>238
sed でどう出力するのか分からんけど
パイプを使って代入しても意味が無いから気をつけろ。

sed '処理' | read a b

とかやっても a や b の中身はパイプの中でしか
参照できない。


240 :名無しさん@お腹いっぱい。:2006/10/26(木) 01:53:16
set -- `sedでほしい2つだけを抜き出す`
とかかね?

241 :名無しさん@お腹いっぱい。:2006/10/26(木) 02:09:02
sedじゃないものを使ったほうが上手くいくと見た

242 :238:2006/10/26(木) 03:53:46
read を使って代入しても
サブプロセスの中の変数にしか影響を与えない場合が
あるとかなんとかで(>>239 さんの言ってることですね)、
exec 使ってリダイレクションをかえるとかそういうのに挑戦しましたが
生半可な知識ではたちうちできず、
結局別の方法で逃げました。
>>240 さんの方法は今回は使えませんでしたが勉強になりました。
いやー難しい。

243 :名無しさん@お腹いっぱい。:2006/10/26(木) 08:14:10
>>237
不思議だ

244 :名無しさん@お腹いっぱい。:2006/10/26(木) 09:40:15
>>232
改良してまとめた

while read dt tm user; do
printf "%s %015d %s\n" $user `date +%s -d "$dt $tm"` $user;
done |sort -nr |uniq -2 |while read user sec user1; do
echo `date "+%m/%d/%Y %T" -d "1970-01-01 00:00:00 UTC $sec sec"` $user;
done;

245 :名無しさん@お腹いっぱい。:2006/10/26(木) 10:32:49
>>244
2 回目の read はいらんだろ。変換前の値もつけとけばいい。

しかし、なんで標準外の date の -d オプションにこだわるんだ?
while read dt tm user; do
  tmp=${dt%/*}; x=${tmp#*/}
  echo $user ${dt##*/}/${dt%%/*}/$x $tm $dt $tm $user
done | sort -r | uniq -f 5 | cut -d ' ' -f 4-
入力順も保存したいなら
cat -n |
while read num dt tm user; do
  tmp=${dt%/*}; x=${tmp#*/}
  echo $user ${dt##*/}/${dt%%/*}/$x $tm $num $dt $tm $user
done | sort -r | uniq -f 6 | sort -nk 4 | cut -d ' ' -f 5-

246 :名無しさん@お腹いっぱい。:2006/10/27(金) 22:48:53
2 つのフィールドを持つ A, B ファイルを結合したいのですが、
一方にしか存在しないフィールドはそのまま出力し、
それ以外は第二フィールドを B に変更したいのです。

例えば次のようなファイルを:
foo 0
bar 0
--
foo 1
qux 1

次のように:
foo 1
bar 0
qux 1

順序は不同なのでソートしちゃっても構いません。
どのような方法があるでしょうか?

247 :名無しさん@お腹いっぱい。:2006/10/27(金) 23:33:05
cut -f1 -d ' '
uniq
uniq -d

を使って適当に。


248 :名無しさん@お腹いっぱい。:2006/10/28(土) 17:24:58
>>247 ありがとうございます。
join(1) あたりで出来るかと思ったんですが、いまいち上手くいかないorz
もう少し頑張ってみます。

249 :名無しさん@お腹いっぱい。:2006/10/28(土) 20:20:34
for aa in a b; do cat $aa |sed -e "s/ / $aa /;"; done |\
sed -e "s/\([^ ]*\).*/& \1/;" |sort -r |uniq -3 |cut -d" " -f 1,3

250 :名無しさん@お腹いっぱい。:2006/10/29(日) 08:35:39
あなたが書いた最大のシェルスクリプトの文字数は?

251 :名無しさん@お腹いっぱい。:2006/10/29(日) 09:16:24
http://life7.2ch.net/test/read.cgi/diet/1158326490
美容版の糞コテ「たお」は自慢大好き
その自慢もたいしたこと無いのに得意気で
見ててとても痛い糞コテ
批判に対しては必ず長レスで的外れに噛み付いてくる
とっても哀れなやつ
http://life7.2ch.net/test/read.cgi/diet/1158326490

252 :名無しさん@お腹いっぱい。:2006/10/30(月) 16:26:50
縦書き
mm=80; nn=3;

pp=`printf "%0${nn}d" 0`;
for ((aa=0; aa<$mm; aa++)); do
bb[$aa]=$pp$aa;
done;

for ((aa=-$nn; aa<0; aa++)); do
for ((aa1=0; aa1<$mm; aa1++)); do
echo -n ${bb[$aa1]:$aa:1};
done;
echo;
done;

253 :名無しさん@お腹いっぱい。:2006/10/30(月) 18:29:51
>>252
脈絡なく何を言いたいかわからんが、
zsh依存乙。

bashですら動かない依存スクリプトは、Bourne-sh互換に書き直して出直すこと。

254 :246:2006/10/30(月) 20:11:41
>>249
なるほど. そういう使い方もあるのですね.
これで上手くいきそうです. ありがとうございました.

255 :名無しさん@お腹いっぱい。:2006/10/31(火) 01:16:24
>>252
俺の環境ではこうなったが、これでいいのか?

00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000001111111111222222222233333333334444444444555555555566666666667777777777
01234567890123456789012345678901234567890123456789012345678901234567890123456789

$ bash --version
GNU bash, version 3.1.17(9)-release (i686-pc-cygwin)


256 :名無しさん@お腹いっぱい。:2006/11/01(水) 17:56:32
不定個のコマンドをパイプで繋げて処理する方法はないですか?

257 :名無しさん@お腹いっぱい。:2006/11/01(水) 18:10:02
>>256
文字列でパイプライン組み立ててevalしる

258 :名無しさん@お腹いっぱい。:2006/11/02(木) 09:32:24
evalを使えば何でも出来る。

259 :名無しさん@お腹いっぱい。:2006/11/05(日) 01:14:11
ディレクトリ名の引数から末尾の名前だけを取り出すにはどうすればいいでようか?
たとえば

% hoge /usr/local/bin
bin
% hoge ~/etc
etc
% pwd
/usr/local/bin
% hoge ..
local

みたいな。


260 :名無しさん@お腹いっぱい。:2006/11/05(日) 01:18:31
x=$(cd "$dir"; pwd); x=${x##*/}

261 :名無しさん@お腹いっぱい。:2006/11/05(日) 01:23:01
basenameは反則?

262 :名無しさん@お腹いっぱい。:2006/11/05(日) 01:37:00
退場


263 :名無しさん@お腹いっぱい。:2006/11/05(日) 13:35:39
hoge=/usr/local/bin/allneeded
% echo $hoge:r
/usr/local/bin/allneeded
% echo $hoge:t
allneeded

csh/tcsh/zsh だがね。sh だったら basename だろ?


264 :名無しさん@お腹いっぱい。:2006/11/05(日) 13:42:20
相対パスがやっかいだな。

265 :名無しさん@お腹いっぱい。:2006/11/05(日) 14:39:54
basenameはPOSIXにすらあるんだからどんどん使うべし。

266 :名無しさん@お腹いっぱい。:2006/11/05(日) 18:18:11
basename なんて使わなくても >>260 でいいじゃないか

267 :名無しさん@お腹いっぱい。:2006/11/05(日) 18:44:46
bshで使えないからダメ。

268 :名無しさん@お腹いっぱい。:2006/11/05(日) 18:49:29
POSIX sh で使えるから別にいいんじゃん

269 :名無しさん@お腹いっぱい。:2006/11/05(日) 22:37:29
これならBourne Shellで動く。


arg=/usr/local/bin
(IFS=/; set $arg; shift `expr $# - 1`; echo "$1")

270 :名無しさん@お腹いっぱい。:2006/11/06(月) 00:12:33
basenameは外部コマンドでも存在「しなければならない」。
たとえ意味がなくてもcdが外部コマンドとして存在「しなければならない」のと同じ。
だから、>>266-267,269の言ってることは意味がない。考えるだけ無駄。

271 :名無しさん@お腹いっぱい。:2006/11/06(月) 00:28:55
> たとえ意味がなくてもcdが外部コマンドとして存在「しなければならない」のと同じ。
どこの世界の話だ?

SUSv3:
> Since cd affects the current shell execution environment, it is always
> provided as a shell regular built-in.

272 :名無しさん@お腹いっぱい。:2006/11/06(月) 00:51:53
お前の挙げているSUSv3の世界だよwwww

1.13 Built-In Utilities
However, all of the standard utilities, including the regular
built-ins in the table (中略) shall be implemented in a manner so that
they can be accessed via the exec family of functions as defined in
the System Interfaces volume of IEEE Std 1003.1-2001 and can be
invoked directly by those standard utilities that require it (後略)

273 :名無しさん@お腹いっぱい。:2006/11/06(月) 01:36:29
どこにも「外部コマンドとして存在しなければならない」なんて書いてないが?
そこで要求されてるのは
they can be accessed via the exec family of functions
つまり execve 等から呼出せれば外部コマンドである必要なんてない。

274 :名無しさん@お腹いっぱい。:2006/11/06(月) 01:39:02
はいはい、そうでちゅよねーwwww

275 :名無しさん@お腹いっぱい。:2006/11/06(月) 01:49:28
"in a manner"というニュアンスなんで、なければならない
というほどでもないのでは?外野ですが。

276 :名無しさん@お腹いっぱい。:2006/11/06(月) 02:03:21
in a mannerはso that節につながるだけだよ。
むしろ"shall be"という強い書き方に注目しないといけない。

んで、exec系の関数の説明には
The exec family of functions shall replace the current process image
with a new process image. The new image shall be constructed from a
regular, executable file called the new process image file.
と書いてあるわけだ。ちゃんと規格書をあたる点は誉めてやってもいいが、
かなり調べ方が足りないゾwwww

277 :名無しさん@お腹いっぱい。:2006/11/06(月) 02:29:57
はいはい、そうでちゅよねーwwww

278 :名無しさん@お腹いっぱい。:2006/11/06(月) 02:34:32
cd の方に nohup cd なんて例があるくらいだから
cd が実行ファイルとして存在することを仮定してるんじゃないかな。

279 :名無しさん@お腹いっぱい。:2006/11/06(月) 02:45:36
うん、仮定っていうより、そう決まってるんだけどね。
ていうか、それはもう>>272ですんだ話。

280 :名無しさん@お腹いっぱい。:2006/11/06(月) 03:25:25
相対パスが多少面倒だな。


281 :名無しさん@お腹いっぱい。:2006/11/06(月) 06:42:17
マタマタごジョーダンを

282 :名無しさん@お腹いっぱい。:2006/11/06(月) 08:51:00
cdが外部コマンドになってると何がうれしいのか俺にもわかるように説明してくれないか。
POSIXで決まってるからというのはなしね。なぜそう決めたかの背景を知りたい。


283 :名無しさん@お腹いっぱい。:2006/11/06(月) 09:49:49
>>282
POSIXで誤ってそう決めてしまった、という説が有力。

後付けの言い訳としては、対象ディレクトリに実際に cdできるかどうかを
テストする目的で使える(返り値で結果判定)、と説明されているが、そんな例あまりないし、
内部コマンドの cdで、
(cd hoge) とやれば済む話。

284 :名無しさん@お腹いっぱい。:2006/11/06(月) 17:49:06
% cat /usr/bin/cd
#!/bin/sh
# $FreeBSD: src/usr.bin/alias/generic.sh,v 1.1 2002/07/16 22:16:03 wollman Exp $
# This file is in the public domain.
${0##*/} ${1+"$@"}


285 :名無しさん@お腹いっぱい。:2006/11/06(月) 18:31:56
>>284

${1+"$@"} って、 "$@" だけでよくねぇ?

286 :名無しさん@お腹いっぱい。:2006/11/06(月) 23:17:07
>>283
cdだけならそれでも説明はつくんだけど、外部コマンドとしても存在する
ビルトインコマンド(regular built-in utility)は、cdだけじゃないのがややこしいところ。

alias, bg, cd, command, false, fc, fg, getopts, jobs, kill, newgrp,
pwd, read, true, umask, unalias, wait

謎だよなあ… fcやcommandに至っては、何のために存在するのかすらわからない。

287 :名無しさん@お腹いっぱい。:2006/11/06(月) 23:33:12
シェル関数はbシェルにも存在するから、外部コマンドのcommandはそれなりに意味があるんじゃね?


288 :名無しさん@お腹いっぱい。:2006/11/06(月) 23:40:49
うう、わからない…
もうちょっとやさしくして

289 :名無しさん@お腹いっぱい。:2006/11/06(月) 23:42:48
意味のある外部コマンド:
(cronとか、inetdとかから直接起動されるとか、
env/nice/time/nohupとかの引数として起動するために外部である必要があるもの)

command, false, kill, newgrp, pwd, true


意味のない外部コマンド:
alias, bg, cd, fc, fg, getopts, jobs, read, umask, unalias, wait

290 :名無しさん@お腹いっぱい。:2006/11/06(月) 23:46:26
それより、教育上、「:」の外部コマンド版 (/bin/:)を
配置するべきだ。/bin/[ はあるのだから。

291 :名無しさん@お腹いっぱい。:2006/11/06(月) 23:48:12
>>290
教育上って、どういうこと?

292 :名無しさん@お腹いっぱい。:2006/11/06(月) 23:50:18
Solarisには /bin/[ (/usr/bin/[)は無い。教育に適さないOSだ。

293 :名無しさん@お腹いっぱい。:2006/11/07(火) 01:39:01
へーーー

294 :名無しさん@お腹いっぱい。:2006/11/07(火) 08:57:14
waitはpidを引数にとれるからまったく意味がないわけでもないんじゃないか。


295 :名無しさん@お腹いっぱい。:2006/11/07(火) 18:29:53
初心者な質問ですが
シェルの格納場所を取得できるような変数とかコマンドとか
誰か知りませんか?

296 :名無しさん@お腹いっぱい。:2006/11/07(火) 19:25:20
>>295
cat /etc/shells

297 :名無しさん@お腹いっぱい。:2006/11/07(火) 20:11:55
which じゃないの ?


298 :名無しさん@お腹いっぱい。:2006/11/07(火) 20:19:08
>>297
whichは cshのコマンド。それを言うなら type。

typeでは、type shとかやって、/bin/sh とかの PATHは得られるけど、
「この OSにインストールされていて使えるシェルを調べたい」
という質問の回答としては不適当。

299 :名無しさん@お腹いっぱい。:2006/11/07(火) 20:26:51
>>294
外部コマンドとして起動したwaitだと、どんな pidに対しても、

wait: pid 1234 is not a child of this shell

と言われるが、それに意味あるのか??

300 :名無しさん@お腹いっぱい。:2006/11/07(火) 22:14:52
bash入門講座してください

301 :名無しさん@お腹いっぱい。:2006/11/07(火) 22:38:30
>>300
つ言いだしっぺの法則。

302 :名無しさん@お腹いっぱい。:2006/11/08(水) 01:03:49
起動スクリプト読んでたら set start ってあったんだけどこれ何?


303 :名無しさん@お腹いっぱい。:2006/11/08(水) 01:13:19
>>301
講師探してます

304 :名無しさん@お腹いっぱい。:2006/11/08(水) 01:13:34
ファイル実行しようとして実行できないときに表示されるエラーなど(まぁ、エラー表示全般)を
表示しない方法ってありますか?
/dev/null 
は試してみましたが、無理でした。


305 :304:2006/11/08(水) 01:14:06
いい忘れたけど、Bashでう

306 :名無しさん@お腹いっぱい。:2006/11/08(水) 06:46:12
>>304
2>/dev/nullでどう

307 :名無しさん@お腹いっぱい。:2006/11/08(水) 08:01:42
エラー表示って、/dev/null にどうやって投げるんだ?
無理だろ

308 :名無しさん@お腹いっぱい。:2006/11/08(水) 08:39:00
>>307
だから、 2> /dev/null でエラー表示消せるんだってすでに >>306 が言ってるだろ。

309 :名無しさん@お腹いっぱい。:2006/11/08(水) 09:15:34
>ファイル実行しようとして実行できないときに表示されるエラーなど

は実行しようとしているコマンドではなくシェルが出してるので、
/dev/null にリダイレクトしても消せない。

つーわけで、シェルの出力をリダイレクトしてやればいい。

sh -c 'hoge fuga' 2>/dev/null


310 :名無しさん@お腹いっぱい。:2006/11/08(水) 09:24:40
>>309
欲嫁。

>>305 で bashだと言ってる。bashなら消せる。

bash$ hoge
hoge: command not found

bash$ hoge 2> /dev/null
bash$

311 :名無しさん@お腹いっぱい。:2006/11/08(水) 09:30:42
>>299
execすれば同じプロセスだろ。どの程度意味があるかは俺にもよくわからんが(笑)


312 :名無しさん@お腹いっぱい。:2006/11/08(水) 09:39:50
>>311
execしても、PIDが変わらないだけで別プロセス扱いになるので、
exec前にバックグラウンドで起動したプロセスを wait で待つことはできないよ。

313 :名無しさん@お腹いっぱい。:2006/11/08(水) 10:14:53
>>312
ありゃーwaitpidはできたよなと思ってよく調べたらshellのwaitコマンドはシステムコール
呼ぶ前にチェックしてるのか(bash調べ)。知らんかった...


314 :名無しさん@お腹いっぱい。:2006/11/08(水) 17:15:17
touch で使える書式で、あるファイルの更新時刻を取得したいのですが、
もっとシンプルor可搬性のある方法はあるでしょうか?
hoge=`stat -c %y FILENAME|sed -e 's/..\..*//' -e 's/-//g' -e 's/://g
' -e 's/ //g'`
touch -t "$hoge" FILENAME2


315 :名無しさん@お腹いっぱい。:2006/11/08(水) 17:20:32
-rオプションが使えるtouchならそれを使うのがいいと思われる。

-r, --reference=FILE
use this file's times instead of current time


316 :314:2006/11/08(水) 18:05:29
ファイルを編集したあと、その更新時刻を編集前に戻したい
というのが動機なので、それだとだめなのです。

317 :名無しさん@お腹いっぱい。:2006/11/08(水) 18:31:03
別のファイルを作って、更新時刻だけコピーして、
編集してから更新時刻をコピーし戻せば?

318 :名無しさん@お腹いっぱい。:2006/11/09(木) 00:01:36
動機が不純

319 :名無しさん@お腹いっぱい。:2006/11/09(木) 00:06:46
>>316
それだって touch -r で行けるじゃん。

$ touch -r hoge temp
$ vi hoge
$ touch -r temp hoge
$ rm temp

↑で、hogeを編集したあと、もとのタイムスタンプに戻せる。

320 :名無しさん@お腹いっぱい。:2006/11/09(木) 03:18:35
シェルスクリプトでC言語のscanfみたいなことやるためのコマンドは何でしょうか?

321 :名無しさん@お腹いっぱい。:2006/11/09(木) 09:36:02
touchもいろいろあるのでよくわからんが、gnuなら時刻指定に@<epochからの秒数>が
使えるはずなので、

hoge=`stat -c %Y FILENAME`

でとりだして

touch -d @$hoge FILENAME

とするのがシンプルじゃないか。


322 :名無しさん@お腹いっぱい。:2006/11/09(木) 09:42:34
>>320
強いて言えば read が近いと思うが、シェルスクリプトとCじゃ考え方が違う。
scanfと同じものを探すより頭を切り替えたほうがいいと思われる。


323 :名無しさん@お腹いっぱい。:2006/11/09(木) 14:31:53
外部コマンドとのやりとりがシェルスクリプトなみに簡潔で
変数や構文の取り扱いがperlとかruby程度に洗練された
スクリプト言語って何かない?
zshとかbashの専用機能使えばそこそこましなのかな?

324 :名無しさん@お腹いっぱい。:2006/11/09(木) 16:17:52
>>323
scsh


325 :名無しさん@お腹いっぱい。:2006/11/09(木) 16:28:29
>>323
python

326 :名無しさん@お腹いっぱい。:2006/11/09(木) 16:39:16
Perl とか Ruby でいいじゃん。

327 :名無しさん@お腹いっぱい。:2006/11/09(木) 18:10:24
continuation がまともに使えない ruby は屑
使えないんだったら実装するなと小一時…


328 :名無しさん@お腹いっぱい。:2006/11/09(木) 18:12:56
ここはそういうスレではありません。

329 :名無しさん@お腹いっぱい。:2006/11/10(金) 02:15:32
シェルスクリプトの変数について質問です。

以下のように値が格納された3つの変数があるとします。
hoge1=10
hoge2=20
hoge3=30

これを、
for i in `jot 3`
do
echo $hoge$i
done

のようなイメージで、変数名を展開し、
それから変数の値を展開したい場合の方法は
シェルスクリプトではどのように行うでしょうか?

330 :名無しさん@お腹いっぱい。:2006/11/10(金) 02:40:09
/etc/rc* 等を見れば例があると思うけど。キーワードはeval。

あなたのしたいことを実現するためには、
echo $hoge1
のような文字列をevalさせればいい。ということは、evalに与えるための
echo $hoge1 のような文字列が作れればいい。

そのまま$hogeとなる文字列に、1を作る変数展開をくっつけて
echo '$hoge'$i
と書くとそれは作れる。

ということは、答えは
eval echo '$hoge'$i


$ hoge1=foo
$ hoge2=bar
$ hoge3=baz
$ for i in `jot 3`; do eval echo '$hoge'$i; done
foo
bar
baz

331 :名無しさん@お腹いっぱい。:2006/11/10(金) 06:12:56
安易にevalをつかうな。
配列にした方がいい。

332 :名無しさん@お腹いっぱい。:2006/11/10(金) 07:05:17
配列はbash依存。evalを使うのが普通。

333 :名無しさん@お腹いっぱい。:2006/11/10(金) 08:19:36
配列はksh起源ニダ。


334 :名無しさん@お腹いっぱい。:2006/11/10(金) 18:53:54
evalを安易に使うなというのは同意。
でも、>>329の場合は使ってよいケース。

set使ってもいいけど。

335 :名無しさん@お腹いっぱい。:2006/11/10(金) 21:52:15
bashだけだろ?
eval使えるの

336 :名無しさん@お腹いっぱい。:2006/11/10(金) 22:23:34
>>335
釣りにも最低限の知識が必要。

337 :>>329:2006/11/11(土) 02:47:00
みなさま、ありがとうございます!!

evalは初めて知りました。

早速試してみますー

338 :名無しさん@お腹いっぱい。:2006/11/11(土) 09:35:47
>>335
lisp1.5でも使えるぞ。

339 :名無しさん@お腹いっぱい。:2006/11/11(土) 11:27:45
evalが使えるからってえばるなよ。


340 :名無しさん@お腹いっぱい。:2006/11/11(土) 12:21:48
>>339
全米が失笑した

341 :名無しさん@お腹いっぱい。:2006/11/11(土) 14:26:06
bashの良いところはこれだな。

echo ls |bash

342 :名無しさん@お腹いっぱい。:2006/11/12(日) 02:57:55
どのシェルでも出来るだろ?

343 :名無しさん@お腹いっぱい。:2006/11/13(月) 21:35:17
シェルスクリプトの中で vi を起動しているのですが、
そのスクリプトの標準出力をリダイレクトしてしまうと
nvi の場合は
ex/vi: Vi's standard input and output must be a terminal
と出て終了し、vim の場合は
Vim: Warning: Output is not to a terminal
と出て画面が表示されなくなってしまいます。
リダイレクトしてても普通に vi を操作できるようにする
ことはできないのでしょうか?

344 :名無しさん@お腹いっぱい。:2006/11/13(月) 21:42:52
>>343
できない。そういう場合は ed とか sed とかを使う。

345 :名無しさん@お腹いっぱい。:2006/11/13(月) 23:03:31
>>344
無理ですか。ありがとうございます。

346 :名無しさん@お腹いっぱい。:2006/11/13(月) 23:13:50
>>343
そのスクリプトの目的が中でviに適当なコマンドを与えて自動的に編集させたいということなら
expectでも使わないとだめだろうが、スクリプトで前処理や後処理はするけどそこから起動した
viは普通にインタラクティブに操作したいというのであれば、vi > /dev/tty とかすればいいと
思われる。どっちを意図してるのかはわからんわけだが。




347 :名無しさん@お腹いっぱい。:2006/11/14(火) 05:11:39
>>346前半
ed

348 :名無しさん@お腹いっぱい。:2006/11/14(火) 20:11:42
>>346
前者です。>/dev/tty でできました。
ありがとうございます。

349 :名無しさん@お腹いっぱい。:2006/11/14(火) 20:13:27
あ、後者だった。

350 :名無しさん@お腹いっぱい。:2006/11/16(木) 22:18:34
ls|grep -v hoge|xargs rm -i
ではまってしまった。
rm -i `ls|grep -v`
でごまかした。

351 :名無しさん@お腹いっぱい。:2006/11/17(金) 10:38:58
カレントディレクトリにある、拡張子のないファイル「だけ」を消すために、
rm *
を実行したら、すべてのファイルが消えてしまいました。(rm *.*じゃないのに)
これって、シェルのバグじゃないでしょうか?

あと、消してしまったファイルを復活する方法を教えてください。

352 :名無しさん@お腹いっぱい。:2006/11/17(金) 10:46:01
仕様です。

>> あと、消してしまったファイルを復活する方法を教えてください。

バックアップから戻せばOK


353 :名無しさん@お腹いっぱい。:2006/11/17(金) 11:51:49
そもそも UNIX では拡張子に大した意味ないんだよ。(一部アプリ以外)
普通は「拡張子」なんて言わず単に「suffix」って言うし。

354 :名無しさん@お腹いっぱい。:2006/11/17(金) 11:53:13
そうか、Makefileとかは例外の「一部アプリ」だったのか、、

355 :名無しさん@お腹いっぱい。:2006/11/17(金) 12:06:03
>>354
突っ込み処が不明なんだが…


356 :名無しさん@お腹いっぱい。:2006/11/17(金) 19:37:09
>>351
拡張子の無いファイル名に一致するシェル表現かー
.loginのようにドットで始まるファイルは対象なのか対象外なのかむずかしい

357 :名無しさん@お腹いっぱい。:2006/11/17(金) 19:43:00
>>356
.loginとかは対象外だろ(つーか、cshの例出すなよ)

hoge.c hoge hage.c hage

↑がある時、hogeとhageだけ消したいということだろ。
そう言えば、拡張子なしのファイルに一致するワイルドカードって
シェルにはないんだな。DOSだと「*」で桶なんだけど。

358 :名無しさん@お腹いっぱい。:2006/11/17(金) 21:19:06
zshなら*~*.*


359 :名無しさん@お腹いっぱい。:2006/11/17(金) 21:22:54
>>357
find . -maxdepth 1 \! -name \*.\* -delete

360 :名無しさん@お腹いっぱい。:2006/11/17(金) 23:21:23
分からないので教えてください。
シェルの中で、あるシェルを呼び出すことを考えています。
2つのシェルはカレントであれば、実行可能なんですが、
パスを変えて実行するにはどうすればよいでしょうか?

例:
# pwd
/home/hoge1

# ls ../hoge2
A.sh Z.sh

# cat ../hoge2/A.sh
#! /bin/sh

date
./Z.sh

# cat ../hoge2/Z.sh
#! /bin/sh

echo "Call OK!"

# ../A.sh
2006年 11月 17日 金曜日 23:15:46 JST
../A.sh: line 4: ./Z.sh: そのようなファイルやディレクトリはありません

361 :名無しさん@お腹いっぱい。:2006/11/18(土) 00:21:05
A.sh

#!/bin/sh
pwd


362 :名無しさん@お腹いっぱい。:2006/11/18(土) 00:44:52
>>360
死ねよ

363 :名無しさん@お腹いっぱい。:2006/11/18(土) 01:50:24
拡張子の無いファイルを消すというか、「.」が無いファイルを消せば。
rm `ls * | fgrep -v .`
ファイル名にスペースがあると不十分かもしれん。

364 :名無しさん@お腹いっぱい。:2006/11/18(土) 05:10:01
>>361
ありがたいのですが、意味がわからないです。

365 :名無しさん@お腹いっぱい。:2006/11/18(土) 07:22:59
IFSで区切られた必要なファイルのリストがあって、そのリストには載ってないが
実在する余計なファイルを削除するにはどうしたらいいでしょうか?

#必要なファイル100個とか
files="a.txt 1.html hoge.jpg"

#実在するファイル100+1個以上
e_files="1.html a.txt fuga.gif hoge.jpg"

366 :名無しさん@お腹いっぱい。:2006/11/18(土) 09:42:33
>>363
ディレクトリというのがUNIXにはあるんだけども。

>>365
試してないけどこんな感じで
contains () {
 local x="$1"; shift
 for i; do
   [ "x$i" = "x$x" ] && return 0
 done
 return 1
}
for f in $e_files; do
 contains "$f" $files || echo "rm $f"
done

367 :名無しさん@お腹いっぱい。:2006/11/18(土) 11:00:01
>>360
シェルってゆうな。クズ

368 :名無しさん@お腹いっぱい。:2006/11/18(土) 12:01:09
>>367
なんと呼ぶの?

369 :名無しさん@お腹いっぱい。:2006/11/18(土) 12:07:06
>>368
>>1嫁。クズ。

370 :名無しさん@お腹いっぱい。:2006/11/18(土) 12:17:17
>>366 ディレクトリというのがUNIXにはあるんだけども。

ls ではディレクトリは出力されませんがな。
alias 付けてなければ。

371 :名無しさん@お腹いっぱい。:2006/11/18(土) 12:26:34
>>370
こんなんなるんだけど。

$ touch fff
$ mkdir ddd
$ touch ddd/fff
$ /bin/ls *
fff

ddd:
fff
$ rm `/bin/ls * | fgrep -v .`
rm: cannot remove `ddd:': No such file or directory
rm: cannot remove `fff': No such file or directory
$

372 :名無しさん@お腹いっぱい。:2006/11/18(土) 12:42:51
>>369 大変失礼しました。で、そうのようなコメントがあるのであれば
どうすればよいのでしょうか。

373 :名無しさん@お腹いっぱい。:2006/11/18(土) 12:54:17
>>350
ちょっとメッセージが違うけど、これでいけることがわかった。
ls|grep -v hoge|xargs -p -n 1 rm

374 :370:2006/11/18(土) 12:58:27
>>371
ああ、そういうことか。
>>370は変なツッコミだった。スマソ。

ls * だとディレクトリの下のファイルがでちゃうから ls -d * だな。

さらに、はじめからディレクトリを除外するとしたら

for x in `ls -d * | fgrep -v .`; do
if [ ! -d $x ]; then
echo $f
fi
done

かな

ls -d * | fgrep -v . | xargs file | fgrep -v 'directory' | awk -F: '{print $1}' | xargs rm

ってのもあるけど

375 :名無しさん@お腹いっぱい。:2006/11/18(土) 13:19:33
>>365

安直なやり方として、

rm `fgrep -v -f files e_files` # 最初は rm じゃなくechoで試す

ってのがある。
ただし、files と e_files は 1行1ファイルでリストされたものとして。
さらに、files の中に "hoge.jpg" があると、e_files に中にある "hogehoge.jpg" は
削除されないけど。

376 :名無しさん@お腹いっぱい。:2006/11/18(土) 15:54:42
WindowsPowershellについてご意見ください。
よろしくお願いします。

http://www.forest.impress.co.jp/article/2006/11/15/windowspowershell.html
http://support.microsoft.com/kb/926140

377 :名無しさん@お腹いっぱい。:2006/11/18(土) 17:30:16
>>360
シェルとシェルスクリプトは別物だぞw

Z.shのところ絶対パスでやれ。
それだけだ。

378 :名無しさん@お腹いっぱい。:2006/11/18(土) 17:32:26
('з')

379 :名無しさん@お腹いっぱい。:2006/11/18(土) 17:33:39
for文について質問です。
内容はfor文のループ変数に配列を代入することは可能なのか?ということです。

for STARTEND in "(1 100)" "(101 200)";do
START=${STARTEND[0]}
END=${STARTEND[1]}
echo -e "&Avestart\nAve_start=${START}/\n&Aveend\nAve_end=${END}/" > namelist/namelist${START}to${END}
done
なるスクリプトを書いてみたのですが、
./speccalc.sh: line 15:(1 100): missing `)' (error token is "100)")
なるエラーが出ます。


もしbashで配列を配列のまま代入するということが不可能であるとして、それ以外のシェルで配列のまま代入することが可能なものはあるのでしょうか?
あるいはもっと他のツールを使った方がよいのでしょうか?

教えていただけないでしょうか?

380 :名無しさん@お腹いっぱい。:2006/11/18(土) 17:35:51
#/bin/bash

hairetu=(a b c d e f d)

for i in ${hairetu[@]}
do
echo $i
done

exit 0


こんな感じか?

381 :名無しさん@お腹いっぱい。:2006/11/18(土) 17:39:21
>>380
違うだろ。複数の配列を for 文の要素として使いたいらしいが。

382 :名無しさん@お腹いっぱい。:2006/11/18(土) 17:40:46
bash Uzzzee.. よそ行け

383 :名無しさん@お腹いっぱい。:2006/11/18(土) 17:42:03
>内容はfor文のループ変数に配列を代入することは可能なのか?

配列をFor文のループ変数に使えるかってことじゃないのか?

384 :名無しさん@お腹いっぱい。:2006/11/18(土) 17:46:26
どのような結果が得たいのか書けよ

385 :名無しさん@お腹いっぱい。:2006/11/18(土) 18:01:27
forという事はborne shellだな。
borne shellには配列などというデータタイプは無い。

386 :名無しさん@お腹いっぱい。:2006/11/18(土) 18:02:55
>>385
"borne shell"って何ですかww

387 :名無しさん@お腹いっぱい。:2006/11/18(土) 18:13:33
for i in "(1 100)" "(101 200)";do
eval STARTEND=$i
START=${STARTEND[0]}
END=${STARTEND[1]}
echo $START, $END
done

キモい。ただでさえキモい bash でさらにこんなキモいことするのか。


388 :名無しさん@お腹いっぱい。:2006/11/18(土) 18:22:48
>>387
いんじゃないか。

こんなインチキしか思い付かなかった
perl -e 'foreach $a ([1, 100], [101, 200]) {
 print "$a->[0] $a->[1]¥n";
}'


389 :名無しさん@お腹いっぱい。:2006/11/18(土) 19:47:14
>>387
evalを使えば何でも出来る。

390 :名無しさん@お腹いっぱい。:2006/11/18(土) 19:51:45
evalが使えるからってエヴァるな。

391 :名無しさん@お腹いっぱい。:2006/11/18(土) 20:13:24
>>390
>>339
>>340

392 :名無しさん@お腹いっぱい。:2006/11/19(日) 01:55:30
>>380-390
みなさん早速にレスいただき恐縮です。外出しておりました。申し訳ありません。
質問したかったのは>>383さんが書かれたとおりです。
>>387さんが書かれたスクリプトでうまくいきました。ありがとうございました。

ところで、配列がサポートされているCシェル、Kシェル、Zシェルでは「for文(に相当する構文)のループ変数に配列を用いること」は可能でしょうか?

393 :名無しさん@お腹いっぱい。:2006/11/19(日) 07:47:13
>>366
ありがとうございます。
とりあえず片付いたらそれをテストしてみます。

394 :名無しさん@お腹いっぱい。:2006/11/19(日) 09:28:12
>>366
関数を作らず、変数を1個使ってうまくいきました。



395 :名無しさん@お腹いっぱい。:2006/11/19(日) 15:33:55
>>366
項目が1万越していたら終らない

396 :名無しさん@お腹いっぱい。:2006/11/19(日) 20:32:30
>>395
そういう状況で適用したい人は自分で考えるってことで。

397 :名無しさん@お腹いっぱい。:2006/11/20(月) 17:41:38
今使っている参考書に
: ${VAR:="exit script because VAR is not set."}
と記述すると、VARに値が設定されていない場合に実行中のスクリプトを
終了させることが出来る、と書かれているのですがうまくいきません。
これはなぜなんでしょうか?わかる方教えてください。お願いします。

398 :名無しさん@お腹いっぱい。:2006/11/20(月) 18:01:09
>>397
なんていう本? そんな間違った本捨てて、別の買え。
正しくは、

: ${VAR:?"exit script because VAR is not set."}

399 :397:2006/11/20(月) 18:43:53
>>398
早速のレスありがとうございました。うまくいきました。
けっこう長い時間これで悩んでたので本当に助かりました。ありがとうございました。

ちなみに参考書は
「入門UNIXシェルプログラミング シェルの基礎から学ぶUNIXの世界」
です。他のところで聞いたらこれを勧められたのですがダメな本なのでしょうか…。

400 :名無しさん@お腹いっぱい。:2006/11/20(月) 19:22:21
ミスプリ程度の間違いだろ。


401 :名無しさん@お腹いっぱい。:2006/11/20(月) 19:44:22
別紙とかで訂正とかないのか?

402 :名無しさん@お腹いっぱい。:2006/11/20(月) 19:46:36
http://www.sbcr.jp/books/products/detail.asp?sku=4797321946
のフォームで報告しときゃいいんじゃね。

403 :名無しさん@お腹いっぱい。:2006/11/20(月) 21:19:03
ミスプリなのか書き間違いなのかは知らんが、おかしいと思ったらマニュアル
読んで調べるぐらいした方がいいぞ。

404 :名無しさん@お腹いっぱい。:2006/11/21(火) 00:06:55
はじめまして。
最近シェルスクリプト始めたのですがわからないことが
あって困っています。
小数の比較ってどうすればできるんですか?

---------------------------------------
#!/bin/bash

if [ 0.0001 -ge 0.00001 ]
then
echo "success"
fi
---------------------------------------

という風に書いて実行するとinteger expression expectedが出てしまうんで
すけど、どうしたらいいのでしょうか?

405 :名無しさん@お腹いっぱい。:2006/11/21(火) 00:21:31
>>404
整数で比較する

406 :名無しさん@お腹いっぱい。:2006/11/21(火) 00:26:08
どうもこうもない。
あきらめろ。
awkやperlなど使うしかないだろ。


407 :名無しさん@お腹いっぱい。:2006/11/21(火) 00:39:35
シェルスクリプトで痩せられんですか???
evalつかえばなんでもできるって…

408 :名無しさん@お腹いっぱい。:2006/11/21(火) 00:42:06
case $(echo 0.0001 - 0.000001 |bc) in
-.*)
echo fail
;;
*)
echo success
;;
esac

409 :名無しさん@お腹いっぱい。:2006/11/21(火) 02:31:42
こんばんわ。アクセスログの集計をやっています。
元ファイルを加工して1レコードが2フィールドで
接続開始時刻:接続終了時刻
の形式のファイルをawkを使って抽出してあります。
時刻は数値化(Excelの日付表示を数値表示に変換したもの)
されているので直接比較可能です。

スクリプトで処理したい作業は
あるレコードの接続開始時刻から接続終了時刻の間に

A 全レコード中、接続開始時刻が何件含まれているか
B 全レコード中、接続終了時刻が何件含まれているか

を各レコードの情報とともに表示させることです。
接続開始時刻:接続終了時刻:A件数:B件数
みたいに。

実際には同時接続数がどれぐらいあるかチェックしたいので
おおざっぱに掴めればなあと。

awkでレコードを1行読むごとに、全行比較という形で
スクリプトを書きかけたのですが、そもそも全行と
比較できず終わってしまっているようです。

{x=0;y=$1;z=$2;if ($1<=y && z<=$2) x=x+1;print x}

readlineが必要そうであれこれ試しているのですが、
こちらは全く使ったことがないので苦戦しています。
どなたかお知恵拝借させてください。

410 :名無しさん@お腹いっぱい。:2006/11/21(火) 06:04:41
>>409
まず

> A 全レコード中、接続開始時刻が何件含まれているか
> B 全レコード中、接続終了時刻が何件含まれているか

を実現する関数かスクリプトを作って
レコードを1行読むごとにそれを実行する、という方法はどう?

awk で関数なんて作ったことないから外しているかも。

411 :名無しさん@お腹いっぱい。:2006/11/21(火) 09:49:42
同時接続数をチェックするのが目的なら

時刻 接続開始or終了

という形式のレコードを時刻でソートしてから頭からなめて

開始が来たら同時接続数++,
終了が来たら同時接続数--

としたほうが簡単じゃないか。

412 :名無しさん@お腹いっぱい。:2006/11/21(火) 13:12:30
それなら接続開始・終了をそれぞれ+1,-1にしておいて足せばいい。

413 :名無しさん@お腹いっぱい。:2006/11/21(火) 22:33:38
readlinkコマンドがない場合、ファイルのリンク先を知るには
どうすればいいんでしょうか?

414 :名無しさん@お腹いっぱい。:2006/11/21(火) 22:49:55
ls -l そして awk

415 :名無しさん@お腹いっぱい。:2006/11/21(火) 22:52:06
ls -l hoge | sed -e 's/^.* -> //'

416 :名無しさん@お腹いっぱい。:2006/11/21(火) 22:57:01
readlink を入れるといいよ。

417 :名無しさん@お腹いっぱい。:2006/11/21(火) 22:59:24
今後は coreutilsは必須として標準化するべきだな。

418 :名無しさん@お腹いっぱい。:2006/11/21(火) 23:05:44
>>415
ファイル名に -> が入っている場合はアウトかと思っていましたが
やってみたらOKでした。ありがとうございます。

419 :名無しさん@お腹いっぱい。:2006/11/23(木) 00:32:53
シェルスクリプト環境によって動いたり動かなかったり不便・・・じゃない?

420 :名無しさん@お腹いっぱい。:2006/11/23(木) 00:48:18
ある環境で確実に動くってことは、それだけで重要な事なのです。
全ての環境で共通に動かせるようにする道は死屍累々ですから。

421 :名無しさん@お腹いっぱい。:2006/11/23(木) 02:53:37
>>419
笑止。
真にマルチプラットフォームな言語なぞ無い。

422 :名無しさん@お腹いっぱい。:2006/11/23(木) 09:16:15
そんなあちこちに持ってったりしないしなぁ。
動かなかったら直せばいいだけ。

423 :名無しさん@お腹いっぱい。:2006/11/23(木) 11:42:56
いや、シェルスクリプトは異なる環境でも少ない修正で動く、だと思うけどな。
所詮テキストファイルだし。

424 :名無しさん@お腹いっぱい。:2006/11/23(木) 13:32:35
>>423
異なる環境で動かすことを考えて作成されたシェルスクリプトに限定すれば真。

425 :名無しさん@お腹いっぱい。:2006/11/23(木) 13:58:38
お前ら その昔 「Cはポータブル」 って言われてたんだぞ

426 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:04:16
>>425
いまでもアセンブリ書くよりはるかにポータブルだが…


427 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:07:32
結局、どれだけ多くの環境に移植されてるかってことじゃねーの?

428 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:15:22
その昔「ポータブルC」と呼ばれていたものは、
Cコンパイラ自身がポータブル。

429 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:16:43
>>425
C言語のソースはポータブルだが、バイナリはポータブルじゃない。
だから、実行形式そのままをポータブルにしたい場合は
Cを使わずにシェルスクリプトで書くというのが常識。

430 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:21:50
C で書くような規模だけどポータビリティが欲しい時にシェルスクリプトは使わないな。
そういう時は C で極力ポータブルに書く。

431 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:22:06
>>429
シェルスクリプトにヒアドキュメントでCのソース埋め込めばポータブル。

432 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:24:09
configure?

433 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:24:46
>>430
「バイナリが」と言ってるだろ。
どこの世界に、バイナリレベルでポータブルなCがあるんだよ???

434 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:27:19
そういう場合は Java かなあ。
シェルスクリプトで書くのはシェルスクリプトで良いやと判断した時だけ。

435 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:37:16
Javaは重いから論外。

436 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:47:11
Perl/Python/Rubyあたりのスクリプト言語で。

437 :名無しさん@お腹いっぱい。:2006/11/23(木) 14:50:41
JavaはJavaVMがインストールされている環境でしか動かない、
という意味ではポータブルではない。

同様のことがperlとかにも言える。

シェルがインストールされていない環境はあり得ないので、
そういう意味でシェルスクリプトが最もポータブル。

438 :名無しさん@お腹いっぱい。:2006/11/23(木) 15:01:39
現状で /bin/sh のポータビリティってどの程度確保されてる?
bash に link されてる奴は論外として…


439 :名無しさん@お腹いっぱい。:2006/11/23(木) 15:39:46
>>437
シェルだけで完結することはほとんどない。
さまざまな外部コマンドを使うことによって機能を実現できる。
つまり外部コマンドの仕様や配置などによって修正を余儀なくされるから、
ポータビリティはかなり低い。
また、それとは別にシェルそのものの実装違いもあるし。


440 :名無しさん@お腹いっぱい。:2006/11/23(木) 15:51:36
>>439
それは人のレベルによる問題。
普段からポータビリティを気にしてシェルスクリプトを書いていれば、
たとえ外部コマンドを使うにしても、どのOSでも使えるコマンドとオプションの
範囲だけで書く癖が付いているから、ポータビリティの高いスクリプトを
書くことは簡単にできる。逆に、別のOSで動かす予定がなかったのに、
たまたま別のOSでも動かす機会があった時に、そのまま動いてしまうことがほとんど。

一方、Java/perlとかだと、インストールされていなければそこで終り。

441 :名無しさん@お腹いっぱい。:2006/11/23(木) 16:02:23
ポータブルな範囲で使うならシェルスクリプトが最もポータブル。
シェルスクリプトがポータブルな範囲でのみ仕事を受け付けます。

442 :名無しさん@お腹いっぱい。:2006/11/23(木) 17:01:59
UNIX板なので別のOSがWindowsだって可能性は考えなくて良いのかな。

443 :名無しさん@お腹いっぱい。:2006/11/23(木) 17:41:21
なんでこの文脈からWinが出てくるのか理解不能w

444 :名無しさん@お腹いっぱい。:2006/11/23(木) 18:41:14
>>443
ガンガレ

445 :名無しさん@お腹いっぱい。:2006/11/23(木) 19:48:59
でもPowerShellは凄そうだぜ?

446 :名無しさん@お腹いっぱい。:2006/11/23(木) 19:51:57
どこらへんが?

447 :名無しさん@お腹いっぱい。:2006/11/23(木) 20:02:23
パイプにテキストじゃなくてオブジェクトが流れるとか。

448 :名無しさん@お腹いっぱい。:2006/11/23(木) 20:09:25
プロセスコンテクストが違うプログラム同士でどうやってオブジェクトを受け渡すの?
シリアライズして渡すのかな。ネットワーク越しにも渡せるの?

449 :名無しさん@お腹いっぱい。:2006/11/23(木) 20:24:33
>>448
詳しくはしらんけど
http://www.atmarkit.co.jp/fdotnet/special/powershell02/powershell02_01.html

cmd.exeより100倍ほどつかいやすそうだ。

450 :名無しさん@お腹いっぱい。:2006/11/23(木) 20:26:48
cmd.exeより100倍ほど重いけどなw

451 :名無しさん@お腹いっぱい。:2006/11/23(木) 20:37:55
まさかVMが毎回起動する訳じゃないよね?

452 :名無しさん@お腹いっぱい。:2006/11/23(木) 21:59:17
シェルスクリプトの中で、リダイレクトされているかどうかを
判定するにはどうすればいいのでしょうか?

453 :名無しさん@お腹いっぱい。:2006/11/23(木) 22:14:56
>>452
標準出力が、端末か、それ以外(ファイル)かの判定なら、
[ -t 1 ]
でできる。

454 :452:2006/11/23(木) 22:31:08
>>453
まさにそれでした。ありがとうございます。

455 :名無しさん@お腹いっぱい。:2006/11/24(金) 10:34:20
シェルスクリプトを最近勉強し始めた初心者なのですが、クォートのことで
ちょっとわからないことがあるので質問します。
$ ABC=100
$ VAR=`echo "'\$ABC'"`
$ echo $VAR
$ '100'
(\はバックスラッシュです)
このようになるのですが、実行結果が'$ABC'ではなくて'100'になるのが理解できません。
展開するときに\によって$の効果が打ち消されると思うのですが…。
なぜこうなるかどなたかお教え下さい。お願いします。

456 :名無しさん@お腹いっぱい。:2006/11/24(金) 10:38:18
>>455
VAR=`echo "'\\$ABC'"`

にする必要がある。バッククォートの中の \ は \\ にする。

あと、ここでは結果的に関係ないけど、
最後の echo $VAR は echo "$VAR" にした方がいいな。

457 :455:2006/11/24(金) 12:20:02
>>456
なるほど。$を一つ加えると結果はうまいこといきました。

でもなぜこうなるのかが納得できません。
\\$ABCの部分で一つ目の\が二つ目の\の効果を打ち消して、
$ABCは普通に変数として解釈されechoに渡されると思うのですが…。
それともバッククオートの中では何か特別なルールがあるのでしょうか?


458 :名無しさん@お腹いっぱい。:2006/11/24(金) 12:26:12
>>457
($を加えるんじゃなくて \ を加えるんだけどね)

>バッククオートの中では何か特別なルールがある
と言ってるとおり。


\\$ABC は、バッククォートで1回解釈される時に
\$ABC となってから、その中身が解釈される。

`echo "\\$ABC"`
の中身が解釈される時に
echo "\$ABC"
に変わってから実行されるので。


ちなみに、推奨しないが、バッククォートの代わりに $( )を使うと、

VAR=$(echo "\$ABC")

みたいに、\はひとつで良い。

459 :名無しさん@お腹いっぱい。:2006/11/24(金) 12:49:19
$( )
使える環境では使っとけ。


460 :455:2006/11/24(金) 13:15:21
>>458
ありがとうございました。やっと理解できました。

>>459
$()についても少し調べてみます。使える場合はこっちの方がすっきりしますね。


ご回答いただいた皆様本当にありがとうございました。


461 :名無しさん@お腹いっぱい。:2006/11/24(金) 13:16:28
$( )は使うな。シェルはポータビリティ大切。

462 :名無しさん@お腹いっぱい。:2006/11/24(金) 13:17:14
eval ${ifconfig_args}=\$ifconfig_${ifn}

ってどういう風に解釈されるんですか?

463 :名無しさん@お腹いっぱい。:2006/11/24(金) 13:28:13
>>462
ifconfig_args=AAA
ifn=hoge0
だとすると、

1回目の解釈で、
AAA=$ifconfig_hoge0
になるわな。
で、2回目にifconfig_hoge0の中身がAAAに代入される。

464 :名無しさん@お腹いっぱい。:2006/11/24(金) 13:42:06
>>461
> シェルはポータビリティ大切。
場合によるでしょ。

465 :名無しさん@お腹いっぱい。:2006/11/24(金) 14:23:22
コーノウ(←英語は発音大事)

466 :名無しさん@お腹いっぱい。:2006/11/24(金) 14:40:40
hoge.192.168.0.1
という文字列から 192.168.0.1 の部分を抜き出したいのですが
どのようにすればよいのでしょうか?

467 :名無しさん@お腹いっぱい。:2006/11/24(金) 14:46:23
$( )や配列、算術演算は使っとけ。
スクリプトが読みやすくなるから。


468 :名無しさん@お腹いっぱい。:2006/11/24(金) 15:02:08
>>466
↓を実行。標準入力から hoge.192.168.0.1 の文字列を読ませる。

IFS=. read hoge a b c d
echo $a.$b.$c.$d


>>467
そういう理由は軟弱。却下。

469 :名無しさん@お腹いっぱい。:2006/11/24(金) 15:16:23
読み易さに勝るポータビリティはない。


470 :名無しさん@お腹いっぱい。:2006/11/24(金) 15:20:32
>>469
???? 「読み易い」って、書き直すってこと?
そもそもポータビリティの意味を誤解してます。

471 :名無しさん@お腹いっぱい。:2006/11/24(金) 18:28:43
/bin/shが$()を扱えない環境ってどれ?

472 :名無しさん@お腹いっぱい。:2006/11/24(金) 18:37:28
>>471
伝統的なBourne shellが/bin/shであるような環境では使えない。
Solarisとか。

473 :名無しさん@お腹いっぱい。:2006/11/24(金) 20:07:45
Solarisなら無視して桶。ユーザーほとんどいないし。
そのうちSolaris側が /bin/sh -> bash にリンクしてくる可能性すら考えられる。

474 :名無しさん@お腹いっぱい。:2006/11/24(金) 21:54:31
sh の実体が ksh になることはあっても bash になることはないと断言しよう。

475 :名無しさん@お腹いっぱい。:2006/11/24(金) 22:29:24
いまさらkshもなかろうw


476 :名無しさん@お腹いっぱい。:2006/11/25(土) 02:19:05
アプリの関係でcshで書いてます。
------------------------
#!/bin/csh
set i=`ps axwww|grep -i aaaa | grep -v grep | wc -l`
echo $j
------------------------

aaaaは存在しないプロセス。
この実行結果、
「0」でなくて「1」になるのはなぜですか?


477 :476:2006/11/25(土) 02:23:46
訂正です。
------------------------
#!/bin/csh
set i=`ps axwww|grep -i aaaa | grep -v grep | wc -l`
echo $i
------------------------

478 :名無しさん@お腹いっぱい。:2006/11/25(土) 02:41:37
>>477
パイプで一気に処理している中身を細切れにして中身を確認してみろ。

あと、pgrep があるならそっちを使った方がいい。

479 :476:2006/11/25(土) 02:55:11
>>478
レスありがとうございます。
パイプ grep -v /bin/csh の追加が必要でした。


480 :名無しさん@お腹いっぱい。:2006/11/25(土) 03:22:50
せめて csh -f にしろや。

481 :名無しさん@お腹いっぱい。:2006/11/25(土) 19:03:08
ifconfigを使ってネットワークにつないでいるインターフェースのデバイス名だけを
取得するにはどう記述すればよいのでしょうか?

482 :名無しさん@お腹いっぱい。:2006/11/25(土) 19:33:35
>>481
OSによってifconfigの出力書式が違うかも知れんが、
↓みたいな感じで行ける。

ifconfig -a | sed -n 's/^\([^ ][^ ]*\).*/\1/p'

483 :名無しさん@お腹いっぱい。:2006/11/25(土) 19:37:28
HP-UXだと、
lanscanだな。


484 :名無しさん@お腹いっぱい。:2006/11/25(土) 20:30:33
FreeBSD だと ifconfig -l で。

485 :名無しさん@お腹いっぱい。:2006/11/25(土) 21:05:38
http://photos.nikkansports.com/sports/synchro/photo/P2006091401786.jpg

486 :名無しさん@お腹いっぱい。:2006/11/26(日) 14:56:47
>>397-400
ミスプリ程度の間違いじゃない、ダメ本みたいだ。
こっちの書き込みによると。

http://pc8.2ch.net/test/read.cgi/linux/1065059126/794

487 :名無しさん@お腹いっぱい。:2006/11/27(月) 02:12:37
自分で作ったシェルスクリプトの引数に"*"と指定したら、
クォートされずに*が展開されて位置パラメタに入っちゃうんだけどなんでなんでだろ。
echoとかの組み込みコマンドだと上手くクォートされるんだけどなぁ。


488 :名無しさん@お腹いっぱい。:2006/11/27(月) 07:20:57
>>487
どこかでクォートし忘れているって事なんだろうな。
そのスクリプトを晒してみな

489 :名無しさん@お腹いっぱい。:2006/11/29(水) 21:31:14
age

490 :名無しさん@お腹いっぱい。:2006/11/29(水) 21:52:55
noglob とかそういうのを使ってみたり

491 :名無しさん@お腹いっぱい。:2006/11/29(水) 22:31:42
>>490
それは csh。cshは帰れ。

/bin/shでは set -f
ただし、ちゃんとクォートすれば set -f は必要ない。

492 :名無しさん@お腹いっぱい。:2006/11/30(木) 21:22:53
$10以降の引数ってどのshでも使えるんでしょうか?

493 :名無しさん@お腹いっぱい。:2006/11/30(木) 21:28:40
>>492
Bourne Shellでは $10以降は使えない。
bashとかkshとかでは使えるが、${10} とする必要あり。
zshでは $10 でも使える。

494 :名無しさん@お腹いっぱい。:2006/11/30(木) 21:31:31
$10は
${1}0と解釈されるから、${10}としないとだめ。


495 :名無しさん@お腹いっぱい。:2006/11/30(木) 21:33:03
zsh は使用料が 10 ドルから、っていう意味?

496 :名無しさん@お腹いっぱい。:2006/11/30(木) 21:33:29
>>494
Bourne Shell では ${10} でもダメ。逆に zsh では $10 でも桶。

497 :492:2006/12/01(金) 00:40:19
皆さんありがとうございます。
shで最後の引数を取得したかったのですが、無理なのですね。

498 :名無しさん@お腹いっぱい。:2006/12/01(金) 00:48:11
shiftするとかいくらでも方法はある。

499 :名無しさん@お腹いっぱい。:2006/12/01(金) 02:24:15
GNU Autoconf付属のinfo内の
"Portable Shell:: Shell script portability pitfalls"
が非常に詳しくて面白い。よくこれだけまとめあげたものだ


500 :名無しさん@お腹いっぱい。:2006/12/02(土) 01:04:32
>>470
人間レベルポータビリティが高いということだと思う。

狭い範囲でのポータビリティを満たすためにトリックを駆使するより、
移植性のない明快な方法複数のほうが意図が読めるから未知プラット
フォームに持って行きやすい(ことがある)。


501 :名無しさん@お腹いっぱい。:2006/12/02(土) 01:16:48
>>500
そういう概念を表すためにわざわざ、可読性(readability)とか
保守性(maintainability)とかいう用語が存在してるでしょうに。

502 :名無しさん@お腹いっぱい。:2006/12/02(土) 01:23:51
そうなんだけど、人間を計算機の一種に見立てて、可読性と
移植性は似てる(生体計算機上で移植性がある=可読性)と
元レスはいいたかったんでないの?


503 :名無しさん@お腹いっぱい。:2006/12/02(土) 20:53:48
ABC
DEF
GHI
JKL
MNO

という文字列を
DEF
GHI
JKL
という部分をごっそり抜いて、
ABC
hogehoge1
hogehoge2
hogehoge3
JKL
としたいのですが、
何か良い案はないでしょうか?


504 :名無しさん@お腹いっぱい。:2006/12/02(土) 21:06:34
MNOはどこに消えたのか?

505 :名無しさん@お腹いっぱい。:2006/12/02(土) 21:08:49
>>504
それくらい察してやれ。
それより、DEFやGHIなどの文字列があるものとして置換していいのか、
それとも2行目から4行目までを置換するという意味なのか、
質問の意味が複数解釈できるね。

506 :名無しさん@お腹いっぱい。:2006/12/02(土) 21:11:49
>>505
全くそのとおり。


507 :名無しさん@お腹いっぱい。:2006/12/02(土) 22:17:15
「ごっそり抜い」 たはずのJKLは
なぜ残っているのか?

508 :名無しさん@お腹いっぱい。:2006/12/02(土) 22:24:14
>>507
だからぁ、察してやれよ、MNOの書き間違いだろ。

509 :名無しさん@お腹いっぱい。:2006/12/02(土) 22:27:07
これでいいか? gawk だが

$ cat minus.awk
#!/usr/bin/gawk -f

ARGIND == 1 {
    minus[ $0 ] = sprintf("hogehoge%d",FNR)
    next
}
$0 in minus {
    print minus[ $0 ]
    next
}
{
    print
}
$ gawk -f minus.awk (抜くキーワードを書いたファイル)  (抜かれる方のファイル)

510 :名無しさん@お腹いっぱい。:2006/12/02(土) 22:37:23
すみません。改めます。
シェルスクリプトでやりたいです。

ABC
DEF
GHI
JKL
MNO

という文字列を
DEF
GHI
JKL
という部分をごっそり抜いて、
ABC

MNO
の間に特定の文字列を挿入して、
ABC
hogehoge1
hogehogeXX
hogeYY
MNO
としたいのですが、
何か良い案はないでしょうか?
よろしくお願いします。


511 :名無しさん@お腹いっぱい。:2006/12/02(土) 22:43:52
>>510
↓ほれ、これでいいかい? シェルだけでやったよ。外部コマンドは使ってない。

while read line
do
case $line in
ABC|MNO) echo "$line";;
DEF) echo hogehoge1;;
GHI) echo hogehogeXX;;
JKL) echo hogeYY;;
esac
done < input_file

512 :名無しさん@お腹いっぱい。:2006/12/02(土) 22:55:31
>>510
cat aa |sed -e '/DEF/,/JKL/c\
hogehoge1\
hogehogeXX\
hogeYY'

513 :名無しさん@お腹いっぱい。:2006/12/02(土) 22:56:21
>>510
>>505は読んだのかw?


514 :名無しさん@お腹いっぱい。:2006/12/02(土) 22:56:33
>>512
お約束のcatが無駄です。あと、シェルだけでやりたいと申されております。

515 :名無しさん@お腹いっぱい。:2006/12/02(土) 23:02:26
>>510
> DEF
> GHI
> JKL
> という部分をごっそり抜いて、
これで人に通じると思ってるの? ゆとり世代?

1 ABCの次の行からMNOの前の行まで。
2 2行目から4行目まで
3 2行目から最終行-1まで
4 DEFまたはGHIまたはJKL
5 1文字目がAかM以外
6 1文字目がDまたはGまたはJ
...

516 :名無しさん@お腹いっぱい。:2006/12/02(土) 23:06:31
>>510
お客様、仕様書が曖昧で作業に入れませんのでご確認をお願いいたします。
こいういうことでしょうか?

START-STRING
AAAA
BBB
CC
END-STRING



START-STRING
REPLACED-1
REPLACED-2
REPLACED-3
END-STRING

とする。
START-STRINGとEND-STRINGに囲まれた複数行を置換するんでしょ?
読み取れないのは、AAAA,BBB,CCの部分は何でも良いのか、
hogehoge1,hogehogeXX,hogeYYの部分は固定なのか、AAAA,BBB,CCそれぞれに
対応させて置換するのか。

517 :510:2006/12/02(土) 23:06:52
1 ABCの次の行からMNOの前の行まで。
ですので、
512
でほぼ解決です。
ありがとうございました。
説明がわかりにくくてご迷惑をお掛けしました。
また出直します。


518 :名無しさん@お腹いっぱい。:2006/12/02(土) 23:09:28
>>517 池沼?

>>512
DEFとJKLではさまれている行だろうが、どこが
> ABCの次の行からMNOの前の行まで。
なんだよ。

519 :名無しさん@お腹いっぱい。:2006/12/02(土) 23:23:28
>>518
「ほぼ」って言ってるから良いんじゃない?
sed -e '/ABC/,/MNO/c¥
ABC¥
hogehoge1¥
hogehogeXX¥
hogeYY¥
MNO'
程度の修正は誤差であるというくらい理解したんじゃないかna

520 :名無しさん@お腹いっぱい。:2006/12/02(土) 23:32:03
for (i=0; i<10; i++) ; do
echo "$i"
done
Bourne Shellでも動きますか?

521 :名無しさん@お腹いっぱい。:2006/12/02(土) 23:32:35
むりでーす。


522 :520:2006/12/02(土) 23:32:52
間違えた

for ((i=0; i<10; i++)) ; do
echo "$i"
done
Bourne Shellでも動きますか?

523 :名無しさん@お腹いっぱい。:2006/12/02(土) 23:38:40
>>522 はBourne shでは使えない。

for i in 1 2 3 4 5 6 7 8 9; do
echo "$i"
done

が最もポータブル。
seqやjotはあえて使わない。

524 :名無しさん@お腹いっぱい。:2006/12/02(土) 23:52:40
問題の出し方と内容がム板と犬板のシェルスクリプトスレに現れた奴に似てる

525 :名無しさん@お腹いっぱい。:2006/12/02(土) 23:57:42
>>523
exprくらいは使ってもいいじゃね?

526 :名無しさん@お腹いっぱい。:2006/12/05(火) 17:00:20
aaa='"AAA AAA" BBB'
for n in $aaa; do
echo "$n"
done
だと
"AAA
AAA"
BBB

となるのですが、これを
"AAA AAA"
BBB
とするにはどうすればいいのでしょうか?


527 :名無しさん@お腹いっぱい。:2006/12/05(火) 17:12:42
>>526
for n in "$aaa"

常に "$hoge" みたいに " " を付ける癖を付けろ。

528 :名無しさん@お腹いっぱい。:2006/12/05(火) 17:13:44
>>527
欲嫁。それだと逆に全部つながっちゃうが、、

529 :名無しさん@お腹いっぱい。:2006/12/05(火) 22:58:15
>>526
ゴリ押し

aaa='"AAA AAA" BBB'
while test "x$aaa" != x
do
 case $aaa in
 \"*\"\ *)
  echo "$aaa" | sed 's,^\("[^"]*"\).*,\1,'
  aaa=`echo "$aaa" | sed 's,^"[^"]*" *,,'` ;;
 *\ *)
  echo "$aaa" | sed 's, .*,,'
  aaa=`echo "$aaa" | sed 's,[^ ]* *,,'` ;;
 *)
  echo "$aaa"; break ;;
 esac
done


530 :名無しさん@お腹いっぱい。:2006/12/05(火) 23:20:23
" " ではさんだやつは " " も消しちゃいかんという仕様がなぁ

531 :526:2006/12/06(水) 13:55:07
う、そんなにややこしいことなんですか?
精進します

532 :名無しさん@お腹いっぱい。:2006/12/06(水) 16:54:03
変数に入っている最初の1文字だけを取り出したいんですけど、なにか良い方法は無いでしょうか?

533 :名無しさん@お腹いっぱい。:2006/12/06(水) 17:48:45
>>532
foo=$(echo $bar | sed -e 's!\(^.\).*!\1!')

534 :名無しさん@お腹いっぱい。:2006/12/06(水) 18:48:23
>>532
${var%%${var#?}}

535 :532:2006/12/06(水) 20:52:29
>>533, >>534
ありがとうございます。

自分なりに無い知恵を絞って出した答えは
foo=`perl -e "print substr('$var', 0, 1)"`
だったんですが、>>534には感動しました。


536 :名無しさん@お腹いっぱい。:2006/12/06(水) 21:02:54
>>534 は Bourne Shell で動かないからポータブルじゃない。
↓がお勧め。

printf '%c\n' "$var"

537 :名無しさん@お腹いっぱい。:2006/12/06(水) 21:42:29
>>532
echo ${var:0:1}

538 :名無しさん@お腹いっぱい。:2006/12/06(水) 21:48:39
>>537
bash/ksh依存乙。

539 :名無しさん@お腹いっぱい。:2006/12/06(水) 21:54:07
これならかなりクラシックな環境でも可
foo=`expr "$bar" : '^\(.\)'`

540 :名無しさん@お腹いっぱい。:2006/12/06(水) 22:49:45
うぉー、さらに増えてる。
みなさん、ありがとうございます。

printfが存在を知ったり、exprの使い方がわかったりと、かなり勉強になりました。
ただ、>>539の正規表現は'\(.\)'`でいいみたいです。
^は正規表現の意味を持っていないので無視される。みたいなワーニングがでました。

541 :名無しさん@お腹いっぱい。:2006/12/06(水) 23:48:50
echo "$var" | cut -c1 は?


542 :名無しさん@お腹いっぱい。:2006/12/07(木) 00:01:29
grep hoge * | nkf -e > out というコマンドを
xargs を使った形に書き換えたいんですが、どう書けばいいんでしょうか?

543 :名無しさん@お腹いっぱい。:2006/12/07(木) 00:25:47
find * -print | xargs grep hoge | nkf -e > out?
ていうか grep とか grep -r で済むなら xargs の出番なさそう。


544 :542:2006/12/07(木) 01:04:05
あ、すいません。説明を間違えました。
ファイルの文字コードがそれぞれ違う可能性があるから、
for i in *; do grep hoge $i |nkf -e >> out; done
と同じことをしたいのでした。
この場合も for の行で外部コマンドを呼んでいないから
ARG_MAX の制限はないようですね。
xargs で起動するコマンドの中にパイプやリダイレクトを
入れることはできるか、と聞きたかったのでした。

545 :名無しさん@お腹いっぱい。:2006/12/07(木) 02:08:55
一応

 find * ... -print | xargs -n 1 sh -c 'grep hoge $0 | nkf -e' > out

とかでもできるけど、

 find * ... -print | xargs nkf -e | grep hoge > out

の方がエレガントなような。でも、 file: line 形式で grep 結果を
出したいなら、ついでに * 展開で溢れるケースも考慮して

 find . ... -print | while read i; do grep hoge $i | nkf -e; done > out

しかし ARG_MAX の心配をするほどファイルがあるなら

 find . ... -print | xargs perl -MJcode -lne 'print jcode("$ARGV: $_")->euc if /hoge/' > out

がちょっと長いけど速そう。


546 :名無しさん@お腹いっぱい。:2006/12/07(木) 09:27:20
とりあえずお約束として
find -print0
xargs -0
にしる、と突っ込んでおくべきなのだろうか

547 :名無しさん@お腹いっぱい。:2006/12/07(木) 13:53:37
お約束だけど GNU のは入れられなかったりとか
仕様バグがどうこうとか。

548 :名無しさん@お腹いっぱい。:2006/12/12(火) 15:03:35
PPPoA で接続してるんですが、モデムのログがほとんど残してもらえず(容量少い)
不安定な回線なのにどの程度不安定なのか把握できず困ってます
切断されてもすぐ再接続されるわけですが、これを記録しておきたいと思います
ping 撃ちまくるのはわかりますが、切断された時と再接続された時を記録するには
どんなスクリプト書けばいいですか?

549 :名無しさん@お腹いっぱい。:2006/12/12(火) 19:53:11
1.txt
↓内容
1
11
111

cat 1.txt | grep 11
とやると
11と111の2つがヒットしてしまいます(^_^;)
11の行だけを抜き出す方法はないですかね?


550 :名無しさん@お腹いっぱい。:2006/12/12(火) 20:14:17
>>549
grep -w 11

551 :名無しさん@お腹いっぱい。:2006/12/12(火) 20:47:34
>>549
catが無駄です、のお約束。

552 :名無しさん@お腹いっぱい。:2006/12/12(火) 21:11:23
>>551
あんたマイナーになってるよ。

553 :名無しさん@お腹いっぱい。:2006/12/12(火) 22:06:51
>>549
grep -x 11 1.txt

554 :名無しさん@お腹いっぱい。:2006/12/13(水) 10:08:05
>>551 かっこいいから俺も会社で真似して渋く言ってみます

555 :名無しさん@お腹いっぱい。:2006/12/13(水) 10:26:21
zcatとかgzcatとかbzcatとかに置き換えるときに、
修正する文字数が少なくなるという、多大なメリットがある。


556 :名無しさん@お腹いっぱい。:2006/12/13(水) 10:30:43
フィルタだってことがわかりやすいしな。
別に咎めるほどのことではないと思う。

557 :名無しさん@お腹いっぱい。:2006/12/13(水) 11:39:14
>>555
本気で言ってんのか?
>>549のような使い捨てのワンライナーなら「修正の手間」も糞もねぇだろ。

元スクリプトが
script
なら、
zcat foo.gz | script
とすりゃいいだけだ。一行の修正も要らないし、zcat決めうちにするより
scriptの汎用性が維持される。
こっちのがツールボックスアプローチとして正しいわな。

必要も無いcatを使ってるスクリプトを見ると、俺は不安になるね。
書き手に変な癖がついてるのか、リダイレクションすら理解して無いのか、
品質上に問題があるんじゃないのかとか。

558 :名無しさん@お腹いっぱい。:2006/12/13(水) 11:53:26
>>557
使い捨てならわざわざリダイレクトなり引き数なりに
直す必要もないじゃん。
script の汎用性の話は意味がわからん。

559 :名無しさん@お腹いっぱい。:2006/12/13(水) 12:05:56
使い捨てなら cat のムダくらい気にせんでもいいやんけ。

560 :名無しさん@お腹いっぱい。:2006/12/13(水) 12:11:06
>>558, 559
使い捨てと言いつつ、
grep -w 11 1.txt
ですむものを、
cat 1.txt | grep -w 11
と書きたがる意図が分からんのだが。

そんなにcatとタイプして無駄にプロセスを一個増やすのが好きか?
変な癖を正当化してるだけじゃないか?

561 :名無しさん@お腹いっぱい。:2006/12/13(水) 12:18:25
>>560
おれが書いたわけじゃないから
おれも意図はわからんな。

プロセスの減らし方あれこれ考えるより
さっさとスクリプト書きあげて
仕事終わらせちゃった方がいいじゃん。

562 :名無しさん@お腹いっぱい。:2006/12/13(水) 12:22:26
>>561
こんなことで「あれこれ考え」なきゃいけない時点でバカ。
判って無い証拠。
cat file cmd
が動作するなら
cmd <file
が確実に動作するんだから。
後者は無駄なプロセスが不要でタイプ量も少ない。

大体、タイプ量増えるのに、「さっさと仕事終わらせる」も糞もないだろ。

563 :562:2006/12/13(水) 12:23:13
すまん
cat file | cmd
な。

564 :名無しさん@お腹いっぱい。:2006/12/13(水) 21:39:54
cat 1.txt | grep -w 11 は中身確かめて加工に合っている。

565 :チラシの裏すまそ:2006/12/13(水) 22:01:56
漏れは同じファイルに対して何回かgrepしたいときに

cat file | grep KEYWORD1
 ↓
カーソルキーの↑を押して前回のコマンドを表示し、
Deleteキー連打して、新しいキーワードを打ち込んで
 ↓
cat file | grep KEYWORD2
 ↓
以下、繰り返し

こんな感じだけどね。
シェルスクリプトの中では使わんけど。

566 :名無しさん@お腹いっぱい。:2006/12/13(水) 22:06:27
>>565
単にコマンドラインの右端の文字を変更しやすいという意味なら、

$ < file grep KEYWORD1
$ < file grep KEYWORD2

↑みたいにやれば良い。< fileの部分が左に来てもいいんだよ。パイプは使わない。

567 :565:2006/12/13(水) 22:19:02
>>566
うぉ、そんな方法があるとは知らなかった。(@_@)
ありがとん。

568 :名無しさん@お腹いっぱい。:2006/12/13(水) 22:29:23
^1^2

とかしないの?

569 :名無しさん@お腹いっぱい。:2006/12/13(水) 22:42:36
cshつかわんから。


570 :名無しさん@お腹いっぱい。:2006/12/13(水) 23:42:18
>>569
bashでもzshでも、もちろんcshでも、^1^2とかできるはずだけど。
kshは知らんが。

571 :名無しさん@お腹いっぱい。:2006/12/14(木) 01:39:01
使える環境でも、^stop^start 位しか使わんな。
ヒットした最初の部分しか置き換わらんのが意外に使いにくいしくつう。


572 :名無しさん@お腹いっぱい。:2006/12/14(木) 02:16:19
ディレクトリーを1〜100まで一気に作りたいのですが
1 2 3....でなく
001 002 003...としたいのですが

d=0
mkdir 0$d
で$dに1つづ加算すると

1 2 3…となってしまいます orz
ヒントなんぞありましたら
おにぃちゃんおしえて! まぅまぅ

573 :名無しさん@お腹いっぱい。:2006/12/14(木) 02:20:03
>>572 まちがえたぁ

d=0
mkdir 00$d
で$dに1つづ加算すると

001 002…009 になるものの 10を超えると
0010になってしまうので

010…099 100 となれば幸いです

574 :名無しさん@お腹いっぱい。:2006/12/14(木) 02:31:55
perl -e 'for ("001".."100") { mkdir $_; }'

575 :名無しさん@お腹いっぱい。:2006/12/14(木) 02:37:10
zsh -c 'mkdir {001..100}'

576 :名無しさん@お腹いっぱい。:2006/12/14(木) 07:34:49
>>572
mkdir `seq -w 1 100`

577 :名無しさん@お腹いっぱい。:2006/12/14(木) 11:29:48
>>574-576

おにいちゃん!ありがと!まぅまぅ
perl,zshも勉強しますorz

winamp のストリームで
bpsやってるよ! まぅまぅ



578 :名無しさん@お腹いっぱい。:2006/12/14(木) 14:03:12
バトルプログラマーシラセ・・・・・bpsね

579 :名無しさん@お腹いっぱい。:2006/12/14(木) 15:23:17
あるプロセスが起動しているかどうかps|grepで確認するにはどうしたらいいですか?
ps ax|grep XXX|wc -l
で確認すると、grep自身が入ったり入らなかったりします。


580 :名無しさん@お腹いっぱい。:2006/12/14(木) 15:27:43
>>579
pgrep XXX

581 :名無しさん@お腹いっぱい。:2006/12/14(木) 15:45:13
>>580
ありがとうございます

582 :名無しさん@お腹いっぱい。:2006/12/14(木) 16:10:56
>>579
grep -v grepしとけ

583 :名無しさん@お腹いっぱい。:2006/12/14(木) 16:22:18
>>582
プロセス名が logreport だったりするとだめ。

584 :名無しさん@お腹いっぱい。:2006/12/14(木) 17:02:27
>>583
やるな。
grep [X]XX
なら?


585 :名無しさん@お腹いっぱい。:2006/12/14(木) 17:54:13
ボーンシェルってシェル関数使えるって思っても
いいのでしょうか?
シゥル関数使えないボーンシェルもありますか?

586 :名無しさん@お腹いっぱい。:2006/12/14(木) 18:02:02
まゆ毛ボーンシェル

587 :名無しさん@お腹いっぱい。:2006/12/14(木) 18:07:39
「ボーン shell」って何ですか?
Bourne shellなら知ってますが、
それとは違うシェルのことですよね?

588 :名無しさん@お腹いっぱい。:2006/12/14(木) 18:19:27
マット・デイモンのやつだろ

589 :名無しさん@お腹いっぱい。:2006/12/14(木) 19:04:19
シゥル関数ktkr

590 :名無しさん@お腹いっぱい。:2006/12/14(木) 23:41:00
シゥル関数、微妙に発音しにくい。

591 :名無しさん@お腹いっぱい。:2006/12/15(金) 00:34:46
シゥルスクリプト

592 :名無しさん@お腹いっぱい。:2006/12/15(金) 00:36:26
はだかーのまっまっでベイベ
おどろーよシゥルダンス

593 :名無しさん@お腹いっぱい。:2006/12/15(金) 01:07:42
>>592

どう見ても米米クラブです。
本当にありがとうございました。

594 :名無しさん@お腹いっぱい。:2006/12/15(金) 12:41:17
スクリプトのログを過去10日間保存して、それよい古いのは削除していくという感じにしたいのですが
LogFile名
Script名_$(date +"%Y%m%d-%H%M%S")_プロセスID

助言よろしくお願いします。

595 :名無しさん@お腹いっぱい。:2006/12/15(金) 12:50:00
>>594
プールン使うって理解でおk?

596 :名無しさん@お腹いっぱい。:2006/12/15(金) 14:07:22
プールン?

597 :名無しさん@お腹いっぱい。:2006/12/15(金) 14:15:37
ミキプルーン

598 :名無しさん@お腹いっぱい。:2006/12/15(金) 14:31:11
>>594
素直にlogrotateでも使え

599 :名無しさん@お腹いっぱい。:2006/12/15(金) 14:52:54
日付で判断出来なかったっけ?
どこかでそんなScriptを見た気がする。

600 :名無しさん@お腹いっぱい。:2006/12/15(金) 16:29:30
ファイル名から、%Y%m%dの文字列を抜き出して、
`expr \`date "+%Y%m%d"\` - 10`と比較して、これより小さければ、そのファイルを削除する。
あとはこれを、for f in `ls Script名_*` みたいな感じでループさせればいいだろう。


601 :名無しさん@お腹いっぱい。:2006/12/15(金) 18:05:57
今まで>>582の方法でやってたけど、>>583は盲点だった
多分そんなプロセス名自分は使わないだろうけど勉強になるな

602 :名無しさん@お腹いっぱい。:2006/12/16(土) 00:44:15
>>594
findで作成日が10日以前のログファイルを見つけて消すようにしては?

603 :名無しさん@お腹いっぱい。:2006/12/16(土) 10:07:15
>>602
この前その方法でやったけど何故か処理重かった・・・
なのでオレは>>600に近い方法でやったよ。
>600のそのままだとうまく動かないと思われ

604 :名無しさん@お腹いっぱい。:2006/12/16(土) 10:26:00
>>603
どの部分が重いのか、今後の為にも確認した方が良いと思うぞ。

605 :名無しさん@お腹いっぱい。:2006/12/16(土) 10:33:12
>>602
ほとんどの場合はそれでいいんだろうけどな、特に削除の場合は。


606 :名無しさん@お腹いっぱい。:2006/12/16(土) 15:11:30
作成する時に date % 10 でファイル名決めれば?
今回は 10 だけど、7 の場合は date +%w でできてもっと単純。


607 :名無しさん@お腹いっぱい。:2006/12/16(土) 18:26:39
兄者!たすけておくんなせぇ

バックアップを1日3回取りたいのですが
日付毎のディレクトリを作って

mkdir /bak/`date +%d%m`

と、ここまではいいのですが2回目に、このスクリプトが動くと
もうディレクトリあるぞ( ゚Д゚)ゴルァ!!とエラーがでます(たいしたことはないのですが)

ディレクトリー作成とバックアップ用のスクリプトは別けたほうが良いでしょうか
if で あるからもう作らない 次進めとやると
速度落ちますよね?
なんかいい知恵ないでしょうか?

608 :名無しさん@お腹いっぱい。:2006/12/16(土) 18:30:13
>if で あるからもう作らない 次進めとやると
これでいいじゃんw


609 :名無しさん@お腹いっぱい。:2006/12/16(土) 18:38:48
ごめんなさい ひらめきました
cronで夜中ディレクトリ作ればいいのですね

>>608 if で毎回やるのがなんかイヤな感じがしたので
識者の方々に伺おうと思ったww
今は反省している

それと%m%d だよな 
逝って来ます

610 :名無しさん@お腹いっぱい。:2006/12/16(土) 18:41:48
つ mkdir -p

611 :名無しさん@お腹いっぱい。:2006/12/16(土) 18:56:56
>>610 それも考えたのですが。。。なんか毎回それを入れるのも・・・・・・
別に中身は消えないんでしょうけどww
なんか気持ち悪いorz

すんませんありがとでございます

612 :名無しさん@お腹いっぱい。:2006/12/16(土) 23:09:40
>>607
「ディレクトリがなかったら作る」でいいんじゃないの?
こんな感じ↓でやれば、1行で済むじゃん。

[ ! -d ディレクトリ ] && mkdir ディレクトリ

613 :名無しさん@お腹いっぱい。:2006/12/16(土) 23:57:53
たまには || の事も思い出してあげてください

614 :名無しさん@お腹いっぱい。:2006/12/17(日) 01:06:26
test のオーバーヘッド(w が気になるのなら、

 mkdir dir 2> /dev/null

でおけ。


615 :名無しさん@お腹いっぱい。:2006/12/17(日) 14:11:54
藻前らなかなかできるな!!
基本を身に付けたいorz

616 :名無しさん@お腹いっぱい。:2006/12/17(日) 18:50:14
>>614
set -e
で不都合が生じるから減点。

617 :名無しさん@お腹いっぱい。:2006/12/17(日) 19:54:25
たまには || の事も思い出してあげてください

mkdir -p dir 2>/dev/null || :


618 :名無しさん@お腹いっぱい。:2006/12/17(日) 20:25:49
-p || || では?


619 :名無しさん@お腹いっぱい。:2006/12/19(火) 18:01:03
確かにコマンドを形で覚えて?いるのか
標準入出力を意識(理解?)していない人は多いね。

たとえば、tar cf - . | ( cd /xxx && tar xpvf - )  とかすると
"-" について9割くらいは見ていた人に聞かれるし簡単には
何をやっているか理解してもらえない。

後は、3>&1 とか使えば多少は幅広がるのにね。

620 :名無しさん@お腹いっぱい。:2006/12/19(火) 18:04:17
- が標準入出力を表すかどうかはコマンドによって違うんで
またちょっと別の話かと。

621 :名無しさん@お腹いっぱい。:2006/12/20(水) 06:17:18
でも解凍するときは zxvf 圧縮するときは zcvf みたいに覚えてて
それぞれのオプションの意味を覚えていないやつってのはいるよね

結局伸びない

622 :名無しさん@お腹いっぱい。:2006/12/20(水) 06:25:30
>>621
そんな奴おらんやろ〜

623 :名無しさん@お腹いっぱい。:2006/12/20(水) 07:40:37
FreeBSDのtarなら圧縮形式自動判定してxvfだけで展開できるしな。

624 :名無しさん@お腹いっぱい。:2006/12/20(水) 07:45:47
>>622
いるよ〜

>>623
paxもおすすめ

625 :名無しさん@お腹いっぱい。:2006/12/20(水) 09:08:53
jはbzipだろ
zはgzだろ
xは解凍
cは圧縮
vは状況表示
fはファイル指定

じゃ無かったかな。
man tar してません。

626 :名無しさん@お腹いっぱい。:2006/12/20(水) 09:22:56
きっと、おぼえていることにポイントがあるわけじゃなくてぇ

627 :名無しさん@お腹いっぱい。:2006/12/20(水) 09:26:12
lhaのオプション覚えてる人いてる?
普段はファイラから解凍や圧縮してたんでじぇんじぇん覚えてにゃ

628 :名無しさん@お腹いっぱい。:2006/12/20(水) 09:32:17
マニュアルを引ければいいんじゃね?

629 :名無しさん@お腹いっぱい。:2006/12/20(水) 09:48:15
マニュアルを脳にインストールする話じゃないのか?

630 :名無しさん@お腹いっぱい。:2006/12/20(水) 10:18:46
いや
その知識自体の価値ではなく、その人の性質というかそういうものについてだよね

631 :名無しさん@お腹いっぱい。:2006/12/20(水) 11:27:32
なんにせよスレ違いだ。

632 :名無しさん@お腹いっぱい。:2006/12/20(水) 13:42:15
結局は基本を覚えて延髄の反射で書けるようにしておけってことでしょうか?
あと正規表現モナーですか?

633 :名無しさん@お腹いっぱい。:2006/12/20(水) 19:39:44
>>600
月が替わったりすると無理じゃね?w
20061125
20061201
20061231
20070101

よく月の1日にはリセットだなw


634 :名無しさん@お腹いっぱい。:2006/12/20(水) 21:25:32
文末にw付けるとwwなんかwwwいいことでもあるのか?wwwwwwwwwww

635 :名無しさん@お腹いっぱい。:2006/12/20(水) 23:33:00
grep の -w オプションみたいなもんだな

636 :名無しさん@お腹いっぱい。:2006/12/21(木) 00:16:42
>>633
BSD系なら
T=$(($(date +"%s") - 86400*10))
DATE=$(date -r $T +"%Y%m%d")

Linux (というかGNU coreutils) なら
DATE=$(date -d '10 days ago' +"%Y%m%d")

637 :名無しさん@お腹いっぱい。:2006/12/21(木) 00:27:27
date -v -10d +%Y%m%d

638 :名無しさん@お腹いっぱい。:2006/12/21(木) 00:37:34
>>637
-vはFreeBSD限定のような気がする

639 :名無しさん@お腹いっぱい。:2006/12/21(木) 02:39:21
>>594
rm `ls -t /directory/*.log | tail -n +11`
なんて方法もあるかなと。

640 :名無しさん@お腹いっぱい。:2006/12/21(木) 08:04:44
>>639
それいけるのか?
1日に複数個ログはいても

641 :名無しさん@お腹いっぱい。:2006/12/21(木) 16:23:03
date は1日引くのができるんじゃないっけ?
ago だかなんかの引数で

642 :名無しさん@お腹いっぱい。:2006/12/21(木) 16:29:37
>>641
FreeBSDのdateは無理です

643 :名無しさん@お腹いっぱい。:2006/12/21(木) 16:36:30
FedoraBSDって無いんですか?

644 :名無しさん@お腹いっぱい。:2006/12/21(木) 18:41:38
kFreeBSDならあってもおかしくない気がするよな

645 :名無しさん@お腹いっぱい。:2006/12/23(土) 04:10:11
大量のファイルに対して、
foo *
というようなことをやりたいのですが、arg list too longというような
メッセージが出ます。
で、有名な
echo * | xargs foo
で解決と思いきや、xargsってARG_MAXを超えた引数については、fooを呼びなおすみたいですね。
fooは全てのファイルに対して1回だけ実行されないと困るんですが、何かいい方法はあるでしょうか?


646 :名無しさん@お腹いっぱい。:2006/12/23(土) 09:36:47
foo を改造するしかない

647 :名無しさん@お腹いっぱい。:2006/12/23(土) 09:45:32
>fooは全てのファイルに対して1回だけ実行
xargs でいいじゃん

648 :名無しさん@お腹いっぱい。:2006/12/23(土) 10:11:40
全てのファイル <-> それぞれのファイル

649 :名無しさん@お腹いっぱい。:2006/12/23(土) 10:27:41
>>645
1 fooをshell functionで書き直す。
2 arglist広げてシステム再構築。
3 fooを複数回実行されても困らないよう作り直す。

650 :名無しさん@お腹いっぱい。:2006/12/23(土) 10:31:37
まずはオナヌーして落ち着く

651 :名無しさん@お腹いっぱい。:2006/12/23(土) 11:34:05


 find ... | xargs tar cvf hoge.tar

で ARG_MAX にあふれたファイルだけ入ったアーカイブ作ったことある。

たぶん受け側のプログラムを標準入力からファイル一覧読むように
改造するしかない。

652 :名無しさん@お腹いっぱい。:2006/12/23(土) 12:20:28
>>647
欲嫁。
>xargsってARG_MAXを超えた引数については、fooを呼びなおす

653 :名無しさん@お腹いっぱい。:2006/12/23(土) 12:25:48
xargs -n 100 とかでおk、とかそういう話ではない?

654 :名無しさん@お腹いっぱい。:2006/12/23(土) 12:37:58
>>652
xargsでいいじゃん

655 :名無しさん@お腹いっぱい。:2006/12/23(土) 12:54:36
>>654
欲嫁。
>xargsってARG_MAXを超えた引数については、fooを呼びなおす

656 :名無しさん@お腹いっぱい。:2006/12/23(土) 13:05:47
>>645の書き方がいまいち曖昧なんだが
fooで同じファイルを二度処理するのはまずいってだけの話なら
xargsでいいんでないの?

一度のfooの実行で全ファイルを処理したいっつーんなら、
引数渡しでやるのは無理だわなそりゃ

657 :645:2006/12/23(土) 13:58:06
色々レスありがとうございます。

書き方が悪かったですが、fooは複数回実行されると困るというよりも、
全ファイルのデータを読み込んだ上でまあ数値計算みたいなものなんですが、
計算を行いたいわけです。
一度に処理されないと意味がない、ということです。

>>653
これ試してみましたけど、-n 100000とかやってもARG_MAXの壁は越えられないんで駄目でした。

どうもfoo内でファイル一覧を読むように書き換えるか、再構築ってことみたいですね。


658 :名無しさん@お腹いっぱい。:2006/12/23(土) 14:02:43
ガベージイン
ガベージアウト

659 :名無しさん@お腹いっぱい。:2006/12/23(土) 15:50:07
引数の個数に1万か3万の制限があったような

660 :名無しさん@お腹いっぱい。:2006/12/23(土) 15:58:38
xargsって言ってる奴あほ過ぎる

661 :名無しさん@お腹いっぱい。:2006/12/23(土) 16:19:21
だから >>651 だってのに。
受け側のプログラムが引数使わないように修正する以外に方法はないって。

662 :名無しさん@お腹いっぱい。:2006/12/23(土) 22:29:44
xargsは obsolete。別の意味でも使ってはいけない。

663 :名無しさん@お腹いっぱい。:2006/12/23(土) 22:44:11
また湧いた

664 :名無しさん@お腹いっぱい。:2006/12/23(土) 22:50:02
>>662
kwsk

665 :名無しさん@お腹いっぱい。:2006/12/25(月) 11:59:27
find . -exec foo {} \;

666 :名無しさん@お腹いっぱい。:2006/12/25(月) 12:02:43
>>665
0点

667 :名無しさん@お腹いっぱい。:2006/12/25(月) 12:06:06
>>665
100点

668 :名無しさん@お腹いっぱい。:2006/12/25(月) 12:16:32
良く読んでない奴多いね。
foo file1 file2 .... (すべてのファイル)
みたいに、1回だけで実行したいという質問なので、
>>665 は 0点。

669 :名無しさん@お腹いっぱい。:2006/12/25(月) 12:26:59
んなことはみんなわかってる

670 :名無しさん@お腹いっぱい。:2006/12/25(月) 13:13:18
* じゃないしな。

671 :名無しさん@お腹いっぱい。:2006/12/25(月) 17:00:20
foo のbinary ラッパーを書いて、main を直接呼び出す。

普通はプログラムを書き直すよな...

672 :名無しさん@お腹いっぱい。:2006/12/27(水) 19:02:58
汎化してGPLで公開すればよくね?

673 :名無しさん@お腹いっぱい。:2006/12/28(木) 02:21:04
ARG_MAXってシェルの制限ではなくてint argc, char **argvのホントの
上限なんだね。標準入力からN行読み込んでexecvpで直接渡すようなの
書いてみたら32768でアウト。

任意のコマンドのmainをフックして、単なる関数として渡すような形で
汎化しないと駄目だな。もっとも問題のプログラムが処理対象のリストを
標準入力から読んだほうがよほどいいと思うけど。

674 :名無しさん@お腹いっぱい。:2006/12/28(木) 08:02:05
(ものすごくつまらない)ネタだと思ってたらマジで汎化してGPLとかほざいてたのか

675 :名無しさん@お腹いっぱい。:2006/12/28(木) 17:30:54
いや検討まで含めてネタだろ

バカか?

676 :名無しさん@お腹いっぱい。:2006/12/28(木) 19:40:53
gdb でmain で止めて、

レジスタ渡し、あるいはスタック渡しの部分で、malloc()で上書き。

.gdbinit で、がんがん代入。

実行開始。

ってのは、どう?

677 :名無しさん@お腹いっぱい。:2006/12/28(木) 21:21:09
こんなこと書いてるうちに元コード直し終わると思うけど、
-Dmain=xmain して、別途 dlsym(h, "xmain"); で呼び出すとか。
mainをそのまま直接呼ぶ方法あるのかな?ptraceとか使える?

678 :名無しさん@お腹いっぱい。:2006/12/28(木) 21:27:02
変わったシェルを使ってるんですね

679 :名無しさん@お腹いっぱい。:2006/12/28(木) 22:49:41
#!/bin/sh

( cat <<EOFEOF
extern int printf(const char *,...);
main(int ac,char *argv[])
{
int i;
for(i=0;i<ac;i++)
printf("%d %s¥n",i,argv[i]);
}
EOFEOF
) | gcc -x c -
(
echo "b *main"
echo "run"
echo 'set $r3=3'
echo 'set *((char **)$r4) = "test1"'
echo 'set *((char **)$r4+1) = "test2"'
echo 'set *((char **)$r4+2) = "test3"'
echo 'set *((char **)$r4+3) = "test4"'
echo " c" ) | gdb ./a.out

(Mac OS X 限定...)
ってな感じで、symbol table がある場合は可能らしい。strip されている場合は、
entry point を根性で探してくれ。

680 :名無しさん@お腹いっぱい。:2006/12/28(木) 22:52:07
おっと、
  set $r4=(void *)malloc(1000)
とかで malloc() するのを忘れずに。


681 :名無しさん@お腹いっぱい。:2006/12/29(金) 11:23:43
独自rtld書いてmain呼び出す。

682 :名無しさん@お腹いっぱい。:2006/12/29(金) 12:24:23
stripされててもmainのオフセット位置はどのプログラムでも同じ(同じ
環境なら)だから、そちらで調べた値をreadelfで得たエントリポイント
アドレスに足せばgdbのブレークポイント設定位置が判るよ。

後は$espから引数にアクセスして書きかえればいい。
この一連の操作はシェルスクリプトにできるから、xargsで扱えない
例外状況の処理用ツールになる(かもしれない)。

683 :名無しさん@お腹いっぱい。:2006/12/29(金) 19:38:07
ファイルをそのパスを含んだファイル名にしてコピーしたいです。
例えば ./foo/bar/mbox を ./foo_bar_mbox にコピーしたい。

find . -type f -name mbox -exec cp {} `echo {}|tr '\/' '_'` \;
とかしても
cp: ./foo/bar/mbox and ./foo/bar/mbox are identical (not copied).とエラーになっちゃう。

スレ違いだったら誘導して

684 :名無しさん@お腹いっぱい。:2006/12/29(金) 19:46:12
>>683
シェルが先に ` ` を評価するから
実際に実行されるのは
find . -type f -name mbox -exec cp {} {} \;
になるな。

685 :名無しさん@お腹いっぱい。:2006/12/29(金) 20:11:47
for f in `find . -type f -name mbox`;do cp $f `echo $f | tr '\/' '_'`;done


686 :名無しさん@お腹いっぱい。:2006/12/29(金) 20:27:54
無理に one-liner にしなくてもいいんじゃね?

687 :名無しさん@お腹いっぱい。:2006/12/29(金) 20:30:28
find . -type f -name mbox | sed 'p;s,/,_,' |xargs -n2 cp

688 :名無しさん@お腹いっぱい。:2006/12/29(金) 21:24:58
ありがとん。
>>685の方法で出来た。

689 :名無しさん@お腹いっぱい。:2006/12/29(金) 21:30:16
ねーねー
このスレのまとめって無いのかなぁ
ここしばらくの話、めっちゃ勉強になるんですけど

690 :名無しさん@お腹いっぱい。:2006/12/29(金) 21:32:30
わざわざ別解書いた >>687 が不憫。
それ以前の問題で外してしまった >>686 はもっと不憫。

691 :名無しさん@お腹いっぱい。:2006/12/29(金) 21:36:01
/usr/fbin

692 :名無しさん@お腹いっぱい。:2006/12/29(金) 22:02:53
>>690
>>687はエラー出ちゃうんだよ。
どうも最初の/しか置換されなくて._foo/bar/mboxにコピーしようするの。
で原因なんだろうと調べてみてるんだけどわけわからん。

693 :名無しさん@お腹いっぱい。:2006/12/29(金) 22:13:46
>>689
まとめてクレクレ

694 :名無しさん@お腹いっぱい。:2006/12/29(金) 22:48:30
>>692
多分 sed の部分が間違っているんじゃないかな
検証してないけど

695 :名無しさん@お腹いっぱい。:2006/12/29(金) 22:49:13
sedのところで、g が抜けてる。


696 :名無しさん@お腹いっぱい。:2006/12/29(金) 23:55:59
#!bash2.04

echo "$(echo " $(echo "`echo "$(ps)"`")")"

ちょい大げさに書きすぎたけど、こんな感じのを見かけた
これはどんな決まりでトークンに切り分けてるのさ!!

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

★スマホ版★ 掲示板に戻る 全部 前100 次100 最新50

read.cgi ver 05.04.00 2017/10/04 Walang Kapalit ★
FOX ★ DSO(Dynamic Shared Object)