[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 2chのread.cgiへ]
Update time : 05/25 03:18 / Filesize : 212 KB / Number-of Response : 865
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

シェルスクリプト総合 その19



1 名前:シェルスクリプトライター mailto:sage [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。
  src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/
  heirloom.sourceforge.net/sh.html
・csh/tcshのシェルスクリプトは推奨されません。
 (理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
 manや参考リンクを見ましょう。
 aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
 正規表現の話題はスレ違い(正規表現スレへ)

□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。

前スレ
シェルスクリプト総合 その18
hibari.2ch.net/test/read.cgi/unix/1308195527/

次スレは >>970 で。

587 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 12:40:39.27 ]
>>586
本当に >>586 のとおりに実行したのなら *.txt は展開される。
展開されないのはカレントディレクトリに *.txt にマッチするファイルがないから。
すでにファイルがなければ展開しようがない。

588 名前:586 mailto:sage [2012/03/19(月) 12:56:05.81 ]
>>587
ヒントありがとうございます

oppai.txt がある場合⇒ oppai.txtにタッチ
oppai.txt がない場合⇒ *.txt を作成

という動きになりました
まーこれはこれで使い物になりませんわ

589 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 13:11:29.40 ]
存在をチェックしてからtouchすればいいじゃない。

590 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 13:13:49.05 ]
>>588
もし「存在しなければ作成したくない」という意図なら、

touch -c $B で桶。

591 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 13:45:15.79 ]
>>586
エスパーすると、

A=*.txt
B=$A
mv $A /どこか
touch $B

みたいなことをやりたいのでは?

それなら、
A=`echo *.txt`
mv $A /どこか
touch $A

で桶。変数はAだけでよい。

592 名前:586 mailto:sage [2012/03/19(月) 14:20:52.93 ]
>>590
天才や・・・ UNIX板には天才がたくさんいる
みんなありがとう

593 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 14:28:02.20 ]
いや、みんなは普通だよ。

594 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 15:43:16.30 ]
>>591のアホさが光るな。

595 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 15:45:13.28 ]
>>586
これなんでBをはさんでるの?



596 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 17:56:07.30 ]
おそらく A=*.txt で *が展開されなかったから
Bに代入し直せば再解釈されて展開されると勘違いしたのだろう

597 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 19:53:24.01 ]
結局、どこで展開されたんだろうね

598 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 19:56:34.87 ]
ん? A=*.txt でも B=$A でも 変数直接代入時は展開されないよ。
touch $B みたいにクォートなしで参照した時に初めて展開される。

599 名前:586 mailto:sage [2012/03/19(月) 19:58:57.99 ]
>>598
ありがとう。それだけが心残りだったんだ

600 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 20:04:56.95 ]
shを作ったBourneは天才だね。

601 名前:名無しさん@お腹いっぱい。 [2012/03/19(月) 20:08:20.98 ]
あのソースコードは勘弁して欲しい。


602 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/19(月) 21:12:40.16 ]
ソース読んだのか あんたスゲーや

603 名前:名無しさん@お腹いっぱい。 [2012/03/19(月) 22:06:26.63 ]
ソースコードつーか、これな。
ttp://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h

604 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 08:01:57.14 ]
x68000.q-e-d.net/~68user/unix/pickup?keyword=test&target=command
のサイトに、
#!/bin/sh
read input
if [ $input = 'q' ]; then
echo QUIT
fi
と言うシェルスクリプトを参考に
if [ "$input" = 'q' ]; then
と $input をダブルクォートで囲めばよい。しかしまだ落とし穴はある。たとえば "!" を入力すると、
[: =: unexpected operator
とまたしてもエラーになってしまう。これは "$input" が "!" であるため、
if [ ! = 'q' ]; then
として扱われたからだ。
ってありますけれど、何度!を入力しても、
[: =: unexpected operator
って表示されません。
それに、
$ test !c = 'q' ; echo $?
test cd /etc = 'q' ; echo $?
test: too many arguments
とエラーが表示されます。
どのような解釈をすると、!cがtest cd /etcに置換されるのでしょうか?

605 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 09:04:17.23 ]
> [ ! = 'q' ]
これはそのように解釈するtestもあるから注意しろ。くらいでいいと思う。

> どのような解釈をすると、!cがtest cd /etcに置換されるのでしょうか?
ヒストリ置換だろ。



606 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 17:36:56.09 ]
>>605
今の時代、そのエラーが出るshを使っている人、いるのかね?

607 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 17:41:15.64 ]
今の時代、
[ ! = ! ]
[ [ = [ ]
[ ] = ] ]
[ = = = ]
[ -f = -f ]

など、すべて文字列の比較として期待通りに動作する

608 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 17:51:22.47 ]
しかし未だに [ x"$hoge" = x"yes" ] などと書いてる人を見掛けるな
#!/bin/bashとか書いてるのに

609 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 19:57:58.15 ]
スクリプトインジェクション対応だよ

610 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 21:45:56.60 ]
[ "$hoge" = yes ] だとして具体的にどうインジェクトするんだよ

611 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/20(火) 23:34:08.60 ]
>>610

612 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 09:04:25.40 ]
>>611
どうインジェクションするか解説お願いします

613 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 10:08:32.37 ]
hoge=']; /bin/sh;'

614 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 10:47:17.62 ]
ってゆーか、こういう場合は

case "$hoge" in
yes) ...;;
esac

って書くよね、ふつー。[Yy][Ee][Ss] なんかに変えるのも簡単だし。


615 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 11:14:27.91 ]
>>613
>>610はダブルクオートで囲ってるから、[コマンドの第一引数として$hogeの中身が渡るんで、そのhogeの値はそのまま[コマンドが解釈する。
どうあがいてもインジェクションなんて無理だと思うんだが。



616 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 11:26:14.79 ]
てきとーに言ったんだろ。
もうカンベンしてやれ。

617 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 12:19:06.39 ]
本人乙

618 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 13:26:55.78 ]
違うよ。

619 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 13:38:09.35 ]
最近のJavaScriptのようにeval使いまくりで威張る奴か。

620 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 14:28:05.05 ]
>>619
座布団

621 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 15:37:01.15 ]
全部持ってって〜

622 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 19:24:26.73 ]
>>606
$ busybox ash
$ hoge=!
$ if [ "$hoge" = 'q' ]; then echo QUIT; fi
ash: q: unknown operand

623 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 22:56:44.16 ]
https://uec.usp-lab.com/SHELL_TIPS/CGI/SHELL_TIPS.CGI?POMPA=TIPS_not_while

>シェルスクリプトに制御構文が増えることを極力避けるように様々な工夫をしている。
>制御構文を避ける理由はコードが読みにくくなるためだ。
>これまで制御構文whileやforのはずし方について書いてきた。
>処理速度を高速化するためにwhileやforをコマンドに置き換えるというのは、
>それなりの効果が期待できる方法だ。
>シェルスクリプトに制御構文であるforやwhileが出てきたら、
>何か避ける方法がないか探してみるとより高速なスクリプトが書けるようになるかもしれない。
ってかいてあって、いろんな例が書いてあったり、
変なパッケージ(python製)を入れて、そのコマンドを使ったりしてるんですね。
僕は制御構文外すと逆に可読性がおちたり、
pythonで書かれたコマンドを呼び出すより、シェルスクリプトで制御構文書いた方が
早いと思うんですけど、おかしいですかね?

624 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 23:01:45.31 ]
質問です。

以下のようなファイルがあるとします。
-----------------
1. aaa hello
2. bbb
3. ccc
4. ddd hello
5. ddd hello
6. eee hello
-----------------
このファイルの2行目から5行目に限定して、helloをgood byに変更したいです。
どのようなやりかたがありますでしょうか?
sedを使えばいいのかなと思うのですが。。



625 名前:名無しさん@お腹いっぱい。 [2012/03/21(水) 23:09:05.42 ]
お前はマニュアル読むという事を考えたことが無いのか?



626 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 23:34:20.22 ]
>>624
うん、sedの超基本的な使い方で出来る

627 名前:名無しさん@お腹いっぱい。 [2012/03/21(水) 23:34:53.13 ]
sedを使えばいいと思うよ



628 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/21(水) 23:41:30.82 ]
>>623
そのページを見て思ったことは、xargsは便利だね、くらい

629 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 00:58:20.98 ]
>>623
シェルスクリプトに限らず、プログラム書く時に(一部の)制御構文を使わないってのは個人的に良くやる。効率とか性能とか抜きで。
ゲームの縛りプレイみたいなもんだけど、意外なテクニックを発見したりできて楽しめるよ。おすすめ。
上司や同僚に見つかったら>>623のサイトみたいな適当なウンチクで誤魔化せばOK。



630 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 01:14:19.58 ]
>>624
sed で 2行目から5行目は 2,5。
hello を good byに置換するには s/hello/good by/
接続すると 2,5s/hello/good by/


631 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 02:23:18.01 ]
>>629
BASICのころはあったけどな。
if文分岐とかで速度差が出ないようにするとかで。
今はそういうのする必要ないけど。

632 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 08:22:33.32 ]
PerlやC#、COBOL、Fortran、アセンブリなんかも、見慣れてなければ読みにくく
感じるものさ

633 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 08:28:41.72 ]
Whitespaceもな。

634 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 09:18:49.18 ]
俺はsedが嫌いなので、できるだけperlを使うようにしている

635 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 09:56:14.04 ]
それは報告しなくてもいいです。



636 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 11:24:16.01 ]
kshで待ち行列を作りたいんですが、どうしたらいいでしょう?

基本動作はキューなんですが、
1 2 3
↓1を実行
2 3

1 2 3
↓2を実行
1 3
としたいです

unset 配列[N]でインデックスを詰めてくれればこんなの楽勝なのに…

637 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 11:37:02.12 ]
>>636
ファイルにしたらいい

638 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 20:00:10.46 ]
位置パラメータ使う。

$ set -- 1 2 3 4
$ shift
$ echo $@
2 3 4
$ set -- 1 2 3 4
$ set -- $1 ${@:3}
$ echo $@
1 3 4



639 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 20:22:13.25 ]
>>636
unset array[N] で要素をunsetした後に、

array=(${array[@]}) でセットしなおせばインデックスは詰まる。

>>638 とは違って位置パラメータを壊さずに済む。

640 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/22(木) 21:29:35.34 ]
>>639
かっこういい

641 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/23(金) 22:05:53.20 ]
シェルスクリプト学び始めたばかりの初心者です。

・ファイルを指定フォルダ内へコピー
・同名ファイルが存在する場合は、
既に存在するファイル名を「ファイル名 (1)」へ変更し、
既に「ファイル名 (1)」が存在しているのであれば、
それをさらに「ファイル名 (2)」へ変更し、、、(繰り返し)

というシェルスクリプトを書きたいんですが、

既に「ファイル名 (*)」が存在する場合に*の数字を
どのようにすれば知ることができますか?

*さえ知れたらexprを使えば出来るとは思うのですが...
アドバイスお願いします。

642 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/23(金) 22:27:01.94 ]
>>641
逆に考える。

変数iとかに1を入れておいて、

"ファイル名($i)" が存在したら
iをインクリメントして "ファイル名($i)" にリネームする。

643 名前:名無しさん@お腹いっぱい。 [2012/03/23(金) 22:28:54.51 ]
再帰使わないとややこしいことになりそうだな。


644 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/23(金) 22:32:05.36 ]
最小の空きを使うんでいいの?
i=1; while [ -f "file($i).txt" ]; do i=`expr $i + 1`; done; echo $i

645 名前:名無しさん@お腹いっぱい。 [2012/03/23(金) 22:52:22.20 ]
「それを」が何を指すかによる。




646 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/23(金) 22:56:33.59 ]
GNU cp なら --backup=numbered とか?

647 名前:名無しさん@お腹いっぱい。 [2012/03/24(土) 01:18:46.16 ]
なんか見覚えがある処理だと思ったが logrotate かいな。

648 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 10:30:46.53 ]
>>641
つまりアヌスを知りたいと……教えてあげよう

649 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 18:23:06.74 ]
>>641
実機が無いので試せないけど・・・

第一引数:コピー対象ファイル名(絶対パス指定)
第二引数:コピー先ディレクトリパス

#!/bin/ksh
FILE_NAMEW=`basename ${1}`
COUNT=1
TARGET_FILE=${2}/${FILE_NAME}

if [[ -e ${TARGET_FILE} ]]; then
while true
do
if [[ -e "${TARGET_FILE}(${COUNT})" ]]; then
COUNT=`expr ${COUNT} + 1`
else
cp ${1} ${TARGET_FILE}(${COUNT})
break
fi
done
else
cp ${1} ${TARGET_FILE}
fi
exit 0


650 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 18:40:54.37 ]
突っ込みどころ多いな

651 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 18:48:18.47 ]
もっと単純にこうだろ。
第1引数: コピー元ファイル(絶対/相対path関係なし)
第2引数: コピー先ファイル(ディレクトリではない)

#!/bin/sh

FILE=$2

if [ -f "$FILE" ]; then
i=1
while [ -f "$FILE($i)" ]; do
i=`expr $i + 1`
done
FILE="$FILE($i)"
fi

cp "$1" "$FILE"

652 名前:641 mailto:sage [2012/03/24(土) 21:11:20.76 ]
皆さんアドバイスありがとうございました。
642さんの意見を参考に書いていたら、
651さんとほぼ同じようなものが書けました。

勉強になりました!

653 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 22:20:08.70 ]
その書いたものをさらしてくれると
みんなも勉強になるんだけどなぁ

654 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/24(土) 22:34:45.96 ]
#!/bin/bash

[ -e "$2" ]&&{ i=0; while [ -e "$2($((++i)))" ];do :;done; set "$1" "$2($i)";}
cp "$1" "$2"

655 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 10:39:31.72 ]
rm -rf -- *
ってどういう風に解釈すれば良いんですか?
-- って正規表現ですか?
*はファイル名ですか?



656 名前:名無しさん@お腹いっぱい。 [2012/03/25(日) 10:59:50.45 ]
>>655
その * は glob。シェルが解釈する。
シェルが展開して rm に渡す。

-- は正規表現でも何でもなくて、ただの --。
シェルは特に何もしない。
そのまま rm に渡される。

657 名前:名無しさん@お腹いっぱい。 [2012/03/25(日) 11:00:45.80 ]
rm が -- をどう解釈するかは man rm に載ってるはず。

658 名前:名無しさん@お腹いっぱい。 [2012/03/25(日) 11:28:39.15 ]
- で始まるファイル名(コマンドからはオプションに見える)に
マッチしたときのための策だな。


659 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 11:51:49.52 ]
でも rm -- が使えるのは GNU rmだけだから、使わない方がいいな。

660 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 12:14:56.30 ]
>>659
調べたらBSD系はgetopt(3)つこうてるから--大丈夫だよと書いてあったんだけど
他のUNIXはまた違うの?

661 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 12:24:48.03 ]
BSD以外のUNIXってあるの?

662 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 13:38:40.68 ]
ねーよんなもん

663 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 13:56:37.10 ]
Solarisのmanには、BSDユーザーのために仕方なく -- が使えるようにしてあるが、
将来は -- が使えなくなるので注意、と書いてあるね。

664 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 18:55:04.62 ]
ワイルドカードを使うときは
rm ./*
みたいにすれば引数の先頭が - になることはない。
--が使える保証がなければこっちで。

665 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 20:43:30.34 ]
この手の問題って rmだけじゃなく cp mv ln等全部なんだよな。

で、-- が使えない ln で、-sという名前を指しているsymlinkを作ろうと、

ln -s ./-s hoge ってやると、hoge -> ./-s というsymlinkができて、
symlink自体に ./ が含まれてしまって美しくない。
-- が使えない条件で 、hoge -> -s は作れないものか。



666 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 22:24:57.35 ]
リンク作る部分をスクリプト言語に投げるとかは?
じゃあ全部スクリプトでやれよみたいな話になりかねんからダメかね

667 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/25(日) 23:41:27.50 ]
>>664
昔からUnixやってる奴は普通そのやり方だよな
--指定してても、引数に./*でなく*を指定するのは違和感を感じる

668 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/26(月) 06:20:04.43 ]
特定のフォルダのpngファイルを見つけて

「◯◯◯.png」というファイルを見つけました

と表示させたいのですが、なるべくコンパクトにするにはどのようにすればいいでしょうか?
自分のやり方だとbasenameで失敗してうまく表示されません
あと、そのフォルダにpngファイルがなかった場合は何も表示しないようにしたいです。

find ${DIR}/ -name "*.png" -exec echo "「`basename {}`」というファイルを見つけました" \;


669 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/26(月) 06:44:41.40 ]
>>668
find "$DIR" -name '*.png' -printf '「%f」というファイルを見つけました¥n'

670 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/26(月) 07:06:33.81 ]
>>668
`basename {}`はfind実行より先に展開されてしまうので、
{}という文字列のbasenameが実行されて無意味になっているのが原因。

GNU findなら >>669 でよし。

671 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/26(月) 07:46:41.98 ]
>>668
find "$DIR" -name '*.png' -exec sh -c 'for f;do echo 「`basename "$f"`」というファイルを見つけました;done' - {} +

672 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/26(月) 14:20:40.93 ]
>>669>>670>>671
おかげさまでできました!
ありがとうございました!!

673 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/27(火) 22:52:24.44 ]
質問です。

開始日付と終了日付を指定したら、その間の日付を出力するスクリプトを作りたいです。
イメージとしては以下のような感じです。
$ ./hoge.sh -s 20120301 -e 20120303
20120301
20120302
20120303

以下の処理までは作ったのですが、ここから先が思いつきません。
---------------------------------------------
$ cat hoge.sh
#!/bin/sh

while getopts s:e: option
do
case $option in
"s")
start_date=$OPTARG
;;
"e")
end_date=$OPTARG
;;
*)
;;
esac
done
---------------------------------------------

よろしくご教示お願いします。


674 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/27(火) 23:18:59.00 ]
日付まわりはシェルでやるとめんどいから
perlとか使っちゃう。

675 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/27(火) 23:30:44.14 ]
> 以下の処理までは作ったのですが、ここから先が思いつきません。

dateをつかってこんな感じかな

ステップ1. 今日の日付を20120301のように出力しよう
ステップ2. 20120301のような日付を、UTCエポックからの秒数に換算しよう
ステップ3. UTCエポックからの秒数を、20120301のような日付に変換しよう
ステップ4. 20120301のような日付を受け取り、その翌日の日付を出力しよう
ステップ5. ループを回して指定範囲の日付を全て出力しよう

※UTCエポックは 1970-1-1 00:00:00 UTC



676 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/27(火) 23:42:28.28 ]
>>673
bash、GNU date依存

#!/bin/bash

while getopts s:e: opt; do
case "${opt}" in
's') stime=$(date -d "${OPTARG}" '+%s') ;;
'e') etime=$(date -d "${OPTARG}" '+%s') ;;
esac
done

t=${stime}

while (( ${etime} >= ${t} )); do
date -d @${t} '+%Y%m%d'
t=$(( ${t} + (60 * 60 * 24) ))
done

677 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/28(水) 00:15:25.48 ]
>>676
bashならこっち
for (( t = stime; etime >= t; t += 60 * 60 * 24 )); do
date -d @${t} '+%Y%m%d'
done


678 名前:676 mailto:sage [2012/03/28(水) 00:53:33.92 ]
添削ありがとう

679 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/28(水) 06:47:17.46 ]
>>676 >>677 でOKだね。
そんな中、何の解答にもヒントにもなってない >>675 って・・・

680 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/28(水) 06:56:04.85 ]
>>676 >>677
わざわざepochからの秒数に直さなくても、日付だけで行けるよ。


#!/bin/bash

while getopts s:e: opt; do
case $opt in
s) stime=$OPTARG;;
e) etime=$OPTARG;;
esac
done

for ((t = stime; etime >= t; t=$(date -d "$t 1 day" '+%Y%m%d'))) {
date -d "$t" '+%Y%m%d'
}

681 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/28(水) 07:04:16.81 ]
>>680
forループ中、dateが1回無駄になってる。せっかく$tに入ってるのでそれ使え。

for ((t = stime; t <= etime; t=$(date -d "$t 1 day" '+%Y%m%d'))) {
echo "$t"
}

682 名前:680 mailto:sage [2012/03/28(水) 07:10:47.88 ]
添削ども

683 名前:名無しさん@お腹いっぱい。 [2012/03/30(金) 14:34:15.36 ]
標準出力に日付をつけたいんだけど
かっこいい方法ありますか?

684 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 14:51:40.88 ]
エスパー、日本語解読しろ

685 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 14:55:44.65 ]
>>683
#!/bin/sh

while IFS= read -r line; do
echo "`date`: $line"
done



686 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 15:42:18.34 ]
>>685
ありがとうございます

687 名前:名無しさん@お腹いっぱい。 mailto:sage [2012/03/30(金) 15:44:45.94 ]
        ∧∧
       ヽ(・ω・)/   ズコー
      \(.\ ノ
    、ハ,,、  ̄
     ̄






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧]( ´∀`)<212KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef