シェルスクリプト総合 その19
■ このスレッドは過去ログ倉庫に格納されています
0001シェルスクリプトライター
2011/12/10(土) 20:06:40.38スクリプトのお勉強・自慢・腕試しなどにどうぞ。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
FreeBSDユーザは/bin/shの正体がashなので注意。
v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/
http://heirloom.sourceforge.net/sh.html
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
前スレ
シェルスクリプト総合 その18
http://hibari.2ch.net/test/read.cgi/unix/1308195527/
次スレは >>970 で。
0028名無しさん@お腹いっぱい。
2011/12/23(金) 01:09:38.83iconv使えよ・・・
0029名無しさん@お腹いっぱい。
2011/12/23(金) 09:09:05.64(まあ、-sもあるとは言え)
0030名無しさん@お腹いっぱい。
2011/12/23(金) 10:17:10.53つiconv -c オプション
0031名無しさん@お腹いっぱい。
2011/12/23(金) 11:13:30.90日本語ならnkfの方がまだ分があるって気がする
0032名無しさん@お腹いっぱい。
2011/12/23(金) 11:32:03.950033名無しさん@お腹いっぱい。
2011/12/23(金) 12:23:33.56-c オプションでも解決はしないので nkfお勧め
0034名無しさん@お腹いっぱい。
2011/12/23(金) 18:10:27.100035名無しさん@お腹いっぱい。
2011/12/24(土) 02:09:13.88入れてたpythonでフィルタ書いて使ってる
0036名無しさん@お腹いっぱい。
2011/12/24(土) 02:52:14.20サーバーの設定で文字コードって指定できるんですか?
0037名無しさん@お腹いっぱい。
2011/12/24(土) 03:18:19.750038名無しさん@お腹いっぱい。
2011/12/24(土) 03:33:21.59文字化けだけは防げると思うよ。
文字化けだけは。
0039名無しさん@お腹いっぱい。
2011/12/24(土) 08:59:26.03make一発でコンパイルできるやん
# Makefileにinstall targetがないけどw
0040名無しさん@お腹いっぱい。
2011/12/24(土) 09:07:08.000041名無しさん@お腹いっぱい。
2011/12/25(日) 00:54:50.02間違っています >>39
0042名無しさん@お腹いっぱい。
2011/12/25(日) 01:07:20.68えっ!?
0043名無しさん@お腹いっぱい。
2011/12/26(月) 01:28:47.74内容は天気表示スクリプトで使いかたは第1引数に、
http://weather.yahoo.co.jp/weather/jp/13/4410/13101.html
などのYahooのかなり限定されたURLを打ち込んで使う。
[Bash] weather_yahoo - Pastebin.com
http://pastebin.com/BxfbhQFd
curlじゃなくてaria2cは好みで使ってみた。
一部文字もユニコードで絵文字部分を使っているのでフォントや文字コードによっては文字化けが発生多発する思います。
最初のHTMLからの行の抜き出しはハードコーディングしないほうがいいと思うけど、構造自体変わったら元も子もないし、面倒でやめてしまった。
0044名無しさん@お腹いっぱい。
2011/12/26(月) 07:58:45.68いちいち変数に入れずに、そのままアウトプットしちゃえばいいんじゃないの?
0045名無しさん@お腹いっぱい。
2011/12/26(月) 08:52:51.00> #! /bin/bash
出直しな。
0046名無しさん@お腹いっぱい。
2011/12/26(月) 09:05:07.670047名無しさん@お腹いっぱい。
2011/12/26(月) 09:48:59.59#! /bin/sh
wget -O - --quiet "$1" \
| sed -n '149,163p' \
| sed -r '0~2d
s/.*>([^<]+)<.*/\1/
s/晴れ/ /
s/曇り/ /
s/弱雨/ /
s/湿雪|乾雪|みぞれ/ /' \
| tr '\n' ' ' \
| awk '{ if ($7 == $8) $8 = "〃"
if ($7 == $8) $8 = "〃"
if ($6 == $7) $7 = "〃"
if ($5 == $6) $6 = "〃"
if ($4 == $5) $5 = "〃"
if ($3 == $4) $4 = "〃"
if ($2 == $3) $3 = "〃"
if ($1 == $2) $2 = "〃"
printf "|--+--+--+--+--+--+--+--|\n\
|00|03|06|09|12|15|18|21|\n\
|--+--+--+--+--+--+--+--|\n\
|%s|%s|%s|%s|%s|%s|%s|%s|\n\
|--+--+--+--+--+--+--+--|\n", $1, $2, $3, $4, $5, $6, $7, $8}'
0048名無しさん@お腹いっぱい。
2011/12/26(月) 10:29:15.477zがそんな感じになってるね。
0049名無しさん@お腹いっぱい。
2011/12/26(月) 11:44:34.940050名無しさん@お腹いっぱい。
2011/12/26(月) 11:52:54.12まあ圧縮するときにどうせ付けないといけないから結局覚えてしまうんだけど。
0051名無しさん@お腹いっぱい。
2011/12/26(月) 23:59:53.81前時刻と同じかどうかのチェックと出力はまとめて
|awk '{for (i=1;i<9;i++){printf "|%s",$i==tmp?"〃":$i;tmp=$i};print "|"}'
としたい気分、スレ違い失礼
0052名無しさん@お腹いっぱい。
2011/12/27(火) 02:06:11.940053ss
2011/12/27(火) 06:20:47.960054名無しさん@お腹いっぱい。
2011/12/30(金) 18:26:14.20a.sh -a -b c d e
=> 3
0055名無しさん@お腹いっぱい。
2011/12/30(金) 18:39:18.15#! /bin/sh
manko=0
for chinko in $@
do
if [ `echo $chinko | grep -v ^-` ] ; then
manko=`expr $manko + 1`
fi
done
echo $manko
0056名無しさん@お腹いっぱい。
2011/12/30(金) 18:52:22.91"$@" の中に特殊記号とかスペースとか入ってたら駄目。
forとかでループしたりせずに一発でできる方法を想定してます。
0057名無しさん@お腹いっぱい。
2011/12/30(金) 18:57:38.49for a in "$@";do
case "$a" in
-*)
;;
*)
n=`expr $n + 1`
;;
esac
done
echo $n
0058名無しさん@お腹いっぱい。
2011/12/30(金) 18:58:18.36ねーよ。
0059名無しさん@お腹いっぱい。
2011/12/30(金) 18:59:04.62sedで一文でできたとしても下のレイヤではいくらでもfor文回ってるだろうに。
0060名無しさん@お腹いっぱい。
2011/12/30(金) 20:54:28.27そういうのはUNIX系OSとは非常に相性が悪いので、至れり尽くせりのMFCとかを使うほうが捗るよ
0062名無しさん@お腹いっぱい。
2011/12/30(金) 21:09:20.570063名無しさん@お腹いっぱい。
2011/12/30(金) 21:14:09.510064名無しさん@お腹いっぱい。
2011/12/30(金) 23:59:08.23なんで…
0065名無しさん@お腹いっぱい。
2011/12/31(土) 00:09:53.640066名無しさん@お腹いっぱい。
2011/12/31(土) 06:39:40.520067名無しさん@お腹いっぱい。
2011/12/31(土) 08:53:32.92俺は単純なものとか、拡張する予定が無いときはつかわないなぁ
それに複雑な処理をするならば、RubyなりPerl使った方が簡単とかさ
0068名無しさん@お腹いっぱい。
2011/12/31(土) 09:07:33.56>>66 は >>54 の場合について言ってるんだろ?
0069名無しさん@お腹いっぱい。
2011/12/31(土) 15:02:13.88こんな便利なものが!
getoptsを利用すれば、そもそも -で始まるものを除いた個数を数える必要もない
ことがわかりました。これで行きます。
まさに、forとかでループしたりせずに一発でできる方法ですね。
0070名無しさん@お腹いっぱい。
2011/12/31(土) 15:39:18.970071名無しさん@お腹いっぱい。
2011/12/31(土) 15:44:42.43でもちょっと寂しいです。
0072名無しさん@お腹いっぱい。
2011/12/31(土) 16:46:43.68おおッ。気付いてませんでした
0073名無しさん@お腹いっぱい。
2011/12/31(土) 16:54:05.710074名無しさん@お腹いっぱい。
2012/01/06(金) 01:39:38.05そのプロセスを自動的に殺すようなスクリプトは書けますでしょうか?
または、あるプロセスを100秒だけ起動して、その後自動的に強制的に殺すこと
は可能でしょうか。
0075名無しさん@お腹いっぱい。
2012/01/06(金) 02:49:26.47>あるプロセスを起動して、その標準出力から100行分の入力をもらったら、
>そのプロセスを自動的に殺すようなスクリプトは書けますでしょうか?
あるプロセス | head -n 100
でいいんでねえの?
>または、あるプロセスを100秒だけ起動して、その後自動的に強制的に殺すこと
>は可能でしょうか。
あるプロセス &
sleep 100
kill -9 あるプロセスのプロセスID
でいいんでねえの?
0076名無しさん@お腹いっぱい。
2012/01/06(金) 07:22:26.85$! 使えよ
0077名無しさん@お腹いっぱい。
2012/01/06(金) 13:58:48.37上の方法はあるプロセスが101行目を出力しようとするまで生きてないか?
0078名無しさん@お腹いっぱい。
2012/01/06(金) 15:00:15.020079名無しさん@お腹いっぱい。
2012/01/06(金) 15:01:39.72困るかどうかは>>74に聞かないとわからん。
0080名無しさん@お腹いっぱい。
2012/01/06(金) 19:01:28.820081名無しさん@お腹いっぱい。
2012/01/06(金) 19:36:33.320082名無しさん@お腹いっぱい。
2012/01/06(金) 23:10:50.34そんなもん、動きゃいいんだよ
0083名無しさん@お腹いっぱい。
2012/01/06(金) 23:23:54.660084名無しさん@お腹いっぱい。
2012/01/07(土) 09:35:59.680085名無しさん@お腹いっぱい。
2012/01/07(土) 10:56:05.85ありがとうございます。
最初の問題については、たとえ延々と最初のプロセスが出力をたれ流していても、
パイプがなくなれば自動的に殺されるんですね。
後者の問題の場合、事前にプロセスIDが分からないのが問題なのですが、
シェルで、起動した命令のプロセスIDを取得する方法があるのでしょうか?
0086名無しさん@お腹いっぱい。
2012/01/07(土) 11:44:27.31だから $! だって >>76 が回答してるだろ
0087名無しさん@お腹いっぱい。
2012/01/07(土) 15:13:56.59あるプロセス &
hoge=$!; sleep 100; kill -9 $hoge
0088名無しさん@お腹いっぱい。
2012/01/07(土) 15:30:29.18変数が無駄だな
sleep 100; kill -9 $!
だけで桶。
あと、>>76 の回答でわからない人間にはサンプルを示しても無駄。
0089名無しさん@お腹いっぱい。
2012/01/07(土) 15:41:35.400090名無しさん@お腹いっぱい。
2012/01/07(土) 15:43:03.63わかってないのはオマエ sleepのプロセスIDは $! に入らない。
0091名無しさん@お腹いっぱい。
2012/01/07(土) 15:45:16.77正解者に間違った指摘する >>89 とかは書き込み自粛してくれ
0092名無しさん@お腹いっぱい。
2012/01/07(土) 15:49:41.76>>88 で桶。
009389
2012/01/07(土) 15:55:44.03すっげぇ数の訂正レスがついて嬉しい。ありがとう。
0094名無しさん@お腹いっぱい。
2012/01/07(土) 19:01:59.74自作自演(・A・)イクナイ!!
0095名無しさん@お腹いっぱい。
2012/01/07(土) 19:02:53.770096名無しさん@お腹いっぱい。
2012/01/07(土) 19:42:18.58ファイルにある特定の文字でファイルを分割したいと考えています
何とか調べて
例えばkiritoriと言う文字の箇所からsample.txtを2つに分割するのに
grep -n kiritori sample.txtで行番号がわかりますので
split -ln sampl.txtによりxaa,xabの二つのファイルに分割することがわかりました
ここでお尋ねしたいのですが
grepとsplitをまとめて処理するためにはnをsplitに引き渡す方法がわかりません
どうかよろしくお願いいたします
又他の方法が有りましたらお教えください
0097名無しさん@お腹いっぱい。
2012/01/07(土) 20:12:54.18d
}' sample.txt > xbb
0098名無しさん@お腹いっぱい。
2012/01/07(土) 21:06:49.01早速のレス有難う御座いました。
おかげでファイルを分割できるようになりました
cutで行番号のみ抜き出したり
sedは文字変換のみの認識しかなかったりで
にわかもんはあなたのスクリプト見ただけで
すごいなと言う感想のみです
たまには勉強します
有難う御座いました
0099名無しさん@お腹いっぱい。
2012/01/08(日) 17:43:52.18dateでYYYYMMを取得してきます。(例:201201)
1月から9月の場合には0を消去して、YYYYMで表示させたいのです。(例:20121)
自分でも一応下のようにして出来たのですが、もっと簡単に作る方法はないでしょうか?
lm=`date "+%Y%m"`
ll=`echo ${lm}|cut -c 1-4`
mm=`echo ${lm}|cut -c 5-6`
if [ ${mm} -lt 10 ];then
mm=`echo ${mm}|sed s/0//`
fi
lm=${ll}${mm}
echo ${lm}
0100名無しさん@お腹いっぱい。
2012/01/08(日) 17:47:39.30date +%Y-%m | sed s/-0//
0101名無しさん@お腹いっぱい。
2012/01/08(日) 17:49:53.71それ、10月以降が駄目だろw
date +%Y%m | sed 's/-0//; s/-//'
0102名無しさん@お腹いっぱい。
2012/01/08(日) 17:51:50.20自演乙 おちつけ
date +%Y-%m | sed 's/-0//; s/-//'
0103名無しさん@お腹いっぱい。
2012/01/08(日) 17:58:24.55おぉ、もう返答が。
そうか、消したい0の前に何か付け足すことで限定すれば良いんですね。
ありがとうございました。
0104名無しさん@お腹いっぱい。
2012/01/08(日) 18:03:08.42せっかくbashならdateコマンド以外、内部コマンドだけでもできるよ。
a=($(date +'%Y %m'))
echo ${a[0]}${a[1]#0}
0105名無しさん@お腹いっぱい。
2012/01/08(日) 18:57:49.32case $month in
0?) month=${month##0} ;;
esac
lm=`date +%Y$month`
or if you are using GNU date
date +%Y%-m
0106名無しさん@お腹いっぱい。
2012/01/08(日) 19:15:43.51>>105 最終行の
date +%Y%-m
が最適解だな。
ところで、>>105 前半のcase文は意味ない。場合分けせずに ${month#0}だけでよい。
0107名無しさん@お腹いっぱい。
2012/01/08(日) 19:52:34.83man dateで>>105さんのやり方がしっかり書いてありました…
お恥ずかしい。
皆様ありがとうございます。
0108名無しさん@お腹いっぱい。
2012/01/08(日) 22:51:02.00今まで expr で 0 を消してた。
0109名無しさん@お腹いっぱい。
2012/01/09(月) 08:29:51.48echo $(date +%Y)$(expr $(date +%m) + 0)
0110名無しさん@お腹いっぱい。
2012/01/09(月) 08:53:59.96expr `date +%m` : "0\?\(.\+\)"
0111名無しさん@お腹いっぱい。
2012/01/09(月) 09:00:41.79$ echo $((08+0))
-bash: 08: value too great for base (error token is "08")
0112名無しさん@お腹いっぱい。
2012/01/09(月) 09:08:48.76シェルの算術式とかでは頭の0は8進数扱いだからな。
exprなら8進数とはみなさないので、expr 08 + 0 とかやって0を消すのは常識テクニック。
0113名無しさん@お腹いっぱい。
2012/01/13(金) 10:37:37.37sed -e "s/ //g" temp.txt
↑ここに/(スラッシュ)を含む文字列を入れたいときはどうしたらいんですか?
0114名無しさん@お腹いっぱい。
2012/01/13(金) 10:46:55.510115名無しさん@お腹いっぱい。
2012/01/13(金) 11:12:47.98>>114のようにするか、区切り文字を"/"から"@"とかの他の文字に変える
純粋なsedの話しなのでスレち
ttp://toro.2ch.net/test/read.cgi/unix/1085730992/
0116名無しさん@お腹いっぱい。
2012/01/19(木) 17:43:20.44中間ファイルを作ってディレクトリ名と日付の比較を行なっての処理は一応出来たのですが、出来ればfind xargsで一発で出来る形にしたいです
中間ファイル無しで上記のような処理は実現できるでしょうか?
0117名無しさん@お腹いっぱい。
2012/01/19(木) 17:54:34.58yyyymmddHHMMSS形式なら単純な数値と考えて大小比較すればいいね。
比較するのに中間ファイルは要らない。
0118名無しさん@お腹いっぱい。
2012/01/19(木) 18:05:56.97エスパーカが足りないなw
中間ファイルは条件にマッチしたディレクトリリストのファイルかと
tarじゃなくてcpioなら Solaris findの -cpioオプションで一発かな
0119名無しさん@お腹いっぱい。
2012/01/19(木) 18:35:22.450120名無しさん@お腹いっぱい。
2012/01/19(木) 18:52:00.33-newer のたぐいはまさに中間ファイルが必要ですが
0121名無しさん@お腹いっぱい。
2012/01/19(木) 18:56:59.650122名無しさん@お腹いっぱい。
2012/01/19(木) 19:01:28.69どんな内容の中間ファイルをどのような目的で作成しているのか
それがわかれば回答する側もエスパーにならなくていいからね
0123名無しさん@お腹いっぱい。
2012/01/19(木) 19:02:52.930124名無しさん@お腹いっぱい。
2012/01/19(木) 19:04:30.79どうやって?
0125名無しさん@お腹いっぱい。
2012/01/19(木) 23:32:23.93/home/my/st/1.txt
1 暑い
2 寒い
3 少し暑い
4 少し寒い
5 すごく暑い
6 すごく寒い
/home/my/st/2.txtに書き込ませたいですのですがどう書けば良いでしょうか?
0126名無しさん@お腹いっぱい。
2012/01/19(木) 23:50:32.460127名無しさん@お腹いっぱい。
2012/01/19(木) 23:57:33.44わお
そんなに短く出来るんですね
感謝です!!
■ このスレッドは過去ログ倉庫に格納されています