ジメジメする梅雨のお悩み、一挙解決! >>

#!/bin/sh
case $1 in
[1-9])echo $1;;
[1-9]*10+[1-9])echo $1;;
*)echo "エラー";;
esac

シェルの第一引数が1~99だった場合、その引数を表示するというものを作りたいのですが、
これだと二桁の数字を入力した際に*)echo "エラー";;の方へ行ってしまいます。
これではだめでしょうか?
またもしcase文でこういった事ができるのなら今は2行に渡って書いていますが、
これを1行にして書くことなどはできるのでしょうか?

A 回答 (1件)

「1~99」の中に 50 なんてのは入る?


case は文字列として (厳密にはファイル名として) 比較してるよん.
だから 2つ目は
[1-9][0-9])
じゃないとダメ.
まあ, | でパターンをつないで
[1-9]|[1-9][0-9]) echo $1;;
でいいんだろうけど.
    • good
    • 0
この回答へのお礼

なるほど!そういえば一桁目0のことをあまり考えてませんでした。
そういうことでしたか・・・。
パターンのつなぎ方もとても参考になりました。
ありがとうございました。m(_ _)m

お礼日時:2009/03/03 12:46

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qsedの置換文字に変数を使用したいのですが・・・

あるファイルの特定の文字を変換し、上書きをする処理を行いたいのですが、sedの置換文字に変数が渡せなくて困っています。

例:
X="a"
Y="b"
echo test.txt | sed 's/${X}/${Y/g}' >test.txt

sedでは置換文字に${X}といった変数を使用することはできないのでしょうか?

Aベストアンサー

' ・・・' で囲まれた中の$はそのままドルマークです。変数展開をするなら、'・・・'で囲んではいけません。

何も囲まないか、"・・・"で囲むかです。

Qシェルスクリプトでファイル内の数値文字列を数値として扱うには

失礼します。
シェルスクリプトでファイル内のテキスト(数値文字列)を取得して、それを使って計算するにはどうすれば良いでしょうか?

str:ファイル内のテキスト(数値文字列)

res=$(( $str + 1 ))

・エラー
")syntax error: invalid arithmetic operator (error token is "


よろしくお願いします。

Aベストアンサー

bashをご使用と判断して

res=$(( $str + 1 ))
ではなく、
res=$(( str + 1 ))
だと思います。

> exprもやってみたのですが、処理が遅くなるので使いません。
興味があって以下のシェルで検証してみました。

#!/bin/bash

str=1
i=0

echo 'Using $((str + 1))'
date '+%H:%M:%S.%N'

while [ $i -lt 10000 ]
do
str=$(( str + 1))
i=`expr $i + 1`
done

date '+%H:%M:%S.%N'

exit

$ ./test.sh
Using $((str + 1))
09:18:46.290418000
09:18:56.929345000
これをexprに書き換えたところ
$ ./test2.sh
Using expr
09:19:00.302748000
09:19:19.259990000

exprだと19秒ですが、$(( 演算 )) だと10秒程度なので、演算が多くなれば確かにexprは不利ですね。

bashをご使用と判断して

res=$(( $str + 1 ))
ではなく、
res=$(( str + 1 ))
だと思います。

> exprもやってみたのですが、処理が遅くなるので使いません。
興味があって以下のシェルで検証してみました。

#!/bin/bash

str=1
i=0

echo 'Using $((str + 1))'
date '+%H:%M:%S.%N'

while [ $i -lt 10000 ]
do
str=$(( str + 1))
i=`expr $i + 1`
done

date '+%H:%M:%S.%N'

exit

$ ./test.sh
Using $((str + 1))
09:18:46.290418000
09:18:56.929345000
これをe...続きを読む

Qbashなどのシェル変数の値に改行を含める事は可能でしょうか?

タイトルの通りですが、通常のシェル変数の値として

 [prompt]$ aaa="bbb<改行>ccc"

のようなセットを行い、

 [prompt]$ echo $aaa
 bbb
 ccc
 [prompt]$

のような結果を得たいのですが、可能でしょうか。

Aベストアンサー

可能です.
というか,やってみたら出来ることがわかると思います.こんなところで聞くより早い.
なお,sh/bash系では改行文字は特にエスケープせずそのまま入れられます.

aaa='bbb
ccc'

Qgrepで検索文字列が完全一致した行だけ取り出す方法

grepの文字列検索で検索文字列が単語として、完全一致した行だけ取り出す方法はないでしょうか?

通常は
grep hoge hoge.txt

と打つと、hogeが含まれる行が出力されますが、今回は含まれる行ではなくて完全に文字列が一致した行だけ取り出したいのです。

例えばhoge.txtの中に
cc ghoge
kkl hogem
jjll hoge
という3行があったとしたら最後の行でhogeという文字が空白で区切られた行だけ取り出したいのです。

何かよい方法があれば教えてください

Aベストアンサー

-w オプションじゃだめですか?

参考URL:http://www.linux.or.jp/JM/html/GNU_grep/man1/grep.1.html

Q正規表現または構文で数値の範囲の指定

if($a =~「1~20」までの数字又は「1_1~1_20」~「20_1~20_20」までの数字){
OK;
}else{
NO;
}

を正規表現や条件分岐を使って範囲指定したいのです。

[1-9]
ですと111等も対象になりますし、{n,}とした場合でも数値の1~20までとは出来ないようで・・・。
また正規表現では_の扱いが今一わからない状況で
更に()と?を使って思考錯誤を繰り返しているうちに
[]//の用途がだんだんと分からなくなってしまいました。

各用途については調べ整理しているつもりなのですが
今回のようなケースに関して参考になる例を見つけられず質問させて頂きました。

ご掲示頂けませんでしょうか。宜しくお願いします。

Aベストアンサー

#3>各細部についての意味
/^(?:[1-9]|1\d|20)(?:_(?:[1-9]|1\d|20))?$/
/^~$/
^:先頭から
$:最後尾までの間
にある、つまり、今回の対象文字列だけが入っている。(他の文字列に埋もれているのを対象としているのではない)
(?:~):グループ化する、()と違うのは$1などに値を設定しないこと、単にグループ化する時に使う。
[1-9]:1から9までの一文字を表す
\d:[0-9]の意味
[1-9]|1\d|20:|は、orの意味、1~9であるか10~19(1で始まる0~9)であるか20であるの意味
(~)?:~が0回または1回ある

Q~以外を削除する場合(rmコマンド)

linuxのコマンドで
~以外のファイル、ディレクトリを全て削除したい時は
どのような記述をすれば良いのでしょうか?
シェルスクリプトではなくrmコマンド1つで削除したのいですが…

例: tar以外のファイル・ディレクトリを
   すべて削除したい場合など

どなたかご存知の方がいらっしゃったら
教えてください。よろしくお願い致します。

Aベストアンサー

rm コマンドのみという訳にはいきませんが基本的なコマンドを組み合わせると実現可能と思います。

「名前が tar で終わるもの以外のファイル・ディレクトリを削除する」場合だと

ls | grep -v -E 'tar$' | xargs rm -r

となります。

ファイルの一覧を取得し ( ls )
'tar'で終わるもの以外を抽出し ( grep )
その結果を rm -r の引数に指定して実行 ( xargs )

という流れです。

ファイルを削除するような操作については失敗するとダメージが大きいので、事前にテストして動作を確認すると良いとおもいます。また rm -r -i としてそれぞれのファイルについて、削除の問い合わせをするのも有効です。

Qシェルスクリプトの変数の制限?

こんにちは。
シェルスクリプトで謎の現象が起こりまして悩んでいます。

現在、
#!/usr/bin/sh
var='foo'
if [ $? - eq - 0 ]; then
mv xxx.bz2 xxx.old.bz2
echo $var | bzip2 -z >xxx.bz2
fi
といった感じのシェルスクリプトを動かしています。
これを手作業で、
foo | bzip2 -z >xxx.tmp.bz2
とやると、xxx.tmp.bz2は1.2MB程度のファイルとなるのですが、
上記のシェルスクリプトで実行すると8KBほどにしかなりません。

シェルスクリプトの変数のサイズの制限かと思い、調べてみましたが、
特に制限があるとの資料はみつかりませんでした。
fooの出力がバイナリなので、そのせいかとも思ったのですが、unix系列の場合、windowsと違ってテキスト/バイナリの区別はないはずだしということで、理由がわかりません。

シェルの変数には、やはり制限があるのでしょうか?それとも他の理由でしょうか。ご存知の方がいらっしゃいましたら、ご教示お願いします。

環境はsolarisです。バージョンは、
$ cat /etc/release
Solaris 10 8/07 s10s_u4wos_12b SPARC
Copyright 2007 Sun Microsystems, Inc. All Rights Reserved.
Use is subject to license terms.
Assembled 16 August 2007

です。よろしくお願いします。

こんにちは。
シェルスクリプトで謎の現象が起こりまして悩んでいます。

現在、
#!/usr/bin/sh
var='foo'
if [ $? - eq - 0 ]; then
mv xxx.bz2 xxx.old.bz2
echo $var | bzip2 -z >xxx.bz2
fi
といった感じのシェルスクリプトを動かしています。
これを手作業で、
foo | bzip2 -z >xxx.tmp.bz2
とやると、xxx.tmp.bz2は1.2MB程度のファイルとなるのですが、
上記のシェルスクリプトで実行すると8KBほどにしかなりません。

シェルスクリプトの変数のサイズの制限かと思い、調べてみましたが、...続きを読む

Aベストアンサー

変数と言うより、シェルのコマンドライン長の制約の気がします。
圧縮して1.2MBということはfooの出力は数十~数百MB?
外部コマンド起動の場合は、Linuxだと128KBが上限のようですが、echoは組み込みコマンドなので、もっと上限は大きいはずです。
変数に200MBいれてみると、入りましたけど、echoしてみるとbashが落ちました。SolarisだとOSが違うので、上限も異なると思いますが。

やはり変数に入れない方がいいでしょうね。

foo | bzip2 -z >xxx.tmp.bz2
ただ、ステータスを調べるのは面倒。パイプのステータスはパイプの最終段のコマンドつまりbzip2のステータスになります。

bashだと、${PIPESTATUS[0]} でfooのステータスが取れるのですが、shだとちょっと細工が要ります。

status=`((foo ; echo $? >&3) | bzip2 -z >xxx.tmp.bz2) 3>&1`
if [ $status = 0 ]
then mv xxx.bz2 xxx.old.bz2; mv xxx.tmp.bz2 xxx.bz2
else rm xxx.tmp.bz2
fi

変数と言うより、シェルのコマンドライン長の制約の気がします。
圧縮して1.2MBということはfooの出力は数十~数百MB?
外部コマンド起動の場合は、Linuxだと128KBが上限のようですが、echoは組み込みコマンドなので、もっと上限は大きいはずです。
変数に200MBいれてみると、入りましたけど、echoしてみるとbashが落ちました。SolarisだとOSが違うので、上限も異なると思いますが。

やはり変数に入れない方がいいでしょうね。

foo | bzip2 -z >xxx.tmp.bz2
ただ、ステータスを調べるのは面倒。パイプの...続きを読む

Qシェルスクリプトの実行、「source」と「.」の違いについて

bashのシェルスクリプトを書いています。
当方、Mac Snow Leopard を使っているため、seq コマンドがデフォルトでは使えません。
そこで、.bashrc 内に、seq 関数をあらかじめ自分で定義して、他で使い回したいと思っています。
.bashrc の中に、
function seq() {
i=$1
while [ $i -le $2 ] ; do
echo $i
let i=$i+1
done
}
と、関数を定義しました。
seq 関数をターミナル上で実行すると、
>seq 0 2
0
1
2
と正しく、表示されます。次に、

#!/bin/sh
seq 0 2

と記述したシェルスクリプト(temp.sh)を「source」で実行すると、
>source temp.sh
0
1
2
と正しく、表示されますが、「.」で実行すると、
>./temp.sh
./temp.sh: line 2: seq: command not found
と言われます。
どのような理由によってこの違いが出るのでしょうか??

bashのシェルスクリプトを書いています。
当方、Mac Snow Leopard を使っているため、seq コマンドがデフォルトでは使えません。
そこで、.bashrc 内に、seq 関数をあらかじめ自分で定義して、他で使い回したいと思っています。
.bashrc の中に、
function seq() {
i=$1
while [ $i -le $2 ] ; do
echo $i
let i=$i+1
done
}
と、関数を定義しました。
seq 関数をターミナル上で実行すると、
>seq 0 2
0
1
2
と正しく、表示されます。次に、

#!/bin/sh
seq 0 2

...続きを読む

Aベストアンサー

追記

source は現在のシェルで実行し、結果がそのまま現在のシェルに適応されます。
今回の temp.sh なら
> source temp.sh

> seq 0 2
と入力したのと同等ということになります。

> ./temp.sh
この . はコマンドではなく、 temp.shへのパスを指定するものです。
実行ファイル名だけでコマンドとして実行できるのは、環境変数PATHで指定したディレクトリにあるものだけです。それ以外は、その実行ファイルへの絶対パス、または相対パスが必要となります。
これは、カレントディレクトリにある実行ファイルも例外ではありません。
環境変数PATHに . が無い場合は、 ./ファイル名 と相対パスを指定する必要があります。
(この点は、常に . がPATHにあるように振る舞うMS-DOSやコマンドプロンプトとは違います)
逆に、PATH上にあれば(例えば、 PATH=$HOME/bin:(以下略)となっている時の $HOME/bin )、 temp.sh とファイル名だけで実行できます。

また、こうしたコマンドは新規プロセスで実行されますので、環境変数を除いて、現在の設定は継承されません。
対話的ではないbashや、 shとして起動された bash は .bashrcを読まないので、そこに書いてあることは無効となります。

追記

source は現在のシェルで実行し、結果がそのまま現在のシェルに適応されます。
今回の temp.sh なら
> source temp.sh

> seq 0 2
と入力したのと同等ということになります。

> ./temp.sh
この . はコマンドではなく、 temp.shへのパスを指定するものです。
実行ファイル名だけでコマンドとして実行できるのは、環境変数PATHで指定したディレクトリにあるものだけです。それ以外は、その実行ファイルへの絶対パス、または相対パスが必要となります。
これは、カレントディレクトリにある実行...続きを読む

Qsedなどで、特定の文字列の後の文字列を抽出したい

sedなどで、特定の文字列の後の文字列を抽出したい

シェルスクリプト内で、sedなどを使って特定の文字列の後の文字列を抽出したいのですが、どうすればいいでしょうか?

たとえば、abcXYZ123defghiのなかから、XYZの後の「123」を抜き出したいです。

echo abcXYZ123defghi | sed ...

のようにして実行させたいです。

Aベストアンサー

日本語対応sedだと日本語数字混じりでもできますね。

echo abcXYZ12357defghi | sed -e 's/^.*XYZ\([0-90-9]*\).*$/\1/' -e 'y/0123456789/0123456789/'
12357

※ 使っている日本語コードの指定は必要かも(例えば、 --ctype=EUC)

echo abcXYZ12357defghi | sed -e 's/^.*XYZ\([0-90-9]*\).*$/\1/'
12357

※ 入力フォームに書いている時はASCIIと日本語の判別がし易いけど回答見るとわかり難いですね。後ろの例での結果57とy/0123456789/の数字部分が日本語です。

Q起動しているサービスを確認するコマンド

初歩的な質問で恐縮ですが、ご教示いただけますと幸いです。

起動しているサービスを確認するために以下の2つのコマンドを打ってみるのですが、結果(出て来るサービス名)が違います。
このコマンドの違いについてご教示いただけますでしょうか。

(1)service --status-all
(2)chkconfig --list

Aベストアンサー

(1)service --status-all

サービスの現在のステータスを調べるコマンド

(2)chkconfig --list

OSのブート時に自動起動するサービスを調べるコマンド

違いが出るのは、
・ブート後に手動あるいは他のコマンドから起動したサービス
・ブート後に手動あるいは他のコマンドから、あるいはエラーで停止したサービス
・ブート後に実行はされるがすぐに停止して常駐しないサービス (ntpdate とか)

あるいは、(1)ではサービス名が表示されない物もあるので、どのサービスがどんなステータス出力をするのか知っておく必要もありますね。(service network statusとか)


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報