トップページunix
1001コメント273KB

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

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。2006/01/21(土) 09:00:29
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。


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

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
0581名無しさん@お腹いっぱい。2006/03/13(月) 08:15:12
再度ファイル名を聞く処理は実装されてるでしょ。再帰してるし。
0582名無しさん@お腹いっぱい。2006/03/13(月) 08:52:56
>>581
コピー元ファイルが存在しなかった時に聞き直す処理が実装されていないようだが・・
0583名無しさん@お腹いっぱい。2006/03/13(月) 09:14:14
$tofileがディレクトリで、再帰して、
再帰実行した自分が失敗して帰った来た時に、cp強行が汚いどす。

$ true && true || echo done
$ true && false || echo done
done

0584名無しさん@お腹いっぱい。2006/03/13(月) 09:15:30
再帰呼出しせずに execすればプロセスは増えない。
さらに、自分をexecするんじゃなく、
whileループの中で、再入力ならcontinueするようにすれば
execする必要もなくなる。
と、ヒントだけ書いておこう。
0585名無しさん@お腹いっぱい。2006/03/13(月) 09:19:09
whileを使う処理が真っ先に思い浮かぶ人間はC出身だと思う。
再帰を使う処理が真っ先に思い浮かぶ人間はLisp出身だと思う。
0586名無しさん@お腹いっぱい。2006/03/13(月) 12:54:27
gotoを使う処理が真っ先に思い浮かぶ人間は(ry
0587名無しさん@お腹いっぱい。2006/03/13(月) 14:21:16
何だ
言ってみろ
0588名無しさん@お腹いっぱい。2006/03/13(月) 15:00:15
真のプログラマ。

「真のプログラマはgotoを恐れない」
0589名無しさん@お腹いっぱい。2006/03/13(月) 15:54:22
ども、後藤です。
0590名無しさん@お腹いっぱい。2006/03/13(月) 15:56:49
どうも倉間です
0591名無しさん@お腹いっぱい。2006/03/13(月) 16:12:04
>>567 の例題で gotoを発想するプログラマはヴァカ。
というか、/bin/shにgotoはないし、break 2以上ができるので
gotoは根本的に排除されている。

まあ、gotoがあるcshみたいなアフォなシェルもあるが・・
0592名無しさん@お腹いっぱい。2006/03/13(月) 16:22:00
遠い昔...

後藤っていう理科の先生が
フィリピンかどっかで自己紹介したら笑われたって
現地の言葉で「後藤=焼きうどん」なんだそうな
0593名無しさん@お腹いっぱい。2006/03/13(月) 16:52:09
ダイクストラ先生のまえで「私の名前は後藤です。」
0594名無しさん@お腹いっぱい。2006/03/13(月) 17:07:56
どうも進野です
0595名無しさん@お腹いっぱい。2006/03/13(月) 17:32:19
>>591
Knuth先生に失礼なヤツだな
0596名無しさん@お腹いっぱい。2006/03/13(月) 17:34:44
csh の利点って何?ただ文法が C ライクってこと?
0597名無しさん@お腹いっぱい。2006/03/13(月) 20:00:43
>>596
ヘボを見分ける指標になる。
0598名無しさん@お腹いっぱい。2006/03/13(月) 21:16:58
hoge1/hoge4.ooo
hoge2/hoge5.ooo
hoge3/hoge6.ooo
これを全て
hoge1/hoge4.ppp_ooo
hoge2/hoge5.ppp_ooo
hoge3/hoge6.ppp_ooo
に変えたいんですが、どうすればいいかわけわかめです。
help me orz
0599名無しさん@お腹いっぱい。2006/03/13(月) 21:18:38
>>598
mv hoge1/hoge4.ooo hoge1/hoge4.ppp_ooo
mv hoge2/hoge5.ooo hoge2/hoge5.ppp_ooo
mv hoge3/hoge6.ooo hoge3/hoge6.ppp_ooo
0600名無しさん@お腹いっぱい。2006/03/13(月) 21:22:27
>>598

for file in hoge*/hoge*.ooo
do
mv $file `echo $file | sed 's/ooo/ppp_ooo/'`
done

>>599
アフォか。
0601名無しさん@お腹いっぱい。2006/03/13(月) 21:29:06
rename 's/\.ooo$/.ppp_ooo/' */*.ooo
0602名無しさん@お腹いっぱい。2006/03/13(月) 21:32:07
sh: rename: command not found
0603名無しさん@お腹いっぱい。2006/03/13(月) 21:43:16
commmand.com みたく ren *.jpeg *.jpg と操作できるようなperlスクリプトあったよね?
0604名無しさん@お腹いっぱい。2006/03/13(月) 21:47:14
あったとしてもスレ違い。あと co"mmm"and.comって何だ?
0605名無しさん@お腹いっぱい。2006/03/13(月) 21:47:20
rename s/jpeg/jpg/ *.jpeg なら
0606名無しさん@お腹いっぱい。2006/03/13(月) 21:49:59
renameの話は犬板でどうぞ。
0607名無しさん@お腹いっぱい。2006/03/13(月) 21:52:22
OS関係ないじゃん
0608名無しさん@お腹いっぱい。2006/03/13(月) 22:01:24
関係あるだろ。
0609名無しさん@お腹いっぱい。2006/03/13(月) 22:02:35
くだ質スレと区別つかなくなってきた
0610名無しさん@お腹いっぱい。2006/03/13(月) 22:11:03
相変わらず
0611名無しさん@お腹いっぱい。2006/03/13(月) 22:12:36
相変わらず給料安いな w
0612名無しさん@お腹いっぱい。2006/03/13(月) 22:13:42
>>604
>mmm
アスキーネットにみたいなホストプログラム?
0613名無しさん@お腹いっぱい。2006/03/13(月) 23:22:45
犬以外でrenameがデフォで使えるOSってあんの?
0614名無しさん@お腹いっぱい。2006/03/13(月) 23:34:03
shiftの反対ってないですか?
スクリプトの最初で、引数で指定された全ファイルが存在することをチェックし、
そのあと各々処理したいんです。
0615名無しさん@お腹いっぱい。2006/03/13(月) 23:45:04
ない
存在チェック関数書いて呼べ
0616名無しさん@お腹いっぱい。2006/03/14(火) 00:05:48
しょんぼり・・・
あったら便利だと思うのに
ありがとうございました。
0617名無しさん@お腹いっぱい。2006/03/14(火) 00:17:49
>>614
shift の反対は無いが

>スクリプトの最初で、引数で指定された全ファイルが存在することをチェック

が目的なら shift 使わなくてもどうにかなるよ。

for i in "$@"
do
[ -e "$i" ] || exit
done
0618名無しさん@お腹いっぱい。2006/03/14(火) 00:30:04
シェルスクリプトってスクリプトのくせに互換性低いな。
06196142006/03/14(火) 00:35:48
>615,617

そうかfor文かfunction使えばいいのか・・・
ありがとうございます。
0620名無しさん@お腹いっぱい。2006/03/14(火) 07:34:29
>>601,605 のrenameコマンドの文法って、Linuxのrenameコマンドとは違うけど、
どこのrename ? そんなの本当にあるの?
0621名無しさん@お腹いっぱい。2006/03/14(火) 07:37:17
mmm = とらいえむ
0622名無しさん@お腹いっぱい。2006/03/14(火) 08:49:45
>620
perlについてくるぞ。
0623名無しさん@お腹いっぱい。2006/03/14(火) 08:57:46
>>620
http://search.cpan.org/~rmbarker/File-Rename-0.02/lib/File/Rename.pm
0624名無しさん@お腹いっぱい。2006/03/14(火) 09:05:15
「Linuxのrename」ってなんだよ
0625名無しさん@お腹いっぱい。2006/03/14(火) 11:59:17
UNIX用のVBscriptは無いかな
あると便利なんだが
0626名無しさん@お腹いっぱい。2006/03/14(火) 12:12:45
>>625
http://www.gnome.org/projects/gb/
は終わったか。
http://www.mono-project.com/VisualBasic.NET_support
とか?
0627名無しさん@お腹いっぱい。2006/03/14(火) 12:49:29
>>624
Linuxだと標準で /usr/bin/renameがある。
renameといえば普通これを指す。ちゃんとしたバイナリだし、
perlは無関係だよ。
0628名無しさん@お腹いっぱい。2006/03/14(火) 13:01:34
>>605 は Linuxの/usr/bin/renameだと
rename jpeg jpg *.jpeg
となるようだ。
全く別物の同名コマンドが出回っているようなので、
シェルスクリプトでは使えんな。
(もともと使ってなかったけど)
0629名無しさん@お腹いっぱい。2006/03/14(火) 13:12:49
>>627
一口に Linux って言ってもその辺はディストリによって違うだろ。
Debian の /usr/bin/rename は perl スクリプトだよ。
たぶん >>623 の古い版。
0630名無しさん@お腹いっぱい。2006/03/14(火) 13:17:14
「Linux の rename」じゃなくて
「util-linux の rename」だろうな。
0631名無しさん@お腹いっぱい。2006/03/14(火) 13:22:37
少なくとも Fedora Core 4 と Plamo は、>>628 の文法のバイナリコマンド。
perlではない。RH系とSlackware系が同じだから、他でも同じかと思ったら
Debianでは違うのか。
まあ、そもそもrenameなんて使わないし、どうでもいいけどね。
人に説明する時はどのrenameか断らないと誤解を受けるね。
0632名無しさん@お腹いっぱい。2006/03/14(火) 14:03:01
Debianのutil-linuxにはrenameはない。

俺の環境だとperlパケージの/usr/bin/prenameへのシンボリックリンク

$ update-alternatives --display rename
rename - status is auto.
link currently points to /usr/bin/prename
/usr/bin/prename - priority 60
slave rename.1.gz: /usr/share/man/man1/prename.1.gz
Current `best' version is /usr/bin/prename.

要するにDebianの場合サイトごとに違う。
# ここんところがシェルスクリプトスレにちょいと関係あるのでレスしてみた。

といってもrenameの候補があるperl以外のパケージ見たことないが…
0633名無しさん@お腹いっぱい。2006/03/14(火) 15:00:24
昔から自分で作ったの使ってたので
そういうのあるの知らなかった。
0634名無しさん@お腹いっぱい。2006/03/14(火) 17:20:25
相変わらずレベル低いなw
0635名無しさん@お腹いっぱい。2006/03/14(火) 21:03:04
lwallのrename.pl、relink.pl、そんでもってhakansonのmkshadowdir.plは
俺的には珠玉のperlスクリプト。
0636名無しさん@お腹いっぱい。2006/03/14(火) 22:36:00
初歩的な質問だが、

$cat L1
aaa
bbb
ccc
1
ddd
eee
2

これを
$cat L1
aaa bbb ccc 1
ddd eee 2

に変換する方法教えてくれ〜
0637名無しさん@お腹いっぱい。2006/03/14(火) 22:48:16
while read x; do
if expr "$x" : '[0-9][0-9]*$' > /dev/null; then
echo "$x"
else
echo -n "$x "
fi
done
0638名無しさん@お腹いっぱい。2006/03/14(火) 22:50:20
条件がよーわからん。

変換後が2行になるための条件は?
数字が来たらってこと?
0639名無しさん@お腹いっぱい。2006/03/14(火) 22:52:53
>>636

while read word
do
echo -n "$word "
case $word in [1-9]*) echo;; esac
done < L1
0640名無しさん@お腹いっぱい。2006/03/14(火) 23:02:21
>638
すうじがきたら改行
0641名無しさん@お腹いっぱい。2006/03/14(火) 23:04:08
質問です。

for name in hoge hage
{
 echo $name
}

↑みたいな書き方は bash依存ですか?
なんか、Solarisの/bin/shでも動いてしまうんですけど、
manには記述がありません。(do doneの記述のみ)
0642名無しさん@お腹いっぱい。2006/03/14(火) 23:06:37
cat L1 | tr -d "\n" | sed 's/([0-9]+)[^0-9]/\1\n/g'
0643名無しさん@お腹いっぱい。2006/03/14(火) 23:11:23
>>642
お約束の突っ込み。「catが無駄です」

>>637 >>639 >>642 の中では、外部コマンドを使っていない
>>639 が一番エレガントだな。

あ、>>642って、数字以外のの入力がスペースなしでくっついてしまうんじゃないか?
0644名無しさん@お腹いっぱい。2006/03/14(火) 23:20:08
じゃあついでに

$cat L1
111
222
333
a
444
555
b

これを
$cat L1
111 444
222 555
333 b
a
に変換する方法教えて
0645名無しさん@お腹いっぱい。2006/03/14(火) 23:20:10
>>641
POSIXの仕様によれば、{}は()と同じくcompound-listを構成することができる。
で、for文は"The for loop requires that the reserved words do and done
be used to delimit the sequence of commands"と書いてあって、
「do/doneをつかわなければならない」のかはちょっとわからない。
0646名無しさん@お腹いっぱい。2006/03/14(火) 23:20:29
>>639は行末に余分な空白。
case内で処理した方がいい。
0647名無しさん@お腹いっぱい。2006/03/14(火) 23:29:41
>>645
do doneの代用としての { } と、
compound-list の { } は違うしなぁ。
すると、Solarisとかで forで { } が使えてしまうのって
一種の隠しコマンドみたいなもの?
0648名無しさん@お腹いっぱい。2006/03/14(火) 23:34:12
>>644
それはjoin一発じゃないか?

>>639
数字の後にスペースはいっちゃわね?
0649名無しさん@お腹いっぱい。2006/03/14(火) 23:35:50
>>644
while read word1; do read word2; echo $word1 $word2; done

1行で桶。
0650名無しさん@お腹いっぱい。2006/03/14(火) 23:37:01
>>649
問題欲嫁。
0651642 2006/03/14(火) 23:42:52
じゃ
sed 's/$/ /g' L1 | tr -d "\n" | sed 's/([0-9]+)[^0-9]/\1\n/g' とか。


>>644 はColumnとか使えそう。使ったこと無いので詳しくはまんまん。
0652名無しさん@お腹いっぱい。2006/03/14(火) 23:44:28
>>648
joinじゃ無理じゃない? フィールド一致を見てしまうから。
0653642 2006/03/15(水) 00:09:38
>>644
column -c 20 L1
とかだった。
0654sage2006/03/15(水) 00:16:10
>>652
>>648 はたぶん paste のことを言いたいのだろう
0655名無しさん@お腹いっぱい。2006/03/15(水) 00:49:50
本当にレベル低いなぁ。ここの回答者たちって本業は何?
0656名無しさん@お腹いっぱい。2006/03/15(水) 01:38:18
粘土屋
0657名無しさん@お腹いっぱい。2006/03/15(水) 02:17:30
>>655
馬鹿学生。

とりあえず何ができればレベルが上がったと
定義するのか説明してくれ。
0658名無しさん@お腹いっぱい。2006/03/15(水) 02:19:58
スライムを一撃で倒す。
0659名無しさん@お腹いっぱい。2006/03/15(水) 04:17:58
回答する側に立つなら、
sed一つで済むところを3つもプロセス使うなんて馬鹿げたことはやめてくれよな。
0660名無しさん@お腹いっぱい。2006/03/15(水) 09:28:26
>>657
俺が決める
0661名無しさん@お腹いっぱい。2006/03/15(水) 10:45:13
>>658
お前、スライム一匹にイオナズン使うタイプだろ。
0662名無しさん@お腹いっぱい。2006/03/15(水) 10:54:20
もういいからぜんぶ機械語で書け。
アセンブラ? なに軟弱なことを言ってんの?
0663名無しさん@お腹いっぱい。2006/03/15(水) 11:41:00
なんで厨房はすぐ機械語とかアセンブル言語とか言うんだろう
ハッカーぽい響きがあるせいか?
0664名無しさん@お腹いっぱい。2006/03/15(水) 11:49:32
レベルが高い回答が来ないからレベルが低くなる。

というわけで、レベルが低い、といっている人はどーぞ、そのレベルの高さを示してください。
そのレベルの低さを示すのが関の山だと思うけど(w
0665名無しさん@お腹いっぱい。2006/03/15(水) 12:11:16
機械語?レベル低杉
0666名無しさん@お腹いっぱい。2006/03/15(水) 12:12:41
>>665
レベルの意味が違いすぎ
0667名無しさん@お腹いっぱい。2006/03/15(水) 14:00:21
この程度でプロセスの数とか言ってるバカはどっかいけよ
0668名無しさん@お腹いっぱい。2006/03/15(水) 14:09:23
程度問題じゃなくて、シェル内部コマンドだけでできる奇麗な解があるのに、
あとから外部コマンド(sed/tr)を複数使った解を出してきても
エレガントではない。
0669名無しさん@お腹いっぱい。2006/03/15(水) 14:11:53
エレガントじゃ食ってけないよ
0670名無しさん@お腹いっぱい。2006/03/15(水) 14:33:13
コマンドに食わせるデータが大量でない限り、プロセスの数は無視して
いいんじゃないか。この程度なら。
0671名無しさん@お腹いっぱい。2006/03/15(水) 15:10:37
ちょwwwおm、あwwwwエレガントwwっw
0672名無しさん@お腹いっぱい。2006/03/15(水) 16:19:54
プロセスの数が少ない = エレガントとは限らんだろ
内部コマンドだけでできればどんなに複雑でもエレガントとか言いはじめるやつとは議論にならんな
0673名無しさん@お腹いっぱい。2006/03/15(水) 17:11:31
そりゃ、食うのがやっとの人にきれいなシェルを期待しちゃダメだな。
0674名無しさん@お腹いっぱい。2006/03/15(水) 17:13:14
>>673
シェルって言うなクズ。
0675名無しさん@お腹いっぱい。2006/03/15(水) 18:05:21
プロセス数とか、外部コマンドとか以前の問題として、
>>651 って動かないわけよ。
sedの中で \( \) とすべきところを ( ) で書いてるから。

動作確認してから書き込むのは最低限の回答者のルールだよ。
確かに、こんなシェル書いてちゃ食えないよな。

(先に言っとくけど「シェルってゆーな」の突っ込みは禁止。そろそろ言葉に慣れろ)
0676名無しさん@お腹いっぱい。2006/03/15(水) 18:06:00
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
シェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェルシェル
0677名無しさん@お腹いっぱい。2006/03/15(水) 18:07:55
そろそろシェルスクリプトって言えるようになれよ。
0678名無しさん@お腹いっぱい。2006/03/15(水) 18:13:52
んー、食わせるデータが大量になると、シェルスクリプトじゃいかんかなと
思うこともあるね。sed,awk,grep,findあたりを良く使いまわすんだけど、
重くてしょうがなくなる。まあ高速化は二の次になっちゃうんだけど、
RubyかPerlあたりのスクリプト言語を使うことを、最初に検討した方がいいかも
知れん。

0679名無しさん@お腹いっぱい。2006/03/15(水) 18:58:31
シェルってゆうな。くず。
0680名無しさん@お腹いっぱい。2006/03/15(水) 19:02:06
カレントディレクトリにある、大文字のファイル名を
すべて小文字のファイル名に直したいのですが、
どういうUNIXを打てばいいでしょうか?
■ このスレッドは過去ログ倉庫に格納されています