シェルスクリプト総合 その6
■ このスレッドは過去ログ倉庫に格納されています
0001うはwwwww
2006/03/26(日) 00:56:22スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>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 でトレースしましょう。
0755名無しさん@お腹いっぱい。
2006/07/14(金) 10:26:45サブシェルも知らんのか。
(unset LANG LC_TIME LC_ALL; ls)
0756名無しさん@お腹いっぱい。
2006/07/14(金) 10:36:15当然知っている。知らなかったのは>>753
0757名無しさん@お腹いっぱい。
2006/07/14(金) 10:41:21当然知ってる割には反応が遅かったな。
>>755 見てから「サブシェル」でググったのかい?
>>753 だってサブシェルは知ってると思われ。
当たり前のことは必要なければ省略するから。
たとえば、unset LANG LC_TIME LC_ALL; ls だけの1行で
シェルスクリプトが終るなら、実行後には影響出ないし。
0758名無しさん@お腹いっぱい。
2006/07/14(金) 10:57:05はいはい、後付の言い訳惨め。
0759名無しさん@お腹いっぱい。
2006/07/14(金) 11:01:11後付の言い訳は >>756 = >>754
0760名無しさん@お腹いっぱい。
2006/07/14(金) 11:10:030761名無しさん@お腹いっぱい。
2006/07/14(金) 11:26:131行シェルスクリプトなら、あとexec付けた方がいい。
↓
unset LANG LC_TIME LC_ALL; exec ls -l
0762名無しさん@お腹いっぱい。
2006/07/14(金) 17:18:12必死だな、落第男。www
0763名無しさん@お腹いっぱい。
2006/07/14(金) 19:16:580764名無しさん@お腹いっぱい。
2006/07/14(金) 19:52:00秒単位がわからないとかいう問題の方が大きいな。
ls -l --full-time や ls -T はポータブルじゃないし。
0765名無しさん@お腹いっぱい。
2006/07/14(金) 20:05:01diff -c /dev/null /path/to/file | sed -n 2p
0766名無しさん@お腹いっぱい。
2006/07/14(金) 20:10:25残念だな。テキストファイルだとそれでいいが、
/path/to/file がバイナリファイルだと、diffが拒否するんだよ。
0767名無しさん@お腹いっぱい。
2006/07/14(金) 20:28:30↓
case `uname -s` in
Linux) ls -l --full-time;;
*BSD) ls -T;;
SunOS) ls -e;;
esac
--full-timeの場合は LANG=ja_JP.eucJPでも関係ないみたい。
0768名無しさん@お腹いっぱい。
2006/07/14(金) 20:32:140769名無しさん@お腹いっぱい。
2006/07/14(金) 20:36:30diff -ca にしても問題が4つある。
(1) diff -a オプション自体がポータブルじゃない
(2) 対象ファイルがディレクトリ自体だと動作しない
(3) 対象ファイルが自分のパーミッションで読めないと動作しない
(4) 対象ファイルの中身を読み出してしまうので atimeが変わってしまう
0770名無しさん@お腹いっぱい。
2006/07/14(金) 21:37:280771名無しさん@お腹いっぱい。
2006/07/19(水) 22:02:53bash で↓こんな関数を作ったのですが、
Cygwin なのでディレクトリ名にスペースが入って
select のところがうまくいかなくなってしまいます。
いい書き方はないでしょうか?
function addbm() {
pwd >> ~/.dirbookmark
}
function bm() {
select dir in `cat ~/.dirbookmark`
do
cd $dir
break
done
}
0772名無しさん@お腹いっぱい。
2006/07/19(水) 22:06:25ダブルクォートしる!
"`cat ~/.dirbookmark`"
bashなら catは省略できて、
↓でも桶。
"`< ~/.dirbookmark`"
0773名無しさん@お腹いっぱい。
2006/07/19(水) 22:09:25ダブルクォートだとファイル中の複数行が全部つながって解釈されるだろ。
↓が正解。IFSのあとにシングルクォートした改行コードね。
IFS='
'
0775名無しさん@お腹いっぱい。
2006/07/21(金) 22:14:31と最近言えなくて少し寂しい。
0776名無しさん@お腹いっぱい。
2006/07/21(金) 22:33:070777名無しさん@お腹いっぱい。
2006/07/21(金) 22:49:322. 出力にはファイル名:行番号がついてほしい
3. ハイフンで始まる引数はすべてgrepに渡される
の条件を満たすスクリプトが欲しいんですが、
簡単に作ることは可能でしょうか?
0778名無しさん@お腹いっぱい。
2006/07/21(金) 23:01:222の、 出力にファイル名:行番号を付ける処理がちょっと面倒だけど、
「可能か?」という質問なら「可能」
0779名無しさん@お腹いっぱい。
2006/07/21(金) 23:25:45テストとかは自分でやってくれ。
#! /bin/sh
while [ $# -gt 0 ] ; do
case "$1" in
-*)
opt="$opt $1"
shift
;;
*)
break
;;
esac
done
nkf -e $* | grep -n -H $opt
0780名無しさん@お腹いっぱい。
2006/07/21(金) 23:32:11-n とか -H を grep につけた意味が無いな。
>>778 の面倒ってそういう事か。
確かにできなくはないけど >>779 に
2、3 行足すくらいじゃ出来そうもないな。
0781名無しさん@お腹いっぱい。
2006/07/21(金) 23:32:51それだと grepが標準入力から読んじゃうから、
ファイル名の表示ができない。
それでいいなら問題ないし、もっと簡単に書ける。
>>778 が言うように、ファイル名:行番号を付ける処理のところが面倒。
0782名無しさん@お腹いっぱい。
2006/07/22(土) 00:11:300783名無しさん@お腹いっぱい。
2006/07/22(土) 00:15:17case "$i" in
-*) arg="$arg $i";;
*) files="$files $i";;
esac
for f in $files; do
nkf -e $f | grep -Hn $args
done
ちゃんと動くかどうかは知らね。
0784名無しさん@お腹いっぱい。
2006/07/22(土) 00:16:360785名無しさん@お腹いっぱい。
2006/07/22(土) 00:20:55- nkf -e $f | grep -Hn $args
+ nkf -e $f | grep -n $arg | sed "s;^;$f:;"
0786名無しさん@お腹いっぱい。
2006/07/22(土) 05:08:000787名無しさん@お腹いっぱい。
2006/07/22(土) 08:14:19内部コマンドの getoptsの方がモアベター。
0788777
2006/07/22(土) 10:04:37↓こんな感じになりました。
これだとまだ
・grep の「-e パターン」という指定方法ができない
・スペースを含むファイル名を正しく扱えない
という問題がありますが。
getopt を使えば解決できますかね?
#!/bin/sh
for i in "$@"; do
case "$i" in
-*) arg="$arg $i";;
*) if [ "$pattern" = "" ]; then
pattern="$i"
else
files="$files $i"
fi
;;
esac
done
#echo "pattern="$pattern
#echo "files="$files
#echo "arg="$arg
for f in $files; do
nkf -e "$f" | grep -n $arg "$pattern" | sed "s;^;$f:;"
done
0789名無しさん@お腹いっぱい。
2006/07/22(土) 14:19:04それだけ愛に飢えているのか?
0790名無しさん@お腹いっぱい。
2006/07/22(土) 15:03:150791名無しさん@お腹いっぱい。
2006/07/22(土) 19:01:410792名無しさん@お腹いっぱい。
2006/07/23(日) 01:12:30季節の話題、今日の暦、今日は何の日
をプレーンテキストで取り出してメールで送るようにしたいんですが
どうすればいいでしょう。
w3mかcurlでページを取得してsedを使って必要な分を取り出してmailで送るのをcronすれば
いいんですよね
0793名無しさん@お腹いっぱい。
2006/07/23(日) 01:26:070794名無しさん@お腹いっぱい。
2006/07/23(日) 09:50:43漏れだったら、perlで全部処理するけどな。LWPモジュール+Socketモジュール+cron
0795名無しさん@お腹いっぱい。
2006/07/23(日) 10:19:060796名無しさん@お腹いっぱい。
2006/07/23(日) 10:46:560797名無しさん@お腹いっぱい。
2006/07/23(日) 12:34:510798名無しさん@お腹いっぱい。
2006/07/23(日) 12:43:070799名無しさん@お腹いっぱい。
2006/07/23(日) 12:47:140800名無しさん@お腹いっぱい。
2006/07/23(日) 12:47:38perlしか知らない厨が不安になって自己弁明するために「俺ならperlでやる」みたいな
カキコするのいいかげんやめれ。
0801名無しさん@お腹いっぱい。
2006/07/23(日) 12:50:570802名無しさん@お腹いっぱい。
2006/07/23(日) 12:53:040803名無しさん@お腹いっぱい。
2006/07/23(日) 13:04:11「お前にはシェルではできない」だな。
0804名無しさん@お腹いっぱい。
2006/07/23(日) 13:14:550805名無しさん@お腹いっぱい。
2006/07/23(日) 13:19:120806名無しさん@お腹いっぱい。
2006/07/23(日) 13:22:570807名無しさん@お腹いっぱい。
2006/07/23(日) 13:24:31>>795 に書いてあるのが見えないのか?
>>806
誰もageてないわけだが…?
0808名無しさん@お腹いっぱい。
2006/07/23(日) 13:37:020809名無しさん@お腹いっぱい。
2006/07/23(日) 15:22:00久しぶりに言えて良かったねw
0810名無しさん@お腹いっぱい。
2006/07/23(日) 16:11:250811名無しさん@お腹いっぱい。
2006/07/23(日) 16:34:220812名無しさん@お腹いっぱい。
2006/07/23(日) 16:42:180813名無しさん@お腹いっぱい。
2006/07/23(日) 16:56:320814名無しさん@お腹いっぱい。
2006/07/23(日) 16:57:19----------------
1 あああ
2 てすと
3 <html>
4 おちんぽ
5 あへあへ
6 ぶりぶりー</html>
7 あげあげ
8 ふとったーt
----------------
<html>〜</html> の間だけ抜き出したいんですがどうやったらええんでしょうか。
それぞれ行は可変です。
\nを削除してしまって一行にして、sedで s/.*<html>.*</html>/\1/g みたいなのとかは思いつくんですが
イマイチ美しゅうないと思うとります。
マッチする行数をゲッツ出来れば、tail&headでがっつり抜き出せそうなんですが、
行番号をゲッツする方法が分かりませぬ。
エロ胃人お願いします
0815名無しさん@お腹いっぱい。
2006/07/23(日) 17:02:54\nを削除しなくても、↓でできるよ。
sed -n '/<html>/,/<\/html>/p'
ただしこれだと<html>や</html>と同じ行のタグ外の部分も出てくるから、
あとsedの置換で<html>より左の部分と</html>より右の部分を削除すれば良い。
0816名無しさん@お腹いっぱい。
2006/07/23(日) 17:30:33ありがとおおおおお
と言うことでドブの素人の俺様が作ってみました
url='http://ja.wikipedia.org/wiki/%E3%83%A1%E3%82%A4%E3%83%B3%E3%83%9A%E3%83%BC%E3%82%B8'
rm temp.html
wget -nv --output-document=temp.html $url
sed -n '/今日は何の日/,/訃報/p' temp.html | sed 's/<[^>]*>//g'
今日はこれくらいで勘弁してください>>792
0817名無しさん@お腹いっぱい。
2006/07/23(日) 20:26:090818名無しさん@お腹いっぱい。
2006/07/23(日) 20:57:24# /usr/bin/printf "%.1s" $(cat file) | wc -c
わかれば教えてください。
一連、動作なんですが、特に書式指定子の.(ドット)の意味がわからないです。
0819名無しさん@お腹いっぱい。
2006/07/23(日) 23:32:36man printf
info printf
0820名無しさん@お腹いっぱい。
2006/07/23(日) 23:33:470821名無しさん@お腹いっぱい。
2006/07/23(日) 23:34:16それだとなんか英語のようなものが表示され、(END)のところでハングたので、
パソコンをリセットしてしまいました。
0822名無しさん@お腹いっぱい。
2006/07/23(日) 23:52:040823名無しさん@お腹いっぱい。
2006/07/24(月) 22:52:41ありがとうございます。
コマンド実行結果は、1 or 2 のどちらが正しいのでしょうか?
0824名無しさん@お腹いっぱい。
2006/07/25(火) 08:30:20オレの環境では、マンド実行結果は 0になる。
0825名無しさん@お腹いっぱい。
2006/07/25(火) 16:35:46私にshellを作れといわれて苦労している45才です。教えてください。
問題が、日付を手入力したときに正常な日付かどうかと、うるう年の計算
方法です。たとえば20051313はエラーですが20060220は正常ですよね。そのときに
曜日も表示したいのでやり方をすいませんがはじめから詳しく教えてください。
すいませんが、お願いします。
0826名無しさん@お腹いっぱい。
2006/07/25(火) 16:42:210827名無しさん@お腹いっぱい。
2006/07/25(火) 16:45:460828名無しさん@お腹いっぱい。
2006/07/25(火) 16:59:350829名無しさん@お腹いっぱい。
2006/07/25(火) 19:39:01シェルスクリプトで日付計算やってるのを数箇所で見て、げんなり。
どうしてもやりたいなら自前で演算するんじゃなくて、
ダミーファイルをtouchするとか、外部でPerlでもよんでほしい。
0830名無しさん@お腹いっぱい。
2006/07/25(火) 20:18:080831名無しさん@お腹いっぱい。
2006/07/25(火) 21:26:13してくれる。数字8桁はさすがに食ってくれないようだが、ちょいと/を付け足して食わせりゃ
出来上がりだ。
0832名無しさん@お腹いっぱい。
2006/07/25(火) 21:34:06↓
$ date -d 20060230
Thu Mar 2 00:00:00 JST 2006
数字8桁でもそのまま日付として食ってくれるが、
2月30日はご丁寧にも3月2日として解釈してくれる。
ま、これも、
if [ `date -d 20060230 +%Y%m%d` = 20060230 ]; then
とかでチェックすれば済むことだな。
それより、>>825 はコピペだから詳しくは答えてあげない。
めでたくリストラされてください。
あ、もし自宅が借り上げ社宅なら、リストラ前に個人契約に変更しといた方がいいよ。
リストラ後だと保証人とかの問題で部屋が借りにくくなるから。
0833名無しさん@お腹いっぱい。
2006/07/25(火) 23:30:410834名無しさん@お腹いっぱい。
2006/07/26(水) 11:13:090835名無しさん@お腹いっぱい。
2006/07/26(水) 12:02:440836名無しさん@お腹いっぱい。
2006/07/26(水) 12:19:540837名無しさん@お腹いっぱい。
2006/07/26(水) 12:25:09あと、日付の正当性チェックは閏年、大小の月で case文あたりで場合わけ判断と。
とは言っても、シェルスクリプト自体超初心者の >>825 には無理。
リストラされろ。
0838名無しさん@お腹いっぱい。
2006/07/26(水) 13:00:24>>407-413
0839名無しさん@お腹いっぱい。
2006/07/26(水) 13:02:490840名無しさん@お腹いっぱい。
2006/07/26(水) 13:23:45欲嫁。>>408 では日付の正当性チェックはできてない。曜日計算のみ。
あと、曜日計算なら >>408 よりももっと簡単にできる。
0841名無しさん@お腹いっぱい。
2006/07/26(水) 22:41:35どうしても解決したいなら、有料でもいいのだろ?
職業別電話帳見ると、街の便利屋さん(何でも屋さん)みたいなの載ってるだろ。
そこに電話して頼め。
もちろん、その便利屋さん本人はshellだのUNIXだの言っても知らないだろうが、
相手もプロだ。shellとかUNIXとかキーワードを頼りにそれ関係の詳しい人に
取り次いで問題を解決してくれる。特殊な用件だから少々高く取られるかもね。
0842名無しさん@お腹いっぱい。
2006/07/28(金) 14:25:42# valid-date - validate date, taking into account leap year rules
ttp://www.intuitive.com/wicked/showscript.cgi?007-valid-date.sh
0843名無しさん@お腹いっぱい。
2006/07/30(日) 13:16:380844名無しさん@お腹いっぱい。
2006/08/05(土) 11:51:54Grepを使った検索スクリプトについて
1) あるテキストファイル(Pattern.txt)に検索対象文字列が改行単位で入っている。
2) この文字列ひとつひとつをパターン文字として、/apl/usr配下のファイルをGrepしたい。
3) 最終的にRESULTファイルに以下のような形式に保存したい。(RDB取込用ファイルの作成)
<検索対象文字列> , <ヒットしたファイル名>
多分、Ptternファイルを一行ずつ読み込んで、Grepする処理を
ループさせるようなスクリプトになると思うんですけど・・
・
0845名無しさん@お腹いっぱい。
2006/08/05(土) 12:31:30はいはい、マルチマルチ。
0846名無しさん@お腹いっぱい。
2006/08/06(日) 00:31:32CGIやPHPでシェルスクリプトを実行するにはどうしたらできますか?
実行方法がわからないのでおしえてください。
0847名無しさん@お腹いっぱい。
2006/08/06(日) 00:45:02(1)先頭に
#!/bin/sh
のように陽にshellのmagicを書いておいて、
(2)CGIやPHPが動くときのuser id での実行許可をたてて、
(3)system()やexec()を呼ぶ。スクリプトのパスは原則フルパスで。
0848名無しさん@お腹いっぱい。
2006/08/06(日) 00:46:03ちょw
0849847
2006/08/07(月) 03:14:470850名無しさん@お腹いっぱい。
2006/08/07(月) 03:36:41(2) CGI鯖のあるプロバイダに接続
(3) 鉄定規をF5キーの箇所に置き、ハイパーオリンピックの要領で弾く
(4) 頃合いを見て80番ポートからログイン
(5) 自分のディレクトリの実行許可を書き換え
(6) /bin/shを実行
0851名無しさん@お腹いっぱい。
2006/08/07(月) 03:54:34CGIとPHPが一緒くたな時点で「ちょw」
CGIは文字通りインターフェースだから、シェルスクリプト自体を直接実行できるのをわるれるな。
0852名無しさん@お腹いっぱい。
2006/08/07(月) 09:06:470853名無しさん@お腹いっぱい。
2006/08/11(金) 23:09:46a:~
となるのに、
% a=a:~
% echo $a
a:/home/giko
となるのはなぜですか?
0854名無しさん@お腹いっぱい。
2006/08/11(金) 23:44:49■ このスレッドは過去ログ倉庫に格納されています