シェルスクリプト総合 その7
■ このスレッドは過去ログ倉庫に格納されています
0001ミスターシェル
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 でトレースしましょう。
0742名無しさん@お腹いっぱい。
2007/01/18(木) 10:12:38つ「最長一致」
0743名無しさん@お腹いっぱい。
2007/01/18(木) 10:39:360744名無しさん@お腹いっぱい。
2007/01/18(木) 17:58:56bashでやってみました
#!/bin/bash
OLDHTML=$1
NEWHTML=$2
COMMENT=0
while read LINE
do
while echo $LINE | grep -q '<!--.*-->'
do
PARTLINE=${LINE%%<!--*}
LINE=$PARTLINE${LINE#*-->}
[ ! $LINE ] && continue 2
COMMENT=0
done
if echo $LINE | grep -q '<!--'; then
LINE=${LINE%<!--*}
[ $LINE ] && echo $LINE >> $NEWHTML
COMMENT=1
elif echo $LINE | grep -q '¥-->'; then
LINE=${LINE#*-->}
[ $LINE ] && echo $LINE >> $NEWHTML
COMMENT=0
elif [ $COMMENT -eq 0 ]; then
echo $LINE >> $NEWHTML
fi
done < $OLDHTML
0745名無しさん@お腹いっぱい。
2007/01/18(木) 18:18:42真面目にやるなら、htmlパーサ使っとけってこった。
0746名無しさん@お腹いっぱい。
2007/01/18(木) 18:27:230747名無しさん@お腹いっぱい。
2007/01/18(木) 19:02:080748名無しさん@お腹いっぱい。
2007/01/18(木) 19:07:10たぶんみんな別人だと思うぞ
0749名無しさん@お腹いっぱい。
2007/01/18(木) 21:30:050750吉田
2007/01/18(木) 23:57:28とくに>>744は茶ふいたわ。
>>737のいっているHTMLファイルを仮に、index.htmlというファイルとすると、
cat index.html | awk '/^<!--/,/^-->/ {next} {print}'
こうやればOK。
ばーか!
0751名無しさん@お腹いっぱい。
2007/01/19(金) 00:04:340752名無しさん@お腹いっぱい。
2007/01/19(金) 00:06:250754吉宗
2007/01/19(金) 00:09:270756徳田
2007/01/19(金) 00:14:200757名無しさん@お腹いっぱい。
2007/01/19(金) 00:15:09とりあえずばけらさんとこでも読んどけ
で>>737は本気で回答がほしければ
全ての形式のHTMLコメントを除去したいのか
>>737の形式のコメントを除去したいのか補足しろ
ってことでしょ
前者ならシェルスクリプト向きじゃないけど
0760名無しさん@お腹いっぱい。
2007/01/19(金) 00:27:54で、>>757はどっちなんだ?
0761名無しさん@お腹いっぱい。
2007/01/19(金) 17:31:080762名無しさん@お腹いっぱい。
2007/01/19(金) 19:32:180763名無しさん@お腹いっぱい。
2007/01/25(木) 13:51:51起動する前に好きなウィンドウマネージャを選べるようにコードを追加したいのですが、
どのようにすればいいのでしょうか?
0764名無しさん@お腹いっぱい。
2007/01/25(木) 13:56:32gdm でも使ったら?
0765名無しさん@お腹いっぱい。
2007/01/25(木) 14:01:490766名無しさん@お腹いっぱい。
2007/01/25(木) 14:05:12何がおすすめ?
0767名無しさん@お腹いっぱい。
2007/01/25(木) 14:07:200768名無しさん@お腹いっぱい。
2007/01/25(木) 14:12:47その理由は?
0769名無しさん@お腹いっぱい。
2007/01/25(木) 14:14:240770名無しさん@お腹いっぱい。
2007/01/25(木) 14:15:47wm 選べたっけ。
0771名無しさん@お腹いっぱい。
2007/01/25(木) 14:22:09xmessage のような物でも使って問い合わせるとかかな
0772名無しさん@お腹いっぱい。
2007/01/25(木) 14:26:51xdialog
0773名無しさん@お腹いっぱい。
2007/01/26(金) 01:27:22俺は$WMで分岐してる
case ${WM:-wmaker} in
wmaker) ... ;;
gnome) ... ;;
kde) ... ;;
*) ... ;;
esac
0774名無しさん@お腹いっぱい。
2007/01/26(金) 09:03:200775名無しさん@お腹いっぱい。
2007/01/26(金) 13:49:370776名無しさん@お腹いっぱい。
2007/01/26(金) 13:59:340777名無しさん@お腹いっぱい。
2007/01/26(金) 14:00:160778名無しさん@お腹いっぱい。
2007/01/26(金) 14:06:56その理由は?
0779名無しさん@お腹いっぱい。
2007/01/26(金) 14:11:340780名無しさん@お腹いっぱい。
2007/01/26(金) 17:33:130781名無しさん@お腹いっぱい。
2007/01/26(金) 17:38:480782名無しさん@お腹いっぱい。
2007/01/28(日) 05:14:10の中で、「20以上である」という条件を満たしたものが
いくつあるのかを数えたいです。
例えば、変数$listの中身が
10.4
30.2
15.4
5.2
20.2
だった場合には、答えは2と出るようにしたいのです。
n=1
sum=0
while [ $n -le 5 ]
do
s=`echo "$list" | sed -n "$n p"`
y=`trunc("$s")`
if test "$y" -ge 20
then sum=`echo "scale=0; $sum + 1" | bc`
else
exit 1
fi
n=`expr $n + 1`
done
echo $sum
0783782
2007/01/28(日) 05:15:34エラーになります。
変数$sに数値がひとつひとつ代入されて行くのは確認できたのですが、
小数点を切り捨てるためのtruncコマンドのところでエラーになります。
command substitution: line 1: syntax error near unexpected token `"$s"'
command substitution: line 1: `trunc("$s")'
どこがおかしいのか教えていただけませんか?
0784名無しさん@お腹いっぱい。
2007/01/28(日) 06:18:110785名無しさん@お腹いっぱい。
2007/01/28(日) 06:47:50というか、小数扱うなら awk 使っとけ
0786名無しさん@お腹いっぱい。
2007/01/28(日) 09:00:04nn=0; for aa in $list; do if [ ${aa%.*} -ge 20 ]; then nn=$((nn + 1)); fi; done; echo $nn;
0787名無しさん@お腹いっぱい。
2007/01/28(日) 09:14:300788782
2007/01/28(日) 09:15:01>>785
man truncしたらこんなのが出てきましたが。
つまり、truncはたぶんtrunc(数字)とかいう形で使うのかな、
と思ったのです。実際trunc "数字"ではうまくいきませんでした。
しかし、trunc()の形にしたところで
$ trunc(23.4)
-bash: syntax error near unexpected token `23.4'
こんな感じでエラーになり、たぶん正しい文法になっていないのが
ネックになっているような雰囲気です。
NAME
trunc -- truncate to integer value
SYNOPSIS
#include <math.h>
double
trunc(double x);
long double
truncl(long double x);
float
truncf(float x);
DESCRIPTION
The trunc() functions return the integral value nearest to but no larger
in magnitude than x.
SPECIAL VALUES
trunc(+-0) returns +-0.
trunc(+-infinity) returns +-infinity.
SEE ALSO
ceil(3), rint(3), math(3)
STANDARDS
The trunc() functions conform to ISO/IEC 9899:1999(E).
BSD January 29, 2003 BSD
0789782
2007/01/28(日) 09:19:35ありがとうございます。
これはなんの言語でしょうか。これがawk?
実際にこれでやってみましたがうまくいきません。
そもそも
${aa%.*}
この意味がわかりません。
けど、これを使うとtruncを使わずに済むので
便利そうですね。
いろいろと勉強してみます。
>>787
今はたまたまbashの勉強をしているので、
別にbashに依存しているわけではありません。
excelとか使った方が速いのはわかってますが、
無理やりbashでやろうとすることで
「 ( ・∀・)つ〃∩ ヘェーヘェーヘェー truncなんて関数があるんだ!」
という発見があるので、おもしろいのですよw
0790名無しさん@お腹いっぱい。
2007/01/28(日) 09:30:330791名無しさん@お腹いっぱい。
2007/01/28(日) 10:23:58それ、マニュアルページの一番上に trunc(3) て書いてるんじゃない?
マニュアルのセクション3は、Cのライブラリ関数。
0792782
2007/01/28(日) 17:54:08!!!!
全くその通りです!
bashでは使えないのですね・・・orz
bashの中でCのライブラリ関数を使う方法か、
他に小数点切り捨てによい方法はありませんか?
0793名無しさん@お腹いっぱい。
2007/01/28(日) 22:07:050794名無しさん@お腹いっぱい。
2007/01/28(日) 22:17:42[ は切り捨てないと使えないyo
0795名無しさん@お腹いっぱい。
2007/01/28(日) 22:32:23本当にbash使ってるなら、>>786 で合ってるよ。awkは関係ない。
これ自体がbashのスクリプト。
bashじゃない普通の shでも動くように >>786 を書き直してみた。
↓ (ちなみに俺は >>786 とは別人)
nn=0
for aa in $list
do
if [ `expr $aa : '\(.*\)\..*'` -ge 20 ]; then
nn=`expr $nn + 1`
fi
done
echo $nn
0796名無しさん@お腹いっぱい。
2007/01/28(日) 22:34:340797名無しさん@お腹いっぱい。
2007/01/29(月) 14:38:20ttp://x68000.q-e-d.net/~68user/unix/pickup?iconv
> 入力ファイルに無効な文字 (-f で指定した文字コードと矛盾するようなデータ) が
> 含まれていた場合、iconv はエラーとして終了する。FreeBSD の iconv では
> -c オプションを指定することで、無効な文字を無視して無視して続行することができる。
> 他の iconv では必ずエラーで終了してしまうようだ。
Linux で、変な文字を無視しつつ文字コードの変換をしたいときにはどうするのがベストでしょうか。
(個人的に馴染のある言語の) php で iconv//IGNORE をする、という手は思いついたのですが。
0798名無しさん@お腹いっぱい。
2007/01/29(月) 14:50:35Linuxでどうするのかを聞くなら
Linux板がいいでしょう。
0799782
2007/01/29(月) 21:06:29か、神!!!!
おかげさまでついにできました!
実はやりたかったことは、
「猛暑日(最高気温が35度以上の日)が2006年8月に何日あったか」
を各都市ごとに数えてみたかったのです。
そうすれば、熊本、佐賀、京都がいかに暑いところか
理解してもらえるかなと思って。
こんな感じでできました!!
ttp://sheel.mydns.jp/~sheel/moushobilastaugust.shtml
bashスクリプトファイルはここに置いておきますのね。
ttp://sheel.mydns.jp/~sheel/moushobilastaugust.sh
またいろいろと教えてください。by 皮先くん
0800782
2007/01/29(月) 21:09:19ちなみにshtmlの方は、12個の都市について
その場で気象庁からデータをとりにいって解析するので
クリックしてから表示されるまで1分弱ほど時間がかかりますので
辛抱強くお待ちくださいね。
0801名無しさん@お腹いっぱい。
2007/01/30(火) 09:09:26なかなかおもしろいね。
色々応用が利きそう。
0802名無しさん@お腹いっぱい。
2007/01/31(水) 09:39:22まだやってたんだね。
Mac板でのやりとりがなつかしいぜ…
0803782
2007/01/31(水) 16:57:2413の都市について気象庁から一気にデータを取得して
自動計算するシェルスクリプトもつくってみました。
<13の都市とは>
東京、大阪、京都、静岡、浜松、
熊本、鹿児島、枕崎、福岡、佐賀、大分、宮崎、長崎
「冬日が何日あったかを計算して表示する」
(13の都市のデータを取得するため1分弱ほど時間がかかります)
ttp://sheel.mydns.jp/~sheel/fuyubi200701.shtml
ソースはこちらです。
ttp://sheel.mydns.jp/~sheel/fuyubi200701.sh
0804名無しさん@お腹いっぱい。
2007/02/01(木) 12:23:44オレも気付いた
のでスルーしといた
0805名無しさん@お腹いっぱい。
2007/02/01(木) 14:41:450806名無しさん@お腹いっぱい。
2007/02/01(木) 21:39:01俺も気がついた
ので教えてやった。
皮先のスクリプトはよく利用させてもらってて重宝してるし。
0807名無しさん@お腹いっぱい。
2007/02/02(金) 20:25:38remsh $リモホ名 -n "find $ディレクトリ名 -type d -name $ディレクトリ名 -print"
で値が取得できるかどうかでディレクトリがあるかチェックしようと思っているのですが
もうちょっとスマートなやりかたがありますでしょうか?・・
0808名無しさん@お腹いっぱい。
2007/02/02(金) 20:30:160809名無しさん@お腹いっぱい。
2007/02/03(土) 16:34:40花子 83
裕子 98
尚美 91
という生徒のテストの点数を記載したデータがあったとき、
これを点数の高い順番でソートしたいのですが、
いろいろ調べるとawkがこういうのを得意にしているような気がしました。
この処理を簡単に行うにはawkが最も適していますか?
他に適している言語はありますか?
といいますのも、awkについて調べてみたのですが、
点数を加算する、とかはわかったのですが
点数の高い順番でソート、は無理なような気がしましたので・・・。
awkが最も適している、ということであればもうちょっとがんばってみたいと思いますが。
0810名無しさん@お腹いっぱい。
2007/02/03(土) 16:53:29ソートはsortでいいじゃん。
キーとするフィールド位置の指定だとか、アルファベット順じゃなく数の大小でのソートだとか、
そういうオプションもあるので、後はsortのmanみてみるとよいです。
0811名無しさん@お腹いっぱい。
2007/02/03(土) 16:54:590812809
2007/02/03(土) 18:17:50>>811
sort!!!!!
そ、そんな普段から自分でもよく使ってるやつで可能だったんですね!
さっそく>>811さんのようにやってみたらうまくいきました!
ありがとうございました。
0813名無しさん@お腹いっぱい。
2007/02/03(土) 18:31:44>>out.txt
を使ってどんどんファイルに書き加えていくのはわかりました。
では、ファイルに出力するのではなく、
(変数として?)メモリ上に出力していく方法はありますか?
例えば、
1回目の繰り返し文によって、変数$ssの値が5になりました。
変数$yyの中身は
5
となりました。
2回目の繰り返し文によって、変数$ssの値が2になったので、
変数$yyの中身は
5
2
となりました。
3回目の繰り返し文によって、変数$ssの値が7になったので
変数$yyの中身は
5
2
7
となりました。
こんな$ssに対して$yyのように出力が可能な方法はありますか?
0814名無しさん@お腹いっぱい。
2007/02/03(土) 18:39:33# ...
yy="$yy
$sss"
# ...
done
echo "$yy"
単純にこうやるとyyの中身の1行目に空の行が出来ちゃうから、
yyが空かどうかチェックしたほうがいいか。
0815名無しさん@お腹いっぱい。
2007/02/03(土) 18:48:28while ...; do
set "$@" "$yy"
done
for a in "$@";do
echo "$a"
done
0816しまった
2007/02/03(土) 18:50:23while ...; do
set "$@" "$yy"
done
for a in "$@";do
echo "$a"
done
0817名無しさん@お腹いっぱい。
2007/02/03(土) 19:04:22なるほど。言われてみると簡単ですね・・・。
実際に自分でやってみたら、確かにできました。
最初の空白行は
yyが殻かどうかチェックするより
最後にsedとかで削除した方が簡単なのでそうしようと思います。
sed '/^$/d'
これをパイプしようと思います。
ありがとうございました。
>>815
よく意味がわからないのですが、
とりあえず814さんの方法でできましたので
お気持ちだけいただいておきます。
ありがとうございました。
0818名無しさん@お腹いっぱい。
2007/02/03(土) 19:21:52それら全体である$@をループで回すことで取り出してる。
0819名無しさん@お腹いっぱい。
2007/02/03(土) 19:35:54なるほど、意味がわかりました!
ありがとうございます。
0820名無しさん@お腹いっぱい。
2007/02/03(土) 19:49:44太郎 84 25
花子 83 21
裕子 98 24
尚美 91 23
冬美 84 21
このように名前 点数 出席日数があったとき、
第一ソートは点数で、第二ソートは出席日数でソートし、
裕子 98 24
尚美 91 23
太郎 84 25
冬美 84 21
花子 83 21
こういうふうに出力したいのですが、
$echo test.txt | sort +2 -nr | sort +1 -nr
こうして二段階のsortでいいのかな?と思ったけど、
むしろ必ず
冬美 84 21
太郎 84 25
と、逆になってしまいます。そこで、
$echo test.txt | sort +2 -n | sort +1 -nr
-rオプションを外してやってみても同じ結果でした・・・orz
なにか別のコツなどがあるのでしょうか?
0821名無しさん@お腹いっぱい。
2007/02/03(土) 19:51:090822820
2007/02/03(土) 20:08:12sortは一度に複数のオプションを指定可能なので
第1フィールドを昇順でソートし、
第2フィールドは降順でソート、
ということが可能のようです。
この場合、具体的には以下のようにします。
$echo "text.txt" | sort +1nr +2n
ちなみに>>819のようなことがやりたい場合は
$echo "text.txt" | sort +1nr +2nr
ですね。
参考
ttp://biking.taiiku.tsukuba.ac.jp/~takai/Unix/Unix-text.html
0823名無しさん@お腹いっぱい。
2007/02/03(土) 20:12:13というか、cat使うと「catイラナイ」と言われるけどさ。
0824名無しさん@お腹いっぱい。
2007/02/03(土) 20:13:370825名無しさん@お腹いっぱい。
2007/02/03(土) 20:17:100826820
2007/02/03(土) 20:19:07あ・・・、マジでごめソ・・・orz
cat text.txt
が正解。
というか初心者がパイプを覚えるには最も分かりやすい例だと思うけどね。
cat hoge.txt | sort
0827名無しさん@お腹いっぱい。
2007/02/03(土) 20:23:030828名無しさん@お腹いっぱい。
2007/02/03(土) 20:25:490829名無しさん@お腹いっぱい。
2007/02/03(土) 20:27:31べつにそういう使いかた教えたせいじゃないだろう
0830820
2007/02/03(土) 21:14:27「全国の都道府県庁所在地の中で
2007年1月に冬日が多かった順に並び替えます」
その結果です。
http://sheel.mydns.jp/~sheel/fuyubikencho0701.txt
スクリプトはこちらです。
http://sheel.mydns.jp/~sheel/fuyubikencho0701.sh
「全国の都道府県庁所在地の中で
2006年8月に猛暑日が多かった順に並び替えます」
その結果です。
http://sheel.mydns.jp/~sheel/moushobikencho0608.txt
スクリプトはこちらです。
http://sheel.mydns.jp/~sheel/moushobikencho0608.sh
これを見ると、
佐賀、熊本、京都、名古屋は
夏場は日本一暑い割に冬場も不相応に寒いことがわかりますね。
0831名無しさん@お腹いっぱい。
2007/02/04(日) 01:24:10変数$hogeaと変数$hogebを連結しようと思います。
$hogeaの中身は
1
3
5
4
8
7
3
$hogebの中身は
1023
1032
1001
1002
1003
1009
1018
これをこんなふうにしたいのですが、
1 1023
3 1032
5 1001
4 1002
8 1003
7 1009
3 1018
ちょっと勉強して感じではよくわかりませんでした。
もうちょっと勉強してみます。
0832名無しさん@お腹いっぱい。
2007/02/04(日) 03:20:350833831
2007/02/04(日) 04:33:44できました!!!
変数が20個くらいあったのですが、
echo "$hogehoge1" | paste file1.txt - >file2.txt
echo "$hogehoge2" | paste file2.txt - >file3.txt
・・・・・
echo "$hogehoge20" | paste file20.txt - >out.txt
とやることでなんとかなりました。
これが47x12x47=26,508回繰り返さないと行けない処理で、
ハードディスクは痛めつけるますがこれ一回だけやればいいので
これでがまんすることにします。
もっとメモリ内のみで済む方法ってないんでしょうね・・・。
0834名無しさん@お腹いっぱい。
2007/02/04(日) 07:57:230835名無しさん@お腹いっぱい。
2007/02/04(日) 07:58:300836名無しさん@お腹いっぱい。
2007/02/04(日) 16:11:520837831
2007/02/04(日) 19:45:16例えばどういう方法がありますか?
わたしがやりたいのは、
気象庁のWebサイトから各都道府県庁所在地の
1961年以降の毎日のデータを2007年1月まで
一気に取得し、
例えば2007年1月の熊本(47814)のデータを
あとでとりだしやすいように加工した後に
「20070147814」
というファイル名で保存していく、ということです。
今朝から一括ダウンロードを始めましたがまだまだ終わりそうにありません。
24時間くらいかかりそうです・・・orz
こういう一回だけやれば済む使い捨てスクリプトをかくのに
シェルスクリプト以外になにかいい方法がありますか?
0838831
2007/02/04(日) 19:59:03シェルスクリプトはこんな感じ。
ttp://sheel.mydns.jp/~sheel/alldataget.sh.txt
使い捨てだね。
そのダウンロードの結果が例えばこれ。
ttp://sheel.mydns.jp/~sheel/19920147819.txt
2年ほど前もこのスレで言われてたんだけど、
毎回毎回気象庁にデータを取りに行くより
一回だけ一括ダウンロードしておいて
ローカルで参照した方がスクリプト自体も高速化する、ってことと
自分自身が一括ダウンロードをするだけのスキルが可能になったので
ついに念願の一括ダウンロードをやっています。
試しにダウンロードが終わった部分だけで
ある連続した5年間の1月の47都市の冬日の日数の平均値を計算し
その平均値の大きい順に並べ替えてみました。
こういうのをダウンロードでやろうとすると小一時間以上?かかるのだけど
ローカルに保存しておくと1〜2分くらいで終わりますね。
0839名無しさん@お腹いっぱい。
2007/02/04(日) 20:17:39PerlやRubyは考慮しないのかな、ということではないかと。
シェルスクリプトにはパズル的なおもしろさはあるけど、
若干の無理矢理感はあるし、外部コマンド使いまくりでモタモタするし。
0840831
2007/02/04(日) 20:36:39なるほど。
モタモタして時間がかかるのは確かだしね。
つか、俺的にはPerlもRubyもシェルスクリプトの1コマンド、という認識。
Rubyはよく知らんけど
Perlはシェルスクリプトと比べて意味がわかりづらいので
なかなか重い腰が上がらないんだよね。
あと、こういうデータを元にして動的なWebコンテンツをつくるには
やっぱphpでつか?
0841名無しさん@お腹いっぱい。
2007/02/04(日) 20:52:56なんでもええよ。
シェルスクリプトでもいいし。
ある程度アクセス数が多くなるなら、シェルスクリプトではきついけどね。
■ このスレッドは過去ログ倉庫に格納されています