シェルスクリプト総合 その16
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
2010/02/20(土) 14:10:05スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。
□お約束
・特記なき場合は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 でトレースしましょう。
前スレ
シェルスクリプト総合 その15
http://pc12.2ch.net/test/read.cgi/unix/1246408968/l50
0083名無しさん@お腹いっぱい。
2010/02/28(日) 12:33:50今時でつまつ調はキモい
0084名無しさん@お腹いっぱい。
2010/02/28(日) 13:17:020085名無しさん@お腹いっぱい。
2010/02/28(日) 17:10:200086名無しさん@お腹いっぱい。
2010/02/28(日) 17:21:110087名無しさん@お腹いっぱい。
2010/02/28(日) 17:38:23'=' はどう書くんでしょう?
0088名無しさん@お腹いっぱい。
2010/02/28(日) 17:45:240089名無しさん@お腹いっぱい。
2010/02/28(日) 17:49:33ついでに、-ne と != も違います
0090名無しさん@お腹いっぱい。
2010/02/28(日) 17:51:42しかし、'='または'==' と -eq は違う。
0091名無しさん@お腹いっぱい。
2010/02/28(日) 17:58:530092名無しさん@お腹いっぱい。
2010/02/28(日) 18:25:420093名無しさん@お腹いっぱい。
2010/02/28(日) 18:27:07009485,87
2010/02/28(日) 18:30:090095名無しさん@お腹いっぱい。
2010/02/28(日) 18:40:420096名無しさん@お腹いっぱい。
2010/02/28(日) 19:45:24%preun
if [ "$1" -eq "0" ]; then
0097名無しさん@お腹いっぱい。
2010/02/28(日) 19:48:38"$1"が 0 でも 00 でも 000 でも一致するのが -eq
0098名無しさん@お腹いっぱい。
2010/02/28(日) 20:00:19こうすれば0のみの一致になる?
0099名無しさん@お腹いっぱい。
2010/02/28(日) 20:06:40と、xをつけたくなってしまうバッドノウハウ
0100名無しさん@お腹いっぱい。
2010/02/28(日) 20:10:19kwsk
0101名無しさん@お腹いっぱい。
2010/02/28(日) 20:14:10その xを付けるバッドノウハウが必要になるような "$1"の例が、
今時のUNIXシェルには存在しないんだな。
よってxを付けるバッドノウハウは不要。
0102名無しさん@お腹いっぱい。
2010/02/28(日) 21:04:27bash/ksh/zsh だとコケない。確かにUNIXシェルならコケないな。
0103名無しさん@お腹いっぱい。
2010/03/09(火) 04:37:55文字として比較するか、数値として比較するか
0104名無しさん@お腹いっぱい。
2010/03/09(火) 04:39:31bashに似ているが、微妙に違う罠
0105名無しさん@お腹いっぱい。
2010/03/11(木) 23:38:01echo $record | wc -c
で取得できると思ったのですが、echoが末尾のスペースをカットしてしまい、上手く行かず…
どんな工夫で解決できるでしょうか?
0106名無しさん@お腹いっぱい。
2010/03/11(木) 23:46:46$record にはどうやってデータ格納してるの?
0107名無しさん@お腹いっぱい。
2010/03/12(金) 06:46:57まだテスト段階で、本格的なコーディングはしていないのですが、
record=`head -1 ファイルパス`
echo "${record}@" …ここではスペースが入っているのを確認
echo ${#record} …スペース込みの文字数が出力されるのを確認
echo $record | wc -c …バイト数が足りず
ということで、パイプする前のechoでスペースが落ちてるんじゃないかと…
0108名無しさん@お腹いっぱい。
2010/03/12(金) 06:59:520109名無しさん@お腹いっぱい。
2010/03/12(金) 18:33:15echo "$record" | wc -c …バイト数が1個多い、、
、、と言うと予想。
0110名無しさん@お腹いっぱい。
2010/03/12(金) 21:01:22sh-3.2$ bar="space "
sh-3.2$ /bin/echo -n ${bar} | wc -c
5
sh-3.2$ /bin/echo -n "${bar}" | wc -c
6
0111名無しさん@お腹いっぱい。
2010/03/12(金) 21:07:44$ bar="space "
$ /bin/echo -n "${bar}" | wc -c
10
???
0112名無しさん@お腹いっぱい。
2010/03/12(金) 21:21:03-n オプション(出力後改行しない)を持たないecho実装だとそうなる。
- n 空白 s p a c e 空白 改行
0113名無しさん@お腹いっぱい。
2010/03/12(金) 21:30:41知ってるよ。だから >>110 じゃ不完全だって指摘してるんだろ。
0114名無しさん@お腹いっぱい。
2010/03/12(金) 21:35:420115名無しさん@お腹いっぱい。
2010/03/12(金) 21:42:52$ /bin/echo -n "$bar" | wc -c
0
0116名無しさん@お腹いっぱい。
2010/03/13(土) 10:29:32echo ${#record} で目的の結果が得られているのに、
なぜ echo -n "$record" | wc -c とかわざわざ外部コマンドでやろうとするの?
(ダブルクォートと -n は付けておいたよ)
0117名無しさん@お腹いっぱい。
2010/03/13(土) 14:53:17service httpd graceful を実行する
という処理を一行で可能でしょうか?
0118名無しさん@お腹いっぱい。
2010/03/13(土) 15:02:210119名無しさん@お腹いっぱい。
2010/03/13(土) 16:09:530120名無しさん@お腹いっぱい。
2010/03/13(土) 16:22:250121名無しさん@お腹いっぱい。
2010/03/13(土) 16:26:00今環境がないので、今度客先に行った時に試してみます。
0122名無しさん@お腹いっぱい。
2010/03/15(月) 01:02:16export HOGE="(A B C D)"
hoge=${HOGE}
export HOGE=(A B C D)
hoge=${HOGE}
の両方試してみたのですが、どちらもhogeには文字列ががが
要素が10個近くあるので、それぞれ別の変数に入れて渡すとごちゃごちゃしそうで…
なにか良い方法はないですかね?
0123名無しさん@お腹いっぱい。
2010/03/15(月) 02:39:42bash なら
hoge=("${HOGE[@]}")
これでどうでしょうか。
0124名無しさん@お腹いっぱい。
2010/03/15(月) 04:23:210125名無しさん@お腹いっぱい。
2010/03/15(月) 07:03:40export HOGE="(A B C D)"
(子プロセスで)
eval hoge=${HOGE}
>>123
同じシェルだとうまく行くが、
配列はexportできないので、
それでは駄目。
0126名無しさん@お腹いっぱい。
2010/03/15(月) 17:36:54find . -name "*" -exec grep $1 {} /dev/null \;
}
findとexecを毎回打つのがめんどいんで
こんなのを書いたんですが
grepall "int main"とかやると
"int main"を含む行じゃなくて
intかmainを含む行が出力されてしまうんですが
そうならないようにできたりしますか?
0127名無しさん@お腹いっぱい。
2010/03/15(月) 17:41:53function grepall(){ find . -exec grep "$1" {} /dev/null \;;}
か?
つーか GNU grep の -r 使えばいいんじゃね。
0128名無しさん@お腹いっぱい。
2010/03/15(月) 17:48:220129名無しさん@お腹いっぱい。
2010/03/17(水) 22:16:20do
echo "${line},1"
done
でファイルの中身をグルグル回すシェルを作りたいのですが、ファイルの改行コードが落ちてしまうのはどうにかならないでしょうか?
読み込むファイルがCRLFなので、LEだけ落ちてCRだけ残るというなんとも半端なことに…
どうせならCRもまとめてなくなるか、CRLFのまま残るかして欲しいんですが…
0130名無しさん@お腹いっぱい。
2010/03/17(水) 22:36:30echo "${line},1"
ってやってるなら、行末に ",1" が付くわけだけど、
${line}に ^M が含まれてるなら、"...^M,1" ってなるわな。
それ、LFが落ちてるわけじゃないよ。
0131名無しさん@お腹いっぱい。
2010/03/17(水) 22:37:250132名無しさん@お腹いっぱい。
2010/03/18(木) 01:33:450133名無しさん@お腹いっぱい。
2010/03/18(木) 07:19:290134名無しさん@お腹いっぱい。
2010/03/18(木) 07:38:43しかし、Windowsに持ってきてエディタで開いたり、バイナリエディタで見てもCRだけ残っているのですが…
>>131
やはりそういう形になりますかね…試してみます。
0135名無しさん@お腹いっぱい。
2010/03/18(木) 08:21:57おまえ、>>130 の言ってる意味わかってないな。
CR+LFのLFが落ちてCRだけ残ったのではなく、
もともとCRが普通の文字とみなされて、
その後に「,1」が追加されただけのことで、
LFが落ちたわけではないんだと言ってるんだけど。
0136名無しさん@お腹いっぱい。
2010/03/18(木) 08:23:160137名無しさん@お腹いっぱい。
2010/03/18(木) 08:24:35IFS= の中に ^M を入れておくと readの際に自動的に CR を落してくれる。
これが最適解。
0138名無しさん@お腹いっぱい。
2010/03/18(木) 17:02:540139名無しさん@お腹いっぱい。
2010/03/18(木) 17:08:360140名無しさん@お腹いっぱい。
2010/03/18(木) 17:32:380141名無しさん@お腹いっぱい。
2010/03/18(木) 17:45:170142名無しさん@お腹いっぱい。
2010/03/18(木) 17:51:24bakanisareta... orz
0143名無しさん@お腹いっぱい。
2010/03/21(日) 14:17:59BシェルもKシェルも大して変わらんよ
0144名無しさん@お腹いっぱい。
2010/03/21(日) 18:14:29ただ、Bashとは違う
0145名無しさん@お腹いっぱい。
2010/03/22(月) 23:29:11関数に渡す引数の中に、5C問題を起こすコードとスペースが混じっている可能性があるとき、どうやって渡せばいいんでしょう?
Fanc '${hoge}'
だと${hoge}が文字列になってしまうし、
Fanc "${hoge}"
だと5C含みの文字がエスケープされて文字化ける
0146145
2010/03/22(月) 23:31:14上手く変数を展開しつつ、さらにエスケープを抑止する方法はないでしょうか?
よろしくお願いします。
0147名無しさん@お腹いっぱい。
2010/03/23(火) 12:49:02いや ksh は bourne sh とぜんぜん違うでしょ。
機能的には bash の方がよほど近い。
bsh は ${hoge%fuga} とか ${#hoge} とか $((1+1)) とかどれも使えない。
~ がホームディレクトリに展開されないぐらいだし。
0148名無しさん@お腹いっぱい。
2010/03/23(火) 13:05:31今現在 B-shと言ったら、*BSDの ash または debianの dash相当のシェルを指す。
で、その B-shでは、${hoge%fuga} とか ${#hoge} とか $((1+1)) とか
すべて使える。
ちなみに、OpenSolarisからはBourne-shが消えて、
/bin/shは kshへのsymlinkになってる。
0149名無しさん@お腹いっぱい。
2010/03/23(火) 13:23:370150名無しさん@お腹いっぱい。
2010/03/23(火) 13:30:22最大の根拠がSolarisに現存していたBourne Shellだったわけだが、
SolarisのBourne Shellがなくなったことで、
Bourne Shell互換で記述する意味がなくなってしまったな。。
0151名無しさん@お腹いっぱい。
2010/03/23(火) 13:33:300152名無しさん@お腹いっぱい。
2010/03/23(火) 15:11:32OpenSolaris にも bourne sh はあるよ。
パスが /usr/has/bin/sh に変わったけど。
>>148
>今現在 B-shと言ったら、*BSDの ash または debianの dash相当のシェルを指す。
これ、ふつー posix shell といわない?
>>144 は classic Bシェルという言葉を出してるわけだし、
昔からの bourne sh の方を言ってると考えるのが妥当じゃないかと。
0153名無しさん@お腹いっぱい。
2010/03/23(火) 15:22:190154名無しさん@お腹いっぱい。
2010/03/23(火) 15:53:36ashやdashぱ posix shellじゃないよ。
たとえば、[[ ]] とかが使えないし、、
0155名無しさん@お腹いっぱい。
2010/03/23(火) 15:56:03かんけーねーだろ。
自分が求める仕事が完結すれば、シェルは何だって良い。
酸いも甘いも理解して使えばいいんだよ
0156名無しさん@お腹いっぱい。
2010/03/23(火) 15:57:41/usr/has/bin/sh は歴史的遺物として置いてあるのであって、
実際のスクリプトで使われていないし、使ってはいけない。
0157名無しさん@お腹いっぱい。
2010/03/23(火) 16:03:34アホくせ
0158名無しさん@お腹いっぱい。
2010/03/23(火) 16:06:380159名無しさん@お腹いっぱい。
2010/03/23(火) 16:48:01夕飯までにcshでちょろっと組むかな
0160名無しさん@お腹いっぱい。
2010/03/23(火) 23:18:150161名無しさん@お腹いっぱい。
2010/03/24(水) 00:22:060162名無しさん@お腹いっぱい。
2010/03/24(水) 01:17:360163名無しさん@お腹いっぱい。
2010/03/24(水) 01:51:480164名無しさん@お腹いっぱい。
2010/03/24(水) 01:56:59はいいんだよ
0165名無しさん@お腹いっぱい。
2010/03/24(水) 02:04:550166名無しさん@お腹いっぱい。
2010/03/24(水) 02:07:000167名無しさん@お腹いっぱい。
2010/03/24(水) 05:51:170168名無しさん@お腹いっぱい。
2010/03/24(水) 06:46:53総称して何と呼べばいいの?
0169名無しさん@お腹いっぱい。
2010/03/24(水) 08:25:510170名無しさん@お腹いっぱい。
2010/03/24(水) 15:41:510171名無しさん@お腹いっぱい。
2010/03/24(水) 16:29:350172名無しさん@お腹いっぱい。
2010/03/24(水) 16:42:410173名無しさん@お腹いっぱい。
2010/03/24(水) 16:49:49http://www.ioplaza.jp/shop/genre/genre.aspx?genre=09outtop&affiliate=TP100323B1#useditem
ユーズドアイテム公開日: 3月24日 (水) 19:30〜
http://www.ioplaza.jp/shop/genre/genre.aspx?genre=09outtop&affiliate=TP100323B1#reusememory
B級ユーズドアイテム公開日: 3月24日 (水) 20:15〜
I-O OUTLET はアイオープラザ会員様限定の特別販売コーナーです。
アイオー製品のワケあり掘り出し物がタイムセールスで大放出。是非ご来店をお待ちしております。
※なお、ご利用には会員登録が必要です(登録無料)。
0174名無しさん@お腹いっぱい。
2010/03/24(水) 16:50:390175名無しさん@お腹いっぱい。
2010/03/24(水) 16:53:500176名無しさん@お腹いっぱい。
2010/03/24(水) 16:54:510177名無しさん@お腹いっぱい。
2010/03/25(木) 00:58:36あるよ。
if [[ ${1} = AAA]] ;then
とか可能
0178名無しさん@お腹いっぱい。
2010/03/25(木) 01:18:04http://www.opengroup.org/onlinepubs/009695399/utilities/test.html
The KornShell-derived conditional command (double bracket [[]]) was removed
from the shell command language description in an early proposal.
0179名無しさん@お腹いっぱい。
2010/03/25(木) 07:39:10letコマンドの動作も変だし。
0180名無しさん@お腹いっぱい。
2010/03/26(金) 01:06:03それ以外なら細かい話もよしではある。
0181名無しさん@お腹いっぱい。
2010/03/26(金) 06:53:420182名無しさん@お腹いっぱい。
2010/03/26(金) 07:08:170183名無しさん@お腹いっぱい。
2010/03/27(土) 21:42:06例えば以下のようなテキストファイル、file.hoge1があるとします。
AAA111ZZZZ
BBB222ZZZZ
CCC333ZZZZ
DDD444ZZZZ
これに対して、先頭CCCで始まるレコードの4カラム目から3カラム
つまり「333」を「XXX」にしたい。
AAA111ZZZZ
BBB222ZZZZ
CCCXXXZZZZ
DDD444ZZZZ
しかし「333」の位置には半角3バイトではあるが必ずしも「333」が入っている訳ではなく
何が入ってるかは一定でない。
これの解をお願いします。
■ このスレッドは過去ログ倉庫に格納されています