トップページunix
1001コメント327KB

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

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。2007/08/15(水) 07:25:02
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>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 でトレースしましょう。

前スレ
シェルスクリプト総合 その8
http://pc11.2ch.net/test/read.cgi/unix/1171517324/
0246名無しさん@お腹いっぱい。2007/10/01(月) 23:27:38
俺のNEWS-OSに入ってないようなOS依存のコマンドは禁止
02472392007/10/01(月) 23:39:15
レスありがとうございます

環境はMac OS Xですがrealpathはコマンドラインとしてはないようです(関数はある)

pwdでも良さげですがpwdが返すパスは必ず/で終わっていない、という保証もなさそうで
ちょっと不安なので、自分でrealpathのような事をするツールを作る事にします。
0248名無しさん@お腹いっぱい。2007/10/01(月) 23:45:16
>>247
pwdが返すpathは、/ディレクトリ以外は / では終らないよ。

だから、`pwd`/A/B とする場合に、/ に居る場合のみ、
pwdの結果の単独の / を取り除く処理が要るね。
0249名無しさん@お腹いっぱい。2007/10/01(月) 23:46:18
ご教示ください。
変数Aの中を、キーワード検索するには、どうすれば
よいでしょうか。たとえば、/usr があるかどうかを検索
したい場合、キーワードはランダムな位置にある。

A="aaaaa /usr bbb 789 ccc"
       ↑キーワード
0250名無しさん@お腹いっぱい。2007/10/01(月) 23:48:51
>>246
GK乙
0251名無しさん@お腹いっぱい。2007/10/01(月) 23:49:21
>>249
普通に、

case $A in */usr*) /usrがあった場合の処理;; esac
0252名無しさん@お腹いっぱい。2007/10/01(月) 23:53:47
>>251
どうも、ありがとうございます。ちょっと実現に向けてがんばってみます。
0253名無しさん@お腹いっぱい。2007/10/02(火) 01:36:48
ご教示ください。

aaaa,bbbb
bbbb,cccc
aaaa,cccc
bbbb.aaaa
aaaa,dddd
bbbb,eeee

こんな感じにならんでいるものを

aaaa,bbbb
aaaa,cccc
aaaa,dddd
bbbb,cccc
bbbb,aaaa
bbbb,eeee

と並べ替えたいのですが、どうやればいいでしょうか。
0254名無しさん@お腹いっぱい。2007/10/02(火) 01:44:11
>>253
普通に sort の -k あたり使えばいいんじゃね?
man sort 参照。
0255名無しさん@お腹いっぱい。2007/10/02(火) 01:47:32
>>254
すみません。書いた後気がつきました^^;
お手数かけました。
0256名無しさん@お腹いっぱい。2007/10/03(水) 00:07:24
教えてください。
標準出力をif文の制御をパイプでつなぎたいですが、
下記の例で、if文の制御で可能でしょうか、だめの場合は、
別な方法はあるでしょうか。

例:
if [[ $? -nq 0 ]]; then
ls -x |
else
cat /etc/hosts |
fi
while read line
do
:

0257名無しさん@お腹いっぱい。2007/10/03(水) 00:29:38
日本語でおkだが、

if [[ $? -nq 0 ]]; then
ls -x
else
cat /etc/hosts
fi |
0258名無しさん@お腹いっぱい。2007/10/03(水) 00:33:08
>>257
どうもありがとうございます。やってみます。
0259名無しさん@お腹いっぱい。2007/10/03(水) 01:40:42
[[ ]]ってなんだよ。
0260名無しさん@お腹いっぱい。2007/10/03(水) 01:44:11
bash は犬板へ
0261名無しさん@お腹いっぱい。2007/10/03(水) 01:48:58
大阪にみえた。もう寝よう。
0262名無しさん@お腹いっぱい。2007/10/03(水) 07:35:15
[[ ]] も POSIXでは OKだよ。bashじゃない。
でも、bourneで使えないから、[[ ]] は普通使うべきじゃない。
## %% を使うべきじゃないのと同じ。
0263名無しさん@お腹いっぱい。2007/10/03(水) 08:03:05
俺的には
-nq
のほうが引っかかるのだが、
何でみんなスルーするのだ?
0264名無しさん@お腹いっぱい。2007/10/03(水) 20:38:08
申し訳ないです。

then節またはelse節がエラーになった場合、
標準出力をパイプに渡したくないするのに、よい方法
はあるでしょうか。エラーがあった場合は、メッセージ
を出したexitするようなことはできないでしょうか。


if [ $? -nq 0 ]; then
 ls -x      ← エラーがあった場合
else
 cat /etc/hosts ← エラーがあった場合
fi |
while read line
do
:
0265名無しさん@お腹いっぱい。2007/10/03(水) 20:42:50
>>264
エラーがあった場合、

echo 'エラーメッセージ' 1>&2
exit

とすればいいだけ。標準エラー出力に出るので、
パイプには渡されない。


-nq はいい加減に直せよ
0266名無しさん@お腹いっぱい。2007/10/03(水) 21:14:47
>>265
-nq を -ne に修正します。

ようわからないのですが、
正常ケースだと、echoで指定したメッセージが渡されて
しまいそうなんですが。
0267名無しさん@お腹いっぱい。2007/10/03(水) 21:31:46
>>266
正常ケースについては言っていない。

エラーが出た場合のエラーメッセージの出し方を言っているのだが。

もしかして、$? での判断の方法とか知らないの?
0268名無しさん@お腹いっぱい。2007/10/04(木) 00:38:55
パイプの前に||を入れて、{}かなんかで>265のを囲う。みたいな?
0269名無しさん@お腹いっぱい。2007/10/04(木) 03:16:20
>>268
パイプの前で exit してもスクリプト自体は終了しないから
>>265 を入れてもあまり意味が無いんじゃね?
0270名無しさん@お腹いっぱい。2007/10/04(木) 06:46:06
>>269
while read で、パイプから読もうとしているから、
broken pipe で終了するよ。

もし、パイプの先が標準入力(=パイプ)を読まないコマンドばかりだったら
確かにすぐには終了しないけどね。

よって、>>265 で正解。
0271名無しさん@お腹いっぱい。2007/10/04(木) 20:53:04
すみません。基本的なことかも知れませんが、
シェルを書く時、まず最初の方で、
#!/bin/sh みたいに、シェルをインクルードしますよね。
でも、この前インクルードしなくても動いてしまったんですよ。
結局インクルードは必要ないんでしょうか?
Cで、printf()を使う程度だったら<stdio.h>を
インクルードしなくていいのと同じですか?
0272名無しさん@お腹いっぱい。2007/10/04(木) 21:42:37
>>271
シェルスクリプト総合 その4
http://pc10.2ch.net/test/read.cgi/unix/1131026501/33-

http://www.bookshelf.jp/2ch/unix/1131026501.html
0273名無しさん@お腹いっぱい。2007/10/05(金) 08:31:25
シェルをインクルードとはまた新しい概念だな。
0274名無しさん@お腹いっぱい。2007/10/05(金) 08:54:33
インクルード=オマジナイ
0275名無しさん@お腹いっぱい。2007/10/05(金) 09:09:24
.はインクルードって言っていい?
0276名無しさん@お腹いっぱい。2007/10/05(金) 15:53:06
そっちかよ
0277名無しさん@お腹いっぱい。2007/10/07(日) 15:08:28
説明が難しいのですが

a=hoge
b=a

こういう時

echo "$b"
↓b=aなので
echo "$a"
↓a=hogeなので
hoge

みたいな処理をしたいのですができますでしょうか?
0278名無しさん@お腹いっぱい。2007/10/07(日) 15:21:34
eval echo \$$b
0279名無しさん@お腹いっぱい。2007/10/08(月) 05:23:27
ありがとうevalかー
02802772007/10/08(月) 06:08:15
何度もすみません。
変数の中に変数を入れることはできないでしょうか?
自分の応用力の無さが嫌になります

hoge_A=AAA
foo=A

${hoge_$foo}
↓foo=Aなので
${hoge_A}

AAA
0281名無しさん@お腹いっぱい。2007/10/08(月) 06:29:01
>>280
eval "echo \"\${hoge_$foo}\"

>>277 ならbash 限定かもしれんが eval なしでもできる
echo "${!b}"

0282名無しさん@お腹いっぱい。2007/10/08(月) 08:02:57
>>280
eval echo \"\$hoge_$foo\"

変数の中に空白とかがなければ
eval echo \$hoge_$foo
でも桶。


>>281 のひとつ目の解答、ダブルクォートがおかしいよ。
0283名無しさん@お腹いっぱい。2007/10/08(月) 20:38:58
応用力のなさよりも、evalを理解しきれていない感じ?
>>278

入力: eval echo \$$b
↓ 変数展開($b)・エスケープ解釈
シェルが実行する文: eval echo $a
↓ そのevalコマンドを実行……
入力: echo $a ←←※
↓ 変数展開($a)
echo hoge

evalを使う式を作る場合は欲しい文※からスタートしてさかのぼればいい。

echo "$hoge_A" ←←※実行させたいケースの例
↓ Aを変数fooの参照に戻す・$などをエスケープ
echo \"\$hoge_$foo\"
↓ 頭にevalをつける
eval echo \"\$hoge_$foo\"
02842772007/10/08(月) 21:08:00
皆さんありがとうございます。
283さんの解説を見つついろいろ試して理解しようと思います。
0285名無しさん@お腹いっぱい。2007/10/10(水) 02:28:09
横の行をsortするコマンドはないでしょうか?

echo 'aaa bbb aaa ccc" | sort
0286名無しさん@お腹いっぱい。2007/10/10(水) 02:53:48
echo "aaa bbb aaa ccc" | sed s/\ /\\n/g | sort
0287名無しさん@お腹いっぱい。2007/10/13(土) 10:12:10
>>285

sedでやる(置換して戻す二度手間が少しダサい)

echo "aaa bbb aaa ccc" | sed 's/ /\
/g' | sort | sed ':loop
N;s/\n/ /;$!b loop'

awkでやる(長い。一目見て何をしているのか解らない)
※とりあえず「行が長すぎる」と投稿時に怒られたので、分割しますたが元は一行です。

echo "aaa bbb aaa ccc" | \
awk '{ sizeOfArray = split($0,words," ")
  for (i = 2; i <= sizeOfArray; ++i) {
    for (j = i;(j-1) in words && wrods[j] < words[j-1]; --j) {
       tmp = words[j]; words[j] = words[j-1]; words[j-1] = tmp
    }
  }
    for (i = 1; i < sizeOfarray; ++i) printf("%s ",words[i])
  print words[i]
}'

sortアルゴリズムを工夫すると更に訳解らん一行コマンドになりそうw
0288名無しさん@お腹いっぱい。2007/10/13(土) 10:50:03
sed 's/ /\n/g;s/^/sort <<.\n/;s/$/\n.\n/;e
s/\n/ /g'
0289名無しさん@お腹いっぱい。2007/10/13(土) 11:26:44
普通にperl使えよ。
0290名無しさん@お腹いっぱい。2007/10/13(土) 11:43:34
awk+sed 使うんなら perl にするかなぁ。
0291名無しさん@お腹いっぱい。2007/10/13(土) 12:39:03
perl使ったら負け。sed awkだけで何とかするのが面白い。
ただし、awkを使う場合はawkだけにしてsedは使わないのが美しい。
0292名無しさん@お腹いっぱい。2007/10/13(土) 14:49:02
オナニーするのは勝手だがそういうのは独りで迷惑をかけないようにやれよ
02932872007/10/13(土) 15:27:47
>>289

済みません。perl 知らないんですw
シェルスクリプトや sed,awk なんかも勉強し始めたばかりで、
もう少し上達したら、次は perl を学ぼうと思ってます。
0294名無しさん@お腹いっぱい。2007/10/13(土) 15:53:04
いるんだよなぁ、シェルで普通に書けるのに、わざわざperlで書くやつ。
ああいうの、まわりに迷惑かけてるよなぁ。
0295名無しさん@お腹いっぱい。2007/10/13(土) 17:32:28
「シェル」で書いてみろ。出来もしないことをゆうな。クズ。
0296名無しさん@お腹いっぱい。2007/10/13(土) 17:44:54
いつもシェルで書いてるよ。今さらなに言ってんの?w
0297名無しさん@お腹いっぱい。2007/10/13(土) 17:47:48
perlなら「書く」というレベルじゃない。コマンドラインで実行して使い捨て。

perl -ne 'print join(" ", sort(split(/\s+/))), "\n"'
0298名無しさん@お腹いっぱい。2007/10/13(土) 17:49:04
>>296
でた、口だけ番長。
0299名無しさん@お腹いっぱい。2007/10/13(土) 17:51:20
「シェルで書く」は別にいいだろ。
03002872007/10/13(土) 18:12:06
>>297

便利ですね

でも私にはまだ早い。
0301名無しさん@お腹いっぱい。2007/10/13(土) 19:08:53
口だけ番長は>>285のお題を「シェル」でどのように解くのだ?
0302名無しさん@お腹いっぱい。2007/10/13(土) 20:56:42
>>299
「シェルをかく」と大して変わらん。
シェルはシェル、スクリプトはスクリプト。
0303名無しさん@お腹いっぱい。2007/10/13(土) 21:15:30
>>302
日本語大丈夫ですかw
「シェルを書く」は間違い。
「シェルで書く」は桶。

「シェルで書く」→「シェルで記述する」
→「シェルをインタプリタとして(コマンドを)記述する」


逆に、
「シェルスクリプトで書く」は間違い。
書かれたもののことを「シェルスクリプト」と言うのだから、
「シェルスクリプトで書く」だと、
「(別の)シェルスクリプトを自動的に書いてくれるようなシェルスクリプトを使う」
みたいな意味になってしまう。
0304名無しさん@お腹いっぱい。2007/10/13(土) 21:20:49
>>303
もしかすると世の中にはシェルスクリプトで書かれたエディタがあったりして

……と書いてこの「シェルスクリプトで」はあってるのか間違ってるのか
わからなくなってきた
0305名無しさん@お腹いっぱい。2007/10/13(土) 21:25:48
口だけ番長は話題をそらすことに必死なようです。
0306名無しさん@お腹いっぱい。2007/10/13(土) 21:46:23
コンピュータ用語を日本語で記述する際に
「てにをは」が通用しないケースが有るだけのこと。

くだくだしく文法を語らなくてよろし。
0307名無しさん@お腹いっぱい。2007/10/15(月) 00:22:28
>>296
やっぱり逃げたな。口だけ番長。
0308名無しさん@お腹いっぱい。2007/10/15(月) 09:31:23
>>294
俺はシェルで書けば直ぐ終わるものをJavaしか
書けないから?と言う理由で全部Javaで書いて
帰って行った外注さん知ってるぞ。
0309名無しさん@お腹いっぱい。2007/10/15(月) 15:27:51
javaでかけないのって結構多いけどな。
chmod(相当)だって、やっと1.6で出来るようになったのに。
0310名無しさん@お腹いっぱい。2007/10/15(月) 20:14:03
>>308-309
権限関連の操作と、ファイルのコピー、移動は、javaから子プロセス起こしてシェルスクリプト実行してる。
1.3,1.4の環境だと実装が面倒&パフォーマンス悪すぎなので。
0311名無しさん@お腹いっぱい。2007/10/17(水) 01:48:54
なんかのFAQで#!ラインは最後にハイフンをつけて
#!/bin/sh -
とした方が安全、みたいなことを読んだことがあるような
気がするんですが、そういう話ってありますか?
なんかごにょごにょして予期しないオプションを渡されないように、
みたいなことだったと思うんですが。
0312名無しさん@お腹いっぱい。2007/10/17(水) 06:03:25
あるディレクトリ以下のファイル名とディレクトリのパスを別々に表示(間にスペースを表示)させたいです。

とりあえず、ファイルのフルパスのみ、もしくは、ファイル名のみであれば以下で表示できるのですが、
find `/bin/pwd` -type f -print -exec ls {} \;|xargs -i dirname {}
find `/bin/pwd` -type f -print -exec ls {} \;|xargs -i basename {}
これを同時に行って

/hoge/hoge bar.txt
/hoge/hoge foo.txt
/hoge/hoge/hoge foo.txt

のように表示することはできないでしょうか?
あるコマンドの処理結果の一行に対して複数コマンドを発行する、ということになると思うのですが。

一旦 set -A で配列に入れてからloopで一行づつ処理することも考えたのですが、ファイル数が多すぎる場合Errorになってしまいます。

どなたかご教示ください
0313名無しさん@お腹いっぱい。2007/10/17(水) 09:05:20
その -print と -exec ls を同時にするという既知概じみた発想をなんとかしろ。
話はそれからだ。
0314名無しさん@お腹いっぱい。2007/10/17(水) 09:12:11
find `pwd` -type f -print | sed -e 's|/\([^/]*\)$| \1|g'
でどうかな。
0315名無しさん@お腹いっぱい。2007/10/17(水) 09:12:53
s/.../.../g は GNU 拡張で s|...|...|g にしたから、/ にする所は
適当に直してください。
0316名無しさん@お腹いっぱい。2007/10/17(水) 09:14:22
>>312
できたよ。

find `/bin/pwd` -type f -exec sh -c 'echo `dirname {}; basename {}`' \;
0317名無しさん@お腹いっぱい。2007/10/17(水) 13:53:01
>>315
> s/.../.../g は GNU 拡張で s|...|...|g にしたから、/ にする所は

それってGNU拡張?

雉も鳴かずば撃たれまいに……w
0318名無しさん@お腹いっぱい。2007/10/18(木) 01:54:00
>>317
うぉ、実はedからこういう挙動なのね:

 $ echo hogehoge > a
 $ ed a
 9
 ,s,hoge,fuga,g
 w
 9
 q
 $ cat a
 fugafuga

なんとなくPerlとかそういう無節操な時代になってからの事だとばかり・・・(恥
0319名無しさん@お腹いっぱい。2007/10/18(木) 19:51:23
んじゃ別解でも。
find "`/bin/pwd`" -type f -exec sh -c "echo \`dirname '{}';basename '{}'\`" \;

または312のようにそれぞれ一方だけを出力する方法はわかるのなら
それぞれ出力して後からくっつけるとかでもいいし
find 〜 -exec dirname '{}' \; > /tmp/dirname.txt
find 〜 -exec basename '{}' \; > /tmp/basename.txt
paste -d ' ' /tmp/dirname.txt /tmp/basename.txt

もしくはリストを出力させてwhileループで料理してもいい
find 〜 -print | while read f; do
echo "`dirname $f` `basename $f`"
done

他にはfindに-execを複数並べて、後から2行を1行にまとめるのでも。
find 〜 -exec dirname '{}' \; -exec basename '{}' \; | while read d; do read b; echo "$d $b"; done
0320名無しさん@お腹いっぱい。2007/10/18(木) 19:55:24
おっと、先頭のは316が既に書いていたのを見落としてました。
0321名無しさん@お腹いっぱい。2007/10/20(土) 08:46:44
以下のデータ構造で、
先頭に#があり、行の終わりにキーワード(Japan_A)がある行
から次の#と行の終わりにキーワード(Japan_X)がある直前まで読み込む
方法を考えています。

readとwhile文で簡単に実現するにはどうすれば、よいでしょうか。
while の条件がよくからないです。

====データ構造
BBB nnn
AAAA
#△△ABC△△△△Japan_A ← このパターンを検出して、次の行を読み込む。

123△△456

:△789△10

#△△ABC△△△△Japan_Z ← ここのひとつ前の行まで、
:zzz△12

====
0322名無しさん@お腹いっぱい。2007/10/20(土) 09:58:25
>>321
whileの条件: コマンドの終了ステータスが0ならループ

その例はsedでやるのが簡単で速いけど。
0323名無しさん@お腹いっぱい。2007/10/20(土) 12:09:46
ファイルの内容を読み込んで、それを
変数に代入するのってどうやればいいでしょうか?
0324名無しさん@お腹いっぱい。2007/10/20(土) 12:30:47
a=`cat a.txt`
0325名無しさん@お腹いっぱい。2007/10/20(土) 13:24:38
/bin/sh
で変数numが1〜10の値の場合、
という処理をしたい場合、
下記って正式にサポートされている構文なんでしょうか。
一応動きますが。。。

if [ ${num} -ge 0 ] && [ ${num} -le 9 ]

また、${num}が1〜9の値の場合、
echo "${num} is 1-9."
というコマンドを実行したい場合、
下記のような記述の仕方も認められているんでしょうか?

if [ ${num} -ge 0 ] && [ ${num} -le 9 ] && echo "${num} is 1-9."

0326名無しさん@お腹いっぱい。2007/10/20(土) 14:10:17
>>325
「正式サポート」って、Bourne shell桶っていう意味かな?
であればすべて桶。無問題。

一番下の行、間違ってるよ。ifは要らん。

× if [ ${num} -ge 0 ] && [ ${num} -le 9 ] && echo "${num} is 1-9."
○ [ ${num} -ge 0 ] && [ ${num} -le 9 ] && echo "${num} is 1-9."
0327名無しさん@お腹いっぱい。2007/10/20(土) 14:40:32
[ ... ] が test ... というコマンドの別名だというのは知ってるよね?

if文の条件式のところに書くのは「リスト」
リストというのは、1つ以上のコマンド(のパイプ列)を&&や||でつないだもの

[ ${num} -ge 0 ] && [ ${num} -le 9 ] がリストとして正当な以上、
if文の条件としても正当。

0328名無しさん@お腹いっぱい。2007/10/20(土) 15:04:29
testというコマンドは使った事ありません。
if文の中の&&が正式サポートされているという事ですが、
if文がないのに、条件式だけ&&で書いても実行できてしまうのは
正式サポートなんですか?
0329名無しさん@お腹いっぱい。2007/10/20(土) 15:20:55
>条件式だけ&&で書いても実行できてしまう
それがリスト。

&&の機能は、左のコマンドが成功したら(0を返したら)右のコマンドを実行する。
||の機能は、左のコマンドが失敗したら(非0を返したら)右のコマンドを実行する。
他に ; てのもあって、これは左のコマンドを実行し、続いて右のコマンドを実行する。
0330名無しさん@お腹いっぱい。2007/10/20(土) 15:36:38
複数の [ ... ] を && でつなぐよりも、test の -a オプションで ANDしたほうがいい。

if [ ${num} -ge 0 ] && [ ${num} -le 9 ]; then

if [ ${num} -ge 0 -a ${num} -le 9 ]; then

今時はないが、[ ] が外部コマンドになってるシェルの場合、
下の方法の方がtestが1回で済むため速い。

あと、変数numが空の場合にtestが混乱するのを避けるため、
常にダブルクォートを付ける癖を付けた方がいい。
さらに、単純な変数参照では { } は不要。
以上を考慮すると、

if [ "$num" -ge 0 -a "$num" -le 9 ]; then

となる。

ところが、実はこの場合はif文じゃなくてcase文で書いた方が簡単。
すべて内部コマンドになり、少しだけ速い。

case $num in [0-9]) 実行したいコマンド;; esac
0331名無しさん@お腹いっぱい。2007/10/20(土) 15:36:53
&&や||といったリストは、最後に実行したコマンドのステータスを返す。
具体的には、
&&は、左のコマンドが失敗したらそのステータス値を返して終了。
成功なら、まだ終わらず、右のコマンドの結果をステータス値を返す。
||は、左のコマンドが成功したら0で終了。
失敗なら、右のコマンドのステータスを返す。
となる。これ自体はシェルの正式な動作。

で、if 条件式…だと思っているものは正しくは if リスト ... であり、
リストを実行し、成功なら(0を返したら) then以下を〜という構文。

testというのはいろんな条件を調べて、成り立つなら成功(0)で終了、
成り立たないなら0以外を返すコマンド。if文に書くときにカッコに
見えるように [ という同機能のコマンドも用意されている。([という
名前で実行する場合は、カッコのペアに見えるように最後に ] という
引数を付ける。

0332名無しさん@お腹いっぱい。2007/10/20(土) 22:51:51
>>322
支援ありがとうございました。
sed ですか。あまり、熟知していないなぁ。
0333名無しさん@お腹いっぱい。2007/10/21(日) 01:48:28
>>321
データが収められているのが file とするとこんな感じ。

flag='false'
while read line ; do
 if echo "$line" | grep -q '^#.*Japan_A' ; then
  flag='true'
 elif echo "$line" | grep -q '^#.*Japan_Z' ; then
  flag='false'
 elif $flag ; then
  echo "$line"
 fi
done < file

あまり効率の良いコードじゃないので、これは叩き台として使ってくれ。
0334名無しさん@お腹いっぱい。2007/10/21(日) 05:53:04
すみません。bashど素人です。
FILE[0]=a
FILE[1]=b
FILE[2]=c
この配列をforを使ってechoしたいのですがどうしたらいいでしょうか?
03353342007/10/21(日) 06:04:47
ごめんなさい。解決しました。
0336名無しさん@お腹いっぱい。2007/10/21(日) 06:34:27
>>333
親切な、詳細コードありがとうございます。感謝いたします。
参考にさせていただきます。
0337名無しさん@お腹いっぱい。2007/10/22(月) 23:18:56
無知で申しわけありません。追加で教えていただきたいのですが、
grep の検索キーを変数などで、変更可能でしょうか。

例: 1022の部分を変数などで変更する方法?は

grep 'ABC_071022' $line

grep 'ABC_???' $line
0338名無しさん@お腹いっぱい。2007/10/22(月) 23:39:57
普通に、grep "ABC_$key" "$line"
0339名無しさん@お腹いっぱい。2007/10/22(月) 23:53:19
>>338
ありがとうございます。試してみます。
( ' → " になるのですね。)
0340名無しさん@お腹いっぱい。2007/10/23(火) 00:00:32
いや、「になる」って言うか……。
基本から勉強しなおしてみたら?
0341名無しさん@お腹いっぱい。2007/10/23(火) 00:05:24
>>340
ご指摘のとおりかと思います。やはり基本からですね。
0342名無しさん@お腹いっぱい。2007/10/23(火) 22:28:14
キーワード: クォート
03433122007/10/25(木) 01:22:35
>>313-319
御礼が遅くなりました。すいません。

>>314
ある出力に対して二回処理を行うのではなくて、出力自体を加工するってことですね。
問題なく実行できました。
ありがとうございます。

>316, 319
find `/bin/pwd` -type f -exec sh -c 'echo `dirname {}; basename {}`' \;
find "`/bin/pwd`" -type f -exec sh -c "echo \`dirname '{}';basename '{}'\`" \;

これ両方うまくいかないんですよね。
どうなるかというと. {} って出力がfindの結果数分続きます。
dirname, filename の引数を{}として実行するとそれぞれ "."と"{}"になるので、
{}にfindの結果が入っていないような動きだと思うんですが原因が分かりません。

よく分からなかったので試しに実験してみたところ、
find `/bin/pwd` -type f -exec echo {} \;
の出力はファイル名が出力されるのに、
find `/bin/pwd` -type f -exec sh -c echo {} \;
だとfindの結果行数分の改行(Blank行が延々続く)になってしまいます。


{}が単独で置かれていなければならないような findもある、
というmanの記述を見つけたのですが、今回のケースがそれなんでしょうか?
http://www.linux.or.jp/JM/html/GNU_findutils/man1/find.1.html

いずれにせよ環境が問題な気もするんですが、どなたか回避策ご存じないですか?
ちなみにOSはAIXです。
0344名無しさん@お腹いっぱい。2007/10/25(木) 04:17:32
>>343
多分 find じゃなくて最後の sh に与える引数のクォートが
上手くいってないんじゃないかな。

これならどうよ?

find `/bin/pwd` -type f -exec sh -c "echo {}" \;
find `/bin/pwd` -type f -exec sh -c "echo \`dirname \"{}\";basename \"{}\"\`" \;
0345名無しさん@お腹いっぱい。2007/10/25(木) 12:12:46
> いずれにせよ環境が問題な気もするんですが

AIXスレでそういう特有の事情がないか聞いてみるとか。
■ このスレッドは過去ログ倉庫に格納されています