シェルスクリプト総合 その7
レス数が950を超えています。1000を超えると書き込みができなくなります。
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 でトレースしましょう。
0878名無しさん@お腹いっぱい。
2007/02/07(水) 15:57:20なんでそんなにこだわるのかわからん。
0879名無しさん@お腹いっぱい。
2007/02/07(水) 15:58:360880名無しさん@お腹いっぱい。
2007/02/07(水) 16:33:11$ cat hoge
しまった長い... ^C
$ head hoge
考える...
$ tail hoge
考える...
$ sed -e '..' hoge |head
更に考える...
$ sed -e '..' -e '..' hoge |head
更に考える...
$ sed -e '..' -e '..' -e '..' hoge |head
やっぱ、catを使いたがるのは、ダメ人間だな。
0881名無しさん@お腹いっぱい。
2007/02/07(水) 16:42:250882名無しさん@お腹いっぱい。
2007/02/07(水) 16:56:480883名無しさん@お腹いっぱい。
2007/02/07(水) 18:05:59sed -n か awk を使えばできると思うのですが難しいです。
<span>
数行
</span>
数行
<span>
数行
</span>
0884名無しさん@お腹いっぱい。
2007/02/07(水) 18:19:17>>743
0885831
2007/02/07(水) 18:50:30今日、仕事をサボって(w)
本屋に行ってきて物色してみました。
Rubyがよさげだったので
さっそく「たのしいRuby」という本を
買ってきました。
ttp://sheel.mydns.jp/~sheel/ruby.jpg
ワクワクしますよ。
0886名無しさん@お腹いっぱい。
2007/02/07(水) 20:54:51xmlstarlet とかのツールを補助に使えばいいと思うよ。
XSLT でも Xpath でも好きにコマンドラインから使える。
0887名無しさん@お腹いっぱい。
2007/02/07(水) 22:52:08<span> と </span> のが完全に1行ずつなら簡単だね
0888名無しさん@お腹いっぱい。
2007/02/07(水) 22:55:59そのように整形する前処理をするとかね
0889831
2007/02/08(木) 09:49:41おれなら
cat -nとかでhtml書類を出力し
それをパイプしてgrepなどで一番最初に遭遇する
<span>と</span>をみつけ、
cut -d¥: -f1を使ってその行頭の数値(=行番号)をよみとり、
その結果をまた
それをパイプしてgrepなどで一番最初に遭遇する
<span>と</span>をみつけ、
cut -d¥: -f1を使ってその行頭の数値(=行番号)をよみとり、
という繰り返しでやるかな。
0890831
2007/02/08(木) 10:05:40>>883
おれなら
cat -nとかでhtml書類を出力し
それをパイプしてgrepなどで一番最初に遭遇する
<span>と</span>をみつけ、
cut -d¥: -f1を使ってその行頭の数値(=行番号)をよみとり、
cat -nする前のhtmlに対してその数値の間をsedのdオプションで削除し、
その結果をまた
cat -nとかで出力し、
それをパイプしてgrepなどで一番最初に遭遇する
<span>と</span>をみつけ、
cut -d¥: -f1を使ってその行頭の数値(=行番号)をよみとり、
cat -nする前のhtmlに対してその数値の間をsedのdオプションで削除し、
という繰り返しでやるかな。
0891名無しさん@お腹いっぱい。
2007/02/08(木) 10:37:59なんてケースは考えるだけ無駄だったりするよな。
0892名無しさん@お腹いっぱい。
2007/02/08(木) 11:26:21RSSとか扱ってると、結構あるけど
0893名無しさん@お腹いっぱい。
2007/02/08(木) 11:30:47たいていこういう質問投げるやつって投げっぱなしだよね。
0894名無しさん@お腹いっぱい。
2007/02/08(木) 12:14:030895883
2007/02/08(木) 14:59:160896名無しさん@お腹いっぱい。
2007/02/08(木) 16:26:18知っているかた教えてください。
if [ -e /work/IBMIHS/logs/access_log ];
then
mv /work/IBMIHS/logs/access_log /logs/auditlog/access_log.$(date "+%Y%m%d") >> ${LOG_FILE}
echo "IHSログローテーション(アクセスログ)は成功しました。"
else
echo "IHSログローテーションは失敗しました。"
exit 1
fi
if [ -e /work/IBMIHS/logs/error_log ];
then
mv /work/IBMIHS/logs/error_log /logs/auditlog/error_log.$(date "+%Y%m%d") >> ${LOG_FILE}
echo "IHSログローテーション(エラーログ)は成功しました。"
else
echo "IHSログローテーションは失敗しました。"
exit 1
fi
0897名無しさん@お腹いっぱい。
2007/02/08(木) 16:45:32↑じゃダメな理由あるの?
0898名無しさん@お腹いっぱい。
2007/02/08(木) 17:12:50if [ -e /work/IBMIHS/logs/$log ];
then
else
fi
done
0899名無しさん@お腹いっぱい。
2007/02/08(木) 17:13:19for f in access_log error_log; do ....
ってことをしたいのか?
0900名無しさん@お腹いっぱい。
2007/02/08(木) 17:17:12ま、それはおいといて、単純に繰り返し部分をまとめるだけなら、
SRCDIR="/work/IBMIHS/logs"
DESTDIR="/logs/auditlog"
for FN in "access_log error_log"
do
if [ -e "${SRCDIR}/${FN}" ]
then
mv "${SRCDIR}/${FN}" "${DESTDIR}/${FN}.$(date "+%Y%m%d")" >> ${LOG_FILE}
echo "IHSログローテーション(${FN})は成功しました。"
else
echo "IHSログローテーションは失敗しました。"
exit 1
fi
done
とか。
0901名無しさん@お腹いっぱい。
2007/02/08(木) 17:32:12for FN in "access_log" "error_log"
0902名無しさん@お腹いっぱい。
2007/02/08(木) 19:58:24sudo -u hoge echo "hoge" > test.txt
とすると
test.txt の所有権は hoge ではなく、
sudo の実行者になります。
test.txt を hogeの所有権のファイルとして作成したいのですが、
どこに間違いがあるかご教授お願いします。
0903名無しさん@お腹いっぱい。
2007/02/08(木) 20:05:21sudo -u hoge sh -c 'echo "hoge" > test.txt'
0904名無しさん@お腹いっぱい。
2007/02/08(木) 20:07:161. > test.txt
2. sudo -u hoge echo "hoge"
の順で処理されるからね。
sudo -u hoge sh -c 'echo "hoge" > test.txt'
0905902
2007/02/08(木) 20:09:21レスありがとうございます、
上の内容をためしたところ、存在しない、といったエラーが出てしまいました。
お助けを〜〜
sh: test.txt: No such file or directory
0906902
2007/02/09(金) 01:44:34再度試してみたらいけました。
ありがとうございました。
教えていただいた内容も納得です!
ちょっと関連した内容になるのですが、
"hoge"の部分に改行などを含んだ変数を入れたいのですが、
うまくいきません。
どうやら改行ごとに、シェルが実行されてしまっている?ようです。
複数行にわたった変数を使用したい場合、
どのように記述すればよいでしょうか?
何度もすいません orz
0907名無しさん@お腹いっぱい。
2007/02/09(金) 06:43:270908名無しさん@お腹いっぱい。
2007/02/09(金) 10:17:57継続行を入力させてくれるかも。
0909名無しさん@お腹いっぱい。
2007/02/09(金) 11:38:06何もする必要ない。"hoge" の途中に改行があっても改行はそのまま保存される。
もし、そうならないなら、sudoを実行しているコマンドラインのシェルが、
普通のB-sh系のシェルじゃないんだろう。
(あるいは、sudo先のユーザーのログインシェルが B-sh系じゃないとか)
sh bash zsh ksh 等の B-sh系を使うこと。
0910902
2007/02/09(金) 15:59:08レスありがとうございます。
ある変数の内容をファイルに書き込みたい、
という場合、echo とリダイレクトを使う以外にありますでしょうか?
0911名無しさん@お腹いっぱい。
2007/02/09(金) 16:04:07echo "$変数" | sudo -u hoge sh -c 'cat > test.txt'
sudo先のshでechoすると、クォートが2重になってややこしいから、
sudo前にechoしておいてパイプでつなぐ。
0912902
2007/02/09(金) 16:30:53orz ありがとうございます、うまくいきました。
クオートが入れ子になってて鬱入ってました。
発想の転換ですね、さすがみなさん視点がすごいです!!
本当にありがとうございました!!!
0913名無しさん@お腹いっぱい。
2007/02/11(日) 17:22:09「ls -l」形式のファイル一覧が入っているテキストファイル(引数)
を1行ずつ読み込み、ファイル名に「.bak」が含まれるファイルを
消去するシェルスクリプトを作成したいのですが、頭の「#!/bin/sh」
を書いた時点で力尽きました。
「while read」を使う、というところまでは理解出来たのですが、
文法等がさっぱりで…どなたかご教授願えないでしょうか?
0914名無しさん@お腹いっぱい。
2007/02/11(日) 17:33:05read 使うと逆に難しそう。
grep .bak したのを sed か awk かなんかで加工して rm、がいいと思う。
> 「ls -l」形式のファイル一覧が入っているテキストファイル(引数)
この前提は変えられない?
ls -l 形式は扱いづらそうだから
find とか使った方がいいと思うんだが。
0915名無しさん@お腹いっぱい。
2007/02/11(日) 17:37:27超簡単。1行で書ける。
while read line; do case $line in *.bak);; *) echo "$line";; esac; done < file
>>914
おまえには難しかったようだね。
0916名無しさん@お腹いっぱい。
2007/02/11(日) 17:48:12それって >>913 の要求満たしてるの?
0917名無しさん@お腹いっぱい。
2007/02/11(日) 17:50:39「ls -l出力が書かれたファイルの中から、ファイル名 *.bakのファイルを消去する」 のか?
0918名無しさん@お腹いっぱい。
2007/02/11(日) 17:53:13わかりにくい質問でどうも済みませんでした。
前者の意味です。>>915 でできました。Thanksです。
0919名無しさん@お腹いっぱい。
2007/02/11(日) 17:54:48なら grep -v '\.bak$' でいいじゃん。
シンボリックリンクに対応してないけど。
0920913
2007/02/11(日) 18:02:01申し訳ありません。説明不足でした。
「ls -l出力が書かれたファイルの中から、ファイル名 *.bakのファイルを消去する」
が目的です。
ファイルリストをgrepして*.bakを含む行だけ取り出した後、awkを使用してls -lの
リストからファイル名を抜き出して…とか色々と考えていたのですが、それらを
シェルスクリプトで作成するだけの知識とか度胸とかが足りなくて困っております。
>915
回答ありがとうございます。「esacって何?」とか調べていたら返事が遅れて
しまいました。
0921名無しさん@お腹いっぱい。
2007/02/11(日) 18:03:460922名無しさん@お腹いっぱい。
2007/02/11(日) 18:04:520923名無しさん@お腹いっぱい。
2007/02/11(日) 18:06:10だったら、↓で行ける。(ls -l であって、ls -lR ではないんだから)
while read perm link usr grp size mon day year file other
do
case $file in
*.bak) rm "$file";;
esac
done < ls-l-file.txt
0924名無しさん@お腹いっぱい。
2007/02/11(日) 19:34:210925名無しさん@お腹いっぱい。
2007/02/11(日) 19:50:26cat file |sed -e
0926913
2007/02/11(日) 19:56:38回答ありがとうございます。色々いじくり回して実験してみます。
0927名無しさん@お腹いっぱい。
2007/02/11(日) 23:23:51アバウトに日付情報だけで判断できれば十分なので
find file -printf "%Ad" でやろうと思ったのですが
月をまたぐとどうにもこうにもいきません。
0928名無しさん@お腹いっぱい。
2007/02/11(日) 23:39:08OSによってはdateとかを駆使してもできるとは思うが、perlが適材適所
0929名無しさん@お腹いっぱい。
2007/02/11(日) 23:41:54とやって、
ファイルXXX をディレクトリAAA にコピー(cp) して
なおかつ、AAA に移動(cd) する
というコマンドを作りたいんだけど、どうすればいい?
0930名無しさん@お腹いっぱい。
2007/02/11(日) 23:48:390931名無しさん@お腹いっぱい。
2007/02/12(月) 00:14:22.bashrc あたりにこんな感じの function を書くのがお手軽かな
hoge(){
cp "$1" "$2"
builtin cd "$2"
}
引数のチェックとかの拡張はお好みで。
0932名無しさん@お腹いっぱい。
2007/02/12(月) 00:27:490933名無しさん@お腹いっぱい。
2007/02/12(月) 01:36:070934名無しさん@お腹いっぱい。
2007/02/12(月) 02:10:570935名無しさん@お腹いっぱい。
2007/02/12(月) 11:09:31>>934
そうだったのかー
0936名無しさん@お腹いっぱい。
2007/02/12(月) 11:46:560937名無しさん@お腹いっぱい。
2007/02/12(月) 12:00:010938名無しさん@お腹いっぱい。
2007/02/12(月) 12:33:37bashだろ、どうせ。
0939929
2007/02/12(月) 22:02:42tcsh です
0940名無しさん@お腹いっぱい。
2007/02/13(火) 00:32:06cshスクリプトを書いておいて、
それをsourceするaliasを設定するとか。
もっとスマートな方法、教えてエロい人。
0941名無しさん@お腹いっぱい。
2007/02/13(火) 03:40:49シンボリックリンクをgawkから変更しようかしら。
最近のgawkはインターネットアクセスが出来るらしいけど使いかたが分からない。
0942名無しさん@お腹いっぱい。
2007/02/13(火) 06:38:22日本語が「通る」の意味がよくわからないが、
.がちゃんと一文字に適合したり
文字クラスとして[あ-ん]のようなものが書けたり
\u3120のようにユニコードリテラルを記述できたりするの?
0943名無しさん@お腹いっぱい。
2007/02/13(火) 07:18:58そのへんは検証してもらえないかなと思いまして。w
とりあえず.は駄目でした。w
[あ-ん]はたぶん大丈夫そうな気が。
4行目の機能ってgawkにあるんですか?
0944名無しさん@お腹いっぱい。
2007/02/13(火) 07:45:46いや別にgawkは関係ない。
せっかくUnicodeに対応しているなら、出来たほうが便利なのは
確実だが。
"Tibetan"とか"Greek"とか"CJKCompatibility"みたいに、
Unicodeのブロック/カテゴリ名が使えるとさらによい。
逆にその辺が出来ないなら、今時のUnicode対応としては
大したこと無いレベルじゃまいか?
まー今更awkにそんなに多くを求めてもしゃーない気はするが。
0945名無しさん@お腹いっぱい。
2007/02/13(火) 07:48:10単に8bitクリーンなだけじゃないの?
0946名無しさん@お腹いっぱい。
2007/02/13(火) 08:25:37...(.が3回)で一文字に適合しました。w
0947名無しさん@お腹いっぱい。
2007/02/13(火) 14:47:36for f in $dir;do
echo "$f"
done
とすると
aaa
bbb
と表示されますが、この dir に空白を含む文字列を含ませるにはどうすればいいのでしょうか?
イメージとしては
dir='aaa bbb "ccc ddd"' とすると
aaa
bbb
ccc ddd
と表示できたらいいなと
0948名無しさん@お腹いっぱい。
2007/02/13(火) 18:30:35できないはず
だからperlにしろと
0949名無しさん@お腹いっぱい。
2007/02/13(火) 19:00:25そういう場合は位置パラメータを使う。
set aaa bbb 'ccc ddd'
for f in "$@"; do
echo "$f"
done
これで、
aaa
bbb
ccc ddd
と表示される。
0950名無しさん@お腹いっぱい。
2007/02/13(火) 20:24:330951929
2007/02/13(火) 21:04:24alias 使えばいいというのはわかるんですが、
そのcsh スクリプトがかけないんです
0952名無しさん@お腹いっぱい。
2007/02/13(火) 21:06:59cshの話は厳禁。よそ行け。
b-shでの答えはすでに出てる。
0953名無しさん@お腹いっぱい。
2007/02/13(火) 21:38:370954名無しさん@お腹いっぱい。
2007/02/13(火) 21:38:560955名無しさん@お腹いっぱい。
2007/02/13(火) 21:43:140956名無しさん@お腹いっぱい。
2007/02/13(火) 22:58:21$HOME/tmp/cpcd.shとかを作って中身を
#!/bin/tcsh
cp "$1" "$2"
cd "$2"
として、
chmod +x $HOME/tmp/cpcd.sh
alias cpcd "source $HOME/tmp/cpcd.sh"
0957名無しさん@お腹いっぱい。
2007/02/13(火) 23:25:57sh-bangも+xもいらないんじゃないか?
0958名無しさん@お腹いっぱい。
2007/02/14(水) 01:24:40対処法を伝授して下さい
mv abc.txt %Y%m%dd.txt
0959名無しさん@お腹いっぱい。
2007/02/14(水) 01:44:50>4行目の機能ってgawkにあるんですか?
ない。
gawkは内部的にwchar_tを使っているだけで、スクリプトの記述は
そのときの locale設定が使われ、表にはUnicode(やwchar_t)はでてこない。
一応 [あ-お]はできるけどね。
0960名無しさん@お腹いっぱい。
2007/02/14(水) 01:48:59mv abc.txt `date +%%Y%m%d`d.txt
0961名無しさん@お腹いっぱい。
2007/02/14(水) 01:50:000963名無しさん@お腹いっぱい。
2007/02/14(水) 03:16:180965名無しさん@お腹いっぱい。
2007/02/14(水) 08:07:50の上のほうにあるスクリプトのtrapって何を拾っているんでしょうか?
0 は分かるんですが、1, 2, 3, 15が分かりません。
0966名無しさん@お腹いっぱい。
2007/02/14(水) 09:19:02man 7 signal参照。
1:SIGHUP 2:SIGINT 3:SIGQUIT 15:SIGTERM
0967名無しさん@お腹いっぱい。
2007/02/14(水) 10:12:04$ man 7 signal
No entry for signal in section 7 of the manual
ここはLinux板じゃない。
0968名無しさん@お腹いっぱい。
2007/02/14(水) 13:32:310969名無しさん@お腹いっぱい。
2007/02/14(水) 13:33:040970名無しさん@お腹いっぱい。
2007/02/14(水) 13:54:30man -a signalと言っておけばよかったね。
BSD(つーかMacだが)だとセクション3のライブラリ関数のとこに
一緒に載ってるようだな。
0971名無しさん@お腹いっぱい。
2007/02/14(水) 15:13:050972名無しさん@お腹いっぱい。
2007/02/14(水) 22:52:510973名無しさん@お腹いっぱい。
2007/02/14(水) 23:01:02ls -FA | grep /
ちょっと意味が違うか?
0974名無しさん@お腹いっぱい。
2007/02/14(水) 23:13:07俺は
ls -l | grep 4096
でなんとかなっている
0975名無しさん@お腹いっぱい。
2007/02/14(水) 23:15:18ls -l | grep ^d
どちらかといえばこれか。
0976名無しさん@お腹いっぱい。
2007/02/14(水) 23:16:200977名無しさん@お腹いっぱい。
2007/02/14(水) 23:26:49大文字も小文字も区別なく表示させたいのですが、可能ですか?
ls *.dat
に何か工夫して、aaa.dat とbbb.DAT などを表示させたいです。
レス数が950を超えています。1000を超えると書き込みができなくなります。