シェルスクリプト総合 その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 でトレースしましょう。
0507名無しさん@お腹いっぱい。
2006/12/02(土) 22:17:15なぜ残っているのか?
0508名無しさん@お腹いっぱい。
2006/12/02(土) 22:24:14だからぁ、察してやれよ、MNOの書き間違いだろ。
0509名無しさん@お腹いっぱい。
2006/12/02(土) 22:27:07$ cat minus.awk
#!/usr/bin/gawk -f
ARGIND == 1 {
minus[ $0 ] = sprintf("hogehoge%d",FNR)
next
}
$0 in minus {
print minus[ $0 ]
next
}
{
}
$ gawk -f minus.awk (抜くキーワードを書いたファイル) (抜かれる方のファイル)
0510名無しさん@お腹いっぱい。
2006/12/02(土) 22:37:23シェルスクリプトでやりたいです。
ABC
DEF
GHI
JKL
MNO
という文字列を
DEF
GHI
JKL
という部分をごっそり抜いて、
ABC
と
MNO
の間に特定の文字列を挿入して、
ABC
hogehoge1
hogehogeXX
hogeYY
MNO
としたいのですが、
何か良い案はないでしょうか?
よろしくお願いします。
0511名無しさん@お腹いっぱい。
2006/12/02(土) 22:43:52↓ほれ、これでいいかい? シェルだけでやったよ。外部コマンドは使ってない。
while read line
do
case $line in
ABC|MNO) echo "$line";;
DEF) echo hogehoge1;;
GHI) echo hogehogeXX;;
JKL) echo hogeYY;;
esac
done < input_file
0512名無しさん@お腹いっぱい。
2006/12/02(土) 22:55:31cat aa |sed -e '/DEF/,/JKL/c\
hogehoge1\
hogehogeXX\
hogeYY'
0513名無しさん@お腹いっぱい。
2006/12/02(土) 22:56:21>>505は読んだのかw?
0514名無しさん@お腹いっぱい。
2006/12/02(土) 22:56:33お約束のcatが無駄です。あと、シェルだけでやりたいと申されております。
0515名無しさん@お腹いっぱい。
2006/12/02(土) 23:02:26> 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
...
0516名無しさん@お腹いっぱい。
2006/12/02(土) 23:06:31お客様、仕様書が曖昧で作業に入れませんのでご確認をお願いいたします。
こいういうことでしょうか?
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それぞれに
対応させて置換するのか。
0517510
2006/12/02(土) 23:06:52ですので、
512
でほぼ解決です。
ありがとうございました。
説明がわかりにくくてご迷惑をお掛けしました。
また出直します。
0518名無しさん@お腹いっぱい。
2006/12/02(土) 23:09:28>>512は
DEFとJKLではさまれている行だろうが、どこが
> ABCの次の行からMNOの前の行まで。
なんだよ。
0519名無しさん@お腹いっぱい。
2006/12/02(土) 23:23:28「ほぼ」って言ってるから良いんじゃない?
sed -e '/ABC/,/MNO/c¥
ABC¥
hogehoge1¥
hogehogeXX¥
hogeYY¥
MNO'
程度の修正は誤差であるというくらい理解したんじゃないかna
0520名無しさん@お腹いっぱい。
2006/12/02(土) 23:32:03echo "$i"
done
Bourne Shellでも動きますか?
0521名無しさん@お腹いっぱい。
2006/12/02(土) 23:32:350522520
2006/12/02(土) 23:32:52for ((i=0; i<10; i++)) ; do
echo "$i"
done
Bourne Shellでも動きますか?
0523名無しさん@お腹いっぱい。
2006/12/02(土) 23:38:40for i in 1 2 3 4 5 6 7 8 9; do
echo "$i"
done
が最もポータブル。
seqやjotはあえて使わない。
0524名無しさん@お腹いっぱい。
2006/12/02(土) 23:52:400525名無しさん@お腹いっぱい。
2006/12/02(土) 23:57:42exprくらいは使ってもいいじゃね?
0526名無しさん@お腹いっぱい。
2006/12/05(火) 17:00:20for n in $aaa; do
echo "$n"
done
だと
"AAA
AAA"
BBB
となるのですが、これを
"AAA AAA"
BBB
とするにはどうすればいいのでしょうか?
0527名無しさん@お腹いっぱい。
2006/12/05(火) 17:12:42for n in "$aaa"
常に "$hoge" みたいに " " を付ける癖を付けろ。
0528名無しさん@お腹いっぱい。
2006/12/05(火) 17:13:44欲嫁。それだと逆に全部つながっちゃうが、、
0529名無しさん@お腹いっぱい。
2006/12/05(火) 22:58:15ゴリ押し
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
0530名無しさん@お腹いっぱい。
2006/12/05(火) 23:20:230531526
2006/12/06(水) 13:55:07精進します
0532名無しさん@お腹いっぱい。
2006/12/06(水) 16:54:030533名無しさん@お腹いっぱい。
2006/12/06(水) 17:48:45foo=$(echo $bar | sed -e 's!\(^.\).*!\1!')
0534名無しさん@お腹いっぱい。
2006/12/06(水) 18:48:23${var%%${var#?}}
0535532
2006/12/06(水) 20:52:29ありがとうございます。
自分なりに無い知恵を絞って出した答えは
foo=`perl -e "print substr('$var', 0, 1)"`
だったんですが、>>534には感動しました。
0536名無しさん@お腹いっぱい。
2006/12/06(水) 21:02:54↓がお勧め。
printf '%c\n' "$var"
0537名無しさん@お腹いっぱい。
2006/12/06(水) 21:42:29echo ${var:0:1}
0538名無しさん@お腹いっぱい。
2006/12/06(水) 21:48:39bash/ksh依存乙。
0539名無しさん@お腹いっぱい。
2006/12/06(水) 21:54:07foo=`expr "$bar" : '^\(.\)'`
0540名無しさん@お腹いっぱい。
2006/12/06(水) 22:49:45みなさん、ありがとうございます。
printfが存在を知ったり、exprの使い方がわかったりと、かなり勉強になりました。
ただ、>>539の正規表現は'\(.\)'`でいいみたいです。
^は正規表現の意味を持っていないので無視される。みたいなワーニングがでました。
0541名無しさん@お腹いっぱい。
2006/12/06(水) 23:48:500542名無しさん@お腹いっぱい。
2006/12/07(木) 00:01:29xargs を使った形に書き換えたいんですが、どう書けばいいんでしょうか?
0543名無しさん@お腹いっぱい。
2006/12/07(木) 00:25:47ていうか grep とか grep -r で済むなら xargs の出番なさそう。
0544542
2006/12/07(木) 01:04:05ファイルの文字コードがそれぞれ違う可能性があるから、
for i in *; do grep hoge $i |nkf -e >> out; done
と同じことをしたいのでした。
この場合も for の行で外部コマンドを呼んでいないから
ARG_MAX の制限はないようですね。
xargs で起動するコマンドの中にパイプやリダイレクトを
入れることはできるか、と聞きたかったのでした。
0545名無しさん@お腹いっぱい。
2006/12/07(木) 02:08:55find * ... -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
がちょっと長いけど速そう。
0546名無しさん@お腹いっぱい。
2006/12/07(木) 09:27:20find -print0
xargs -0
にしる、と突っ込んでおくべきなのだろうか
0547名無しさん@お腹いっぱい。
2006/12/07(木) 13:53:37仕様バグがどうこうとか。
0548名無しさん@お腹いっぱい。
2006/12/12(火) 15:03:35不安定な回線なのにどの程度不安定なのか把握できず困ってます
切断されてもすぐ再接続されるわけですが、これを記録しておきたいと思います
ping 撃ちまくるのはわかりますが、切断された時と再接続された時を記録するには
どんなスクリプト書けばいいですか?
0549名無しさん@お腹いっぱい。
2006/12/12(火) 19:53:11↓内容
1
11
111
cat 1.txt | grep 11
とやると
11と111の2つがヒットしてしまいます(^_^;)
11の行だけを抜き出す方法はないですかね?
0550名無しさん@お腹いっぱい。
2006/12/12(火) 20:14:17grep -w 11
0551名無しさん@お腹いっぱい。
2006/12/12(火) 20:47:34catが無駄です、のお約束。
0552名無しさん@お腹いっぱい。
2006/12/12(火) 21:11:23あんたマイナーになってるよ。
0553名無しさん@お腹いっぱい。
2006/12/12(火) 22:06:51grep -x 11 1.txt
0554名無しさん@お腹いっぱい。
2006/12/13(水) 10:08:050555名無しさん@お腹いっぱい。
2006/12/13(水) 10:26:21修正する文字数が少なくなるという、多大なメリットがある。
0556名無しさん@お腹いっぱい。
2006/12/13(水) 10:30:43別に咎めるほどのことではないと思う。
0557名無しさん@お腹いっぱい。
2006/12/13(水) 11:39:14本気で言ってんのか?
>>549のような使い捨てのワンライナーなら「修正の手間」も糞もねぇだろ。
元スクリプトが
script
なら、
zcat foo.gz | script
とすりゃいいだけだ。一行の修正も要らないし、zcat決めうちにするより
scriptの汎用性が維持される。
こっちのがツールボックスアプローチとして正しいわな。
必要も無いcatを使ってるスクリプトを見ると、俺は不安になるね。
書き手に変な癖がついてるのか、リダイレクションすら理解して無いのか、
品質上に問題があるんじゃないのかとか。
0558名無しさん@お腹いっぱい。
2006/12/13(水) 11:53:26使い捨てならわざわざリダイレクトなり引き数なりに
直す必要もないじゃん。
script の汎用性の話は意味がわからん。
0559名無しさん@お腹いっぱい。
2006/12/13(水) 12:05:560560名無しさん@お腹いっぱい。
2006/12/13(水) 12:11:06使い捨てと言いつつ、
grep -w 11 1.txt
ですむものを、
cat 1.txt | grep -w 11
と書きたがる意図が分からんのだが。
そんなにcatとタイプして無駄にプロセスを一個増やすのが好きか?
変な癖を正当化してるだけじゃないか?
0561名無しさん@お腹いっぱい。
2006/12/13(水) 12:18:25おれが書いたわけじゃないから
おれも意図はわからんな。
プロセスの減らし方あれこれ考えるより
さっさとスクリプト書きあげて
仕事終わらせちゃった方がいいじゃん。
0562名無しさん@お腹いっぱい。
2006/12/13(水) 12:22:26こんなことで「あれこれ考え」なきゃいけない時点でバカ。
判って無い証拠。
cat file cmd
が動作するなら
cmd <file
が確実に動作するんだから。
後者は無駄なプロセスが不要でタイプ量も少ない。
大体、タイプ量増えるのに、「さっさと仕事終わらせる」も糞もないだろ。
0563562
2006/12/13(水) 12:23:13cat file | cmd
な。
0564名無しさん@お腹いっぱい。
2006/12/13(水) 21:39:540565チラシの裏すまそ
2006/12/13(水) 22:01:56cat file | grep KEYWORD1
↓
カーソルキーの↑を押して前回のコマンドを表示し、
Deleteキー連打して、新しいキーワードを打ち込んで
↓
cat file | grep KEYWORD2
↓
以下、繰り返し
こんな感じだけどね。
シェルスクリプトの中では使わんけど。
0566名無しさん@お腹いっぱい。
2006/12/13(水) 22:06:27単にコマンドラインの右端の文字を変更しやすいという意味なら、
$ < file grep KEYWORD1
$ < file grep KEYWORD2
↑みたいにやれば良い。< fileの部分が左に来てもいいんだよ。パイプは使わない。
0568名無しさん@お腹いっぱい。
2006/12/13(水) 22:29:23とかしないの?
0569名無しさん@お腹いっぱい。
2006/12/13(水) 22:42:360570名無しさん@お腹いっぱい。
2006/12/13(水) 23:42:18bashでもzshでも、もちろんcshでも、^1^2とかできるはずだけど。
kshは知らんが。
0571名無しさん@お腹いっぱい。
2006/12/14(木) 01:39:01ヒットした最初の部分しか置き換わらんのが意外に使いにくいしくつう。
0572名無しさん@お腹いっぱい。
2006/12/14(木) 02:16:191 2 3....でなく
001 002 003...としたいのですが
d=0
mkdir 0$d
で$dに1つづ加算すると
1 2 3…となってしまいます orz
ヒントなんぞありましたら
おにぃちゃんおしえて! まぅまぅ
0573名無しさん@お腹いっぱい。
2006/12/14(木) 02:20:03d=0
mkdir 00$d
で$dに1つづ加算すると
001 002…009 になるものの 10を超えると
0010になってしまうので
010…099 100 となれば幸いです
0574名無しさん@お腹いっぱい。
2006/12/14(木) 02:31:550575名無しさん@お腹いっぱい。
2006/12/14(木) 02:37:100576名無しさん@お腹いっぱい。
2006/12/14(木) 07:34:49mkdir `seq -w 1 100`
0577名無しさん@お腹いっぱい。
2006/12/14(木) 11:29:48おにいちゃん!ありがと!まぅまぅ
perl,zshも勉強しますorz
winamp のストリームで
bpsやってるよ! まぅまぅ
0578名無しさん@お腹いっぱい。
2006/12/14(木) 14:03:120579名無しさん@お腹いっぱい。
2006/12/14(木) 15:23:17ps ax|grep XXX|wc -l
で確認すると、grep自身が入ったり入らなかったりします。
0580名無しさん@お腹いっぱい。
2006/12/14(木) 15:27:43pgrep XXX
0581名無しさん@お腹いっぱい。
2006/12/14(木) 15:45:13ありがとうございます
0582名無しさん@お腹いっぱい。
2006/12/14(木) 16:10:56grep -v grepしとけ
0583名無しさん@お腹いっぱい。
2006/12/14(木) 16:22:18プロセス名が logreport だったりするとだめ。
0584名無しさん@お腹いっぱい。
2006/12/14(木) 17:02:27やるな。
grep [X]XX
なら?
0585名無しさん@お腹いっぱい。
2006/12/14(木) 17:54:13いいのでしょうか?
シゥル関数使えないボーンシェルもありますか?
0586名無しさん@お腹いっぱい。
2006/12/14(木) 18:02:020587名無しさん@お腹いっぱい。
2006/12/14(木) 18:07:39Bourne shellなら知ってますが、
それとは違うシェルのことですよね?
0588名無しさん@お腹いっぱい。
2006/12/14(木) 18:19:270589名無しさん@お腹いっぱい。
2006/12/14(木) 19:04:190590名無しさん@お腹いっぱい。
2006/12/14(木) 23:41:000591名無しさん@お腹いっぱい。
2006/12/15(金) 00:34:460592名無しさん@お腹いっぱい。
2006/12/15(金) 00:36:26おどろーよシゥルダンス
0593名無しさん@お腹いっぱい。
2006/12/15(金) 01:07:42どう見ても米米クラブです。
本当にありがとうございました。
0594名無しさん@お腹いっぱい。
2006/12/15(金) 12:41:17LogFile名
Script名_$(date +"%Y%m%d-%H%M%S")_プロセスID
助言よろしくお願いします。
0595名無しさん@お腹いっぱい。
2006/12/15(金) 12:50:00プールン使うって理解でおk?
0596名無しさん@お腹いっぱい。
2006/12/15(金) 14:07:220597名無しさん@お腹いっぱい。
2006/12/15(金) 14:15:370598名無しさん@お腹いっぱい。
2006/12/15(金) 14:31:11素直にlogrotateでも使え
0599名無しさん@お腹いっぱい。
2006/12/15(金) 14:52:54どこかでそんなScriptを見た気がする。
0600名無しさん@お腹いっぱい。
2006/12/15(金) 16:29:30`expr \`date "+%Y%m%d"\` - 10`と比較して、これより小さければ、そのファイルを削除する。
あとはこれを、for f in `ls Script名_*` みたいな感じでループさせればいいだろう。
0601名無しさん@お腹いっぱい。
2006/12/15(金) 18:05:57多分そんなプロセス名自分は使わないだろうけど勉強になるな
0602名無しさん@お腹いっぱい。
2006/12/16(土) 00:44:15findで作成日が10日以前のログファイルを見つけて消すようにしては?
0603名無しさん@お腹いっぱい。
2006/12/16(土) 10:07:15この前その方法でやったけど何故か処理重かった・・・
なのでオレは>>600に近い方法でやったよ。
>600のそのままだとうまく動かないと思われ
0604名無しさん@お腹いっぱい。
2006/12/16(土) 10:26:00どの部分が重いのか、今後の為にも確認した方が良いと思うぞ。
0605名無しさん@お腹いっぱい。
2006/12/16(土) 10:33:12ほとんどの場合はそれでいいんだろうけどな、特に削除の場合は。
0606名無しさん@お腹いっぱい。
2006/12/16(土) 15:11:30今回は 10 だけど、7 の場合は date +%w でできてもっと単純。
0607名無しさん@お腹いっぱい。
2006/12/16(土) 18:26:39バックアップを1日3回取りたいのですが
日付毎のディレクトリを作って
mkdir /bak/`date +%d%m`
と、ここまではいいのですが2回目に、このスクリプトが動くと
もうディレクトリあるぞ( ゚Д゚)ゴルァ!!とエラーがでます(たいしたことはないのですが)
ディレクトリー作成とバックアップ用のスクリプトは別けたほうが良いでしょうか
if で あるからもう作らない 次進めとやると
速度落ちますよね?
なんかいい知恵ないでしょうか?
■ このスレッドは過去ログ倉庫に格納されています