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

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

■ このスレッドは過去ログ倉庫に格納されています
0001うはwwwww2006/03/26(日) 00:56:22
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>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 でトレースしましょう。
0399名無しさん@お腹いっぱい。2006/05/12(金) 11:00:06
>>398 THX です。
必要なものだけ環境変数に export することにします。
同じ種類のシェルなら内部でなんかうまいことパイプとか
つくって引き継いでくれるのかな?
とか都合いいこと考えてました。
0400名無しさん@お腹いっぱい。2006/05/13(土) 00:13:13
ShUnit使ってる人いる?

http://shunit.sourceforge.net/

ドキュメントがまったく無いんだけど
0401名無しさん@お腹いっぱい。2006/05/13(土) 06:48:50
>>400
シェルスクリプトのテストツール?なのかこれ?

今ソースを眺めてるけど、なんか関数が
たくさん定義されてるな。
今は眠いから処理を追いかけられねーや。
0402名無しさん@お腹いっぱい。2006/05/14(日) 04:13:00
bash上で

5 だったら 0005
55 だったら 0055
555 だったら 0555
5555 だったらそのままの 5555

というように数字1〜4桁までのファイル名を0を使って4桁に揃えたいのですが

for 名前 in * ; do
桁数=${#名前}
[ $桁数 = 1 ] && mv $名前 000$名前
[ $桁数 = 2 ] && mv $名前 00$名前
[ $桁数 = 3 ] && mv $名前 0$名前
done

こんなのしか思い浮かびません。もっとスマートで汎用的な感じにできませんでしょうか?
0403ヽ(´ー`)ノ ◆.ogCuANUcE 2006/05/14(日) 05:05:53
printf %04d 5
# -> 0005

printf %04d 55
# -> 0055

printf %04d 555
# -> 0555

printf %04d 5555
# -> 5555

printf %04d 55555
# -> 55555
0404名無しさん@お腹いっぱい。2006/05/14(日) 09:15:04
aa=000055; echo ${aa:$((-4)):4}

0055
0405名無しさん@お腹いっぱい。2006/05/14(日) 12:13:29
bashと限定している馬鹿には答える必要はないかもしれないが。

case "$x" in
?) y=000$x ;;
??) y=00$x ;;
???) y=0$x ;;
????) y=$x ;;
*) y=$x ;;
esac

なんて方法もある。
普通なら>>403を使うけど、数値しか使えないのでこういう小細工も使うことがある。
0406名無しさん@お腹いっぱい。2006/05/14(日) 13:36:09
>>405
それ自体は悪くはないんだけど、
仕事でそういうのの塊のコードがあって泣きそうになったことある。

シェルスクリプトで日付計算とかね。アホかっちゅーの。
0407名無しさん@お腹いっぱい。2006/05/14(日) 13:56:39
このスレの>>1を読めと言ってやれ。

とはいえ、「任意の日からN日後の日付」「任意の日どうしの間隔」
「任意の日の曜日」あたりを調べるのは確かに頭痛いな。
GNU date, env TZ=... dateを使うのが定番だろうけど、どっちもイマイチな気がする。
修正ユリウス日をうまく使ってすっぱりと実装できそうなんだが。
04084072006/05/14(日) 15:03:08
とりあえず作ってみた。bc/dcでやるべきだったか…
bash厨は$(())に置き換えたいだろうが、自分のマシンで勝手にやってくれ。

to_mjd() {
if [ "$2" -lt 3 ]; then
yy=`expr "$1" - 1`; mm=`expr "$2" + 12`; dd=$3
else
yy="$1"; mm="$2"; dd=$3
fi
expr $yy \* 1461 / 4 + $yy / 400 - $yy / 100 + \( 3059 \* $mm - 6118 \) / 100 + $dd - 678912
}
dayofweek() {
# Sun=0, Mon=1, Tue=2, Wed=3, Thu=4, Fri=5, Sat=6
expr \( "$1" + 3 \) % 7
}
from_mjd() {
yy=`expr \( $mjd \* 100 - 1507820 \) / 36525`
m2=`expr $yy \* 1461 / 4`
mm=`expr \( \( $mjd - $m2 \) \* 10000 - 149561000 \) / 306001`
d2=`expr $mm \* 306001 / 10000`
dd=`expr $mjd - 14956 - $m2 - $d2`
if [ $mm -gt 13 ]; then
yy=`expr $yy + 1901`; mm=`expr $mm - 13`
else
yy=`expr $yy + 1900`; mm=`expr $mm - 1`
fi
echo "$yy $mm $dd"
}
mjd=`to_mjd 2004 1 1`
echo "mjd: $mjd"# => 53005
echo "dayofweek: `dayofweek $mjd`"# => 4 (Thu)
echo "gregorian: `from_mjd $mjd`"# => 2004 1 1
04094022006/05/14(日) 16:45:14
ありがとうございましあた。
printf便利ですね。
caseも勉強になりました
エロ画像の生理に使います。
0410名無しさん@お腹いっぱい。2006/05/14(日) 18:21:33
>>408
どうでもいいことだが mjd って何の略?
「マジで」としか変換できないバカに教えてくれ。
0411名無しさん@お腹いっぱい。2006/05/14(日) 18:22:01
>>409
だったらrenameの使い方も覚えとけ。
0412名無しさん@お腹いっぱい。2006/05/14(日) 18:23:55
検索一発
Modified Julian Day
04134072006/05/14(日) 22:06:16
あうあう、from_mjdの一行目に"mjd=$1"ってのが必要なのでご注意を。
行数制限にひっかかったので、いろいろやってるうちに消してしまった… スマヌ
0414名無しさん@お腹いっぱい。2006/05/14(日) 22:32:07
>>411
renameコマンドは、同名の別物コマンドが少なくとも2種類以上あって、
使い方も違うので、どのrenameのことを言ってるのか明示すること。
で、OSによって使えるかどうかわからないrenameは覚える必要なし。
0415名無しさん@お腹いっぱい。2006/05/14(日) 22:34:57
>>412
マジで?!

いや、ありがと。
0416名無しさん@お腹いっぱい。2006/05/15(月) 16:39:35
named や httpd なんかが動作してるか(死んでないか)確認できる
シェルスクリプトきぼんぬ!
0417名無しさん@お腹いっぱい。2006/05/15(月) 17:09:26
pgrep named
0418名無しさん@お腹いっぱい。2006/05/15(月) 17:16:14
つrndc apachectl pgrep
0419名無しさん@お腹いっぱい。2006/05/15(月) 18:48:14
shell script じゃないじゃん。Mac OS X ではmake しても動かないし....

ps agx | grep named

つうか、rc か lanuchctl で生きているかどうか確認せずに殺すことが多い。
0420名無しさん@お腹いっぱい。2006/05/15(月) 19:12:39
grep使うならせめて
ps -ef | grep [n]amed
ps ax | grep [/]named
とかしてほしいす。
# 商用Unixにも入ってるようなpgrepがOSXに無いのはオドロキ
0421名無しさん@お腹いっぱい。2006/05/15(月) 19:32:10
やっぱ、
ps `cat /var/run/named.pid`
だろ。
pgrepはまだ歴史が浅井。
0422名無しさん@お腹いっぱい。2006/05/15(月) 21:38:44
>>421
そういうのってときどき見るけど
突然死してpidが再利用されてしまっている可能性は0とみなすの?
0423名無しさん@お腹いっぱい。2006/05/15(月) 23:29:44
PDP-11の時代ならまだしも今なら最低でも31bitあるわけだし、
一巡する前に気づかないのは別の意味で問題な気が。
0424名無しさん@お腹いっぱい。2006/05/15(月) 23:41:00
俺のマシンはPID_MAXが99999な件。
PDP時代ならこれだけの桁数まわすのに相当時間が
かかるからよかっただろうが、
今だからこそ再利用されてしまう可能性があるんじゃないか?
0425名無しさん@お腹いっぱい。2006/05/15(月) 23:47:16
>>420
FreeBSD ベースだからじゃね?
4.x は pgrep を ports で入れないといけなかった記憶がある。
0426名無しさん@お腹いっぱい。2006/05/15(月) 23:50:20
流量の多い qmail なメールサーバだと数時間で1周するな。
04274162006/05/15(月) 23:56:14
みなさんサンクスコ
でさらにあふぉな質問でスマソなんですが、
プロセスが死んでる場合(PIDが存在しない)は
メール、みたいな分岐処理をするにはどうすればよかとですか?
0428名無しさん@お腹いっぱい。2006/05/16(火) 00:57:56
>>427
if "プロセスが死んでると判定するコマンド"
then "メール送信用のコマンド"
fi
04294162006/05/16(火) 09:12:54
「プロセスが死んでると判定するコマンド」
は何になるのでしょうか?
pgrep named
はあくまで生きているプロセスを調べるためのコマンドなので
これでは無いですよね?
0430名無しさん@お腹いっぱい。2006/05/16(火) 11:44:04
そのプロセスと同じ uid か、あるいは root 権限で、
if kill -0 プロセスID 2>/dev/null; then
  生きてる
else
  死んでる
fi
0431名無しさん@お腹いっぱい。2006/05/16(火) 12:04:29
>>429
pgrepでもできる。死んでいる(存在しない)プロセスなら、
終了ステータスで偽を返す。

if pgrep named 2> /dev/null; then
:
else
echo 'namedが死んでるよ' | mail omae
fi
0432名無しさん@お腹いっぱい。2006/05/17(水) 17:30:19
すみません、とても素人な質問させてください。
リナックスザウルスの活用の幅を広げようと思ってます。

UNIXシェルスクリプトで、ライフゲームや、HIT&BROW(四桁数字当て)ゲームは
作ることができますか?
0433名無しさん@お腹いっぱい。2006/05/17(水) 17:58:59
職場の管理者が、「もうcsh系は不要」と言って削除されてしまいました。
ログインシェルをtcshにしていた人は強制zsh移行。
そこで、自宅からtcshをフロッピーに入れて ~/bin/tcshに突っ込みましたが、
chshでログインシェルが変更できません。あと、いろいろいじってるうちに
ログインできなくなってしまいました。内容が内容だけに、
管理者には相談できません。どうすればいいでしょうか?
0434名無しさん@お腹いっぱい。2006/05/17(水) 18:10:06
おとなしく懺悔
0435名無しさん@お腹いっぱい。2006/05/17(水) 18:53:24
>>432
できなくは無いと思うが余計な苦労を強いられるだろう。
そういう挑戦に興味が無ければ、より高機能なもの(Perlなど)を薦める。

>>433
> 管理者が削除されてしまいました
ガクガクブルブル
0436名無しさん@お腹いっぱい。2006/05/17(水) 20:07:13
>>435
> >>433
> > 管理者が削除されてしまいました
ヒント:尊敬
0437名無しさん@お腹いっぱい。2006/05/17(水) 23:10:52
僕も、tcsh 削除させようかな。zsh 使うのには、どうしようもない理由が必要だろうし。

function と **/*.c だけでも、zsh にして良かったと思うよ。つうか、なんで、いままでtcshなんか使っていたんだろうと反省中。
0438名無しさん@お腹いっぱい。2006/05/17(水) 23:24:44
zshって、シェルスクリプトスレで延々スレ違いのインタラクティブシェルの話をする馬鹿が
使うシェルってイメージがあるから損してるよな。かわいそう。
0439名無しさん@お腹いっぱい。2006/05/18(木) 03:33:06
それはむやみにフェラーリのるあほな成金がいるから
フェラーリのイメージが成金趣味っぽくなるのと同じだよ。
0440精進2006/05/18(木) 12:18:31
【労働環境】営業担当者が「SEに足りないと思うスキル」とは [06/05/16]
ttp://news18.2ch.net/test/read.cgi/bizplus/1147877411/-100

 「もっと顧客から課題を聞き出す力があればなあ」「専門知識を生かして積極的に提案して
もらえると助かるのだが」---。

 営業担当者がITに関する商談で客先を訪問した際に、同行したSEに対してこんな不満や要望を
抱いている。顧客に対して「何をすればいいのでしょうか」と“御用聞き”に徹して提案しようと
しないSEや、顧客と積極的にコミュニケーションを図ろうとしないSEに対して、営業担当者は
もどかしい思いをしているのだ。

 営業担当者がSEに抱く不満は、SEに対する期待の裏返しでもある。そんな不満や期待が込め
られた、営業担当者からSEに対するコメントをいくつかを紹介しよう。

「お客様の目の前で“それはできません”と即答しないでほしい」
「お客様を満足させていくという顧客指向を持ってほしい」
「指示・依頼を待つだけでなく、自分で考え積極的に提案してほしい」
0441名無しさん@お腹いっぱい。2006/05/18(木) 14:50:12
テキストファイルから /foo .* bar/ を検索して
.* の部分だけ出力するのにスマートな方法ある?
とりあえず ruby で下のように書いてるけど、
長いしPOSIX標準じゃないしで、いまいち気に入らない。
ruby -e '$<.each { |line| line.sub(/foo (.*) bar/) { print $1 + "\n";} }'
0442名無しさん@お腹いっぱい。2006/05/18(木) 14:57:30
sed -n -e 's@.*/foo \(..*\) bar/.*@\1@p'
04434412006/05/18(木) 16:54:08
>>442
dクス。勉強になりました。
0444名無しさん@お腹いっぱい。2006/05/18(木) 17:32:21
>>440
抜きん出たSEになるために必要なスキルだとは思うけど
SEに提案させて顧客交渉までさせたら営業いらなくなるよな
0445名無しさん@お腹いっぱい。2006/05/18(木) 18:14:27
営業とSEが別の人間てのは、実際にはそうなるケースが多いにしても、
避けた方が良くないかね。
0446名無しさん@お腹いっぱい。2006/05/18(木) 19:57:46
ご注文を分析すれば良いだけだろ。
0447名無しさん@お腹いっぱい。2006/05/18(木) 20:29:17
規模によるな。
0448名無しさん@お腹いっぱい。2006/05/18(木) 23:44:12
質問させてください。
echo で、○行目に文字を追加するにはどうしたらいいでしょうか?
0449名無しさん@お腹いっぱい。2006/05/19(金) 00:08:54
米国一流企業では見積りも有料です。
0450名無しさん@お腹いっぱい。2006/05/19(金) 00:22:01
「見積り」と称して散々技術コンサルを無料でさせられたのを思いだしたじゃないか。
あんな客は2度と相手にしないよ。
0451名無しさん@お腹いっぱい。2006/05/19(金) 00:43:18
うちは要件定義書まで無料でやらされる場合が多いですが・・・
0452名無しさん@お腹いっぱい。2006/05/19(金) 04:29:20
よし、皆わかっている事を敢えて言おう!
泥をかぶるのは俺だけでいい!

仕事の愚痴はスレ違い。
0453名無しさん@お腹いっぱい。2006/05/19(金) 10:03:51
スレ違いな話から戻すため質問に答えようと>>448を見たが意味がわからない。
0454名無しさん@お腹いっぱい。2006/05/19(金) 10:37:56
>>448
カーソルを移動させたいならこんな感じ。
adhocな方法 echo "^[[5;10H"
ちょっとましな方法 tput cup 5 10
文字の追加が具体的にどういう動作なのかわからない。
04554482006/05/19(金) 15:37:47
>>453>>454さん。ありがとうございます。

echo hoge >> test.txt
この場合はtext.txtの最後の行にhogeが追加されるのですが
このような感じでhogeという文字を
指定の行に追加するにはどうしたらいいでしょうか?
0456名無しさん@お腹いっぱい。2006/05/19(金) 16:07:48
>>455
echoでは無理。
04574482006/05/19(金) 16:09:33
>>456さん
どうやってできますでしょうか?
0458名無しさん@お腹いっぱい。2006/05/19(金) 16:26:18
>>448
echoでは無理といわれているのだから、問題を再定義しなさい。
04594482006/05/19(金) 16:29:52
すみません。できました。
0460名無しさん@お腹いっぱい。2006/05/19(金) 19:34:34
>>459
本当に出来たのか?ウソはだめだぞ。
0461名無しさん@お腹いっぱい。2006/05/20(土) 01:05:58
客:「右足上げて、それが地面につく前に左足上げたら空飛べるじゃん」
SE:「それはできません」

営業:「お客様の目の前で“それはできません”と即答しないでほしい」
0462名無しさん@お腹いっぱい。2006/05/20(土) 01:53:40
客:「抱いてくれたらええやん」
SE:「それはできません」

営業:「お客様の目の前で“それはできません”と即答しないでほしい」
0463名無しさん@お腹いっぱい。2006/05/20(土) 04:29:08
ある文字列を含んだ行とその下二行を削除したい、
のですが教えていただけないでしょうか?

例:hoge を含む行とその下二行の削除

-----------------------
1
hoge
2
3
4
hoge
5
6
-----------------------

-----------------------
1



4



-----------------------
0464名無しさん@お腹いっぱい。2006/05/20(土) 05:07:10
>>463
無理にシェルスクリプトにせず、awkやperlで書いたほうがよさそうな気がします
0465名無しさん@お腹いっぱい。2006/05/20(土) 05:18:43
: ${aaa=bbb}
これは
aaa=bbb
と等価になるのはなぜですか?
0466名無しさん@お腹いっぱい。2006/05/20(土) 05:52:55
>>463
sed で簡単に出来そう。
おれは一行ごとに処理するやり方しか知らないからわからん。
0467名無しさん@お腹いっぱい。2006/05/20(土) 09:51:44
newlineが扱えないsedはしらん。
sed -E -e '/hoge/{N
N
s/[^\n]//g
}' data
0468名無しさん@お腹いっぱい。2006/05/20(土) 10:32:09
>>465
先頭のコロンはよくわかんないけど
${aaa=bbb} はaaaが未定義の場合のみ代入
${aaa:=bbb} はaaaが未定義または空の場合のみ代入
:- :? :+ も同様に:の有無でちょい違う動作をする。
:なし 変数が未定義かどうかをチェックする
:あり 変数が未定義かどうか、値が空かどうかをチェックする
ということがマニュアルに書いてある。
0469名無しさん@お腹いっぱい。2006/05/20(土) 10:42:03
>>468
ありがとうございます。
マニュアルの微妙な隙間に : を入れないときの動作がちゃんと書いてありました。
流し読みだったのでいつもいつも読み飛ばしてたorz
パラメータ展開のひとつという事は、先頭のヌルポマンドの引数とすることで
aaa=${aaa:=bbb}
みたいな冗長な代入にしなくてすむっぽいという事ですか。
0470名無しさん@お腹いっぱい。2006/05/20(土) 10:49:21
コロンは何も実行しないコマンド。終了ステータスは常に0。
コマンドなので、引数やリダイレクトは他のコマンドと同様に処理される。
0471名無しさん@お腹いっぱい。2006/05/20(土) 10:54:40
あーそか、ヌルコマンドに引数指定できるという発想はなかったわ
0472名無しさん@お腹いっぱい。2006/05/20(土) 11:01:10
>>465
等価にはならない。
: ${aaa=bbb}
で値が代入されるのは、aaa が未定義の時だけ。

>>467
sed に -E というオプションは無さげ。
sed -e '/hoge/ {
a \

N
a \

N
a \

d
}'
なら、仮に \n を認識しない場合でも出来るかと。
0473名無しさん@お腹いっぱい。2006/05/20(土) 11:03:22
ぐぁ、リロードしたら既に解答が…
ここって案外人多いのね。
0474名無しさん@お腹いっぱい。2006/05/20(土) 11:25:28
>>472
-Eでnewline(\n)が扱えるようになるsedもあるんだよ。
お前のsed(gnu sed)は行末の\でnewlineとみなしてるだけで、行末の\を
newlineとみなさないのもある。

gnu sedなら
sed -e '/hoge/{N
N
s/[^\
]//g
}' data
でも行ける。
0475名無しさん@お腹いっぱい。2006/05/20(土) 11:57:11
そういえば ed は /hoge/,/hoge/+2 という範囲指定ができるんだが
sed はできないんだな。
0476名無しさん@お腹いっぱい。2006/05/20(土) 12:15:10
>>474
> -Eでnewline(\n)が扱えるようになるsedもあるんだよ。
いや、だから -E は POSIX 準拠でもないはずだが。

上のコマンドは間違ってた。a \ じゃなく a\ です。Append コマンドは。
スペース入れると POSIX & SUS 違反。GNU なんかじゃ通っちまうがな。

まあ、洩れ自身 GNU に冒されてるのは認めし、GNU を嫌う気持ちも分かる。
スペースいれちまったことは素直に謝りたい。

後、GNU sed なら N なんぞ使わず、/hoge/,+2 とでもしといた方が良い。
0477名無しさん@お腹いっぱい。2006/05/21(日) 11:57:07
>>463
:g/hoge/.,.+2s/.*//

ってvimじゃないのか。
0478名無しさん@お腹いっぱい。2006/05/22(月) 02:42:26
お勧めはしないが、sed のバージョンに
依存したくないのならこんな方法もある。

#!/bin/sh
i=0
while read x ; do
 y=''
 if [ "$x" = 'hoge' ] ; then
  i=2
 elif [ "$i" -gt 0 ] ; then
  i=`expr "$i" - 2`
 else
  y="$x"
 fi
 echo "$y"
done < file
0479名無しさん@お腹いっぱい。2006/05/22(月) 12:36:14
hogeを含む行だし、-2の意味わかんないし
0480名無しさん@お腹いっぱい。2006/05/25(木) 17:12:36
ある機械のHTTPサーバが落ちている(ポート80にconnect(2)できない)
かどうかを調べるのにはどうしたらよいでしょうか?

HTTPで自分の状況を公開している装置Mがあります。
これの状況を定期的に wget 1.8.2 で調べようとしてるのですが、
時々MのHTTPサーバが落ちています。(OSは動いててping等に応答。)
サーバが落ちていると、wget はいつまでも終了しません。
HTTPでつながらない時にはすぐあきらめるにはどうしたらよいでしょう?

wget の --timeoutオプションは、connect(2)成功後のreadに対する指定
らしく、効果ありませんでした。

wgetするマシンはFreeBSD 4.10で、/bin/sh で書いてます。
0481名無しさん@お腹いっぱい。2006/05/25(木) 17:45:23
ピンポンダッシュにはやっぱりnmap?
04824802006/05/25(木) 17:56:25
ピンポンした後ダッシュせず、相手の顔色(HTML response)を確認したいっす。
でも、相手出ないのに玄関でずっと待ってるのも変で。

nmapごもっともですが、大鉈っぽくないですか?
0483名無しさん@お腹いっぱい。2006/05/25(木) 18:07:46
>>480
wget http://... &
sleep 5
kill $!
0484名無しさん@お腹いっぱい。2006/05/25(木) 18:41:40
>>480
リトライが0(=infinity)になってない?
1.10.1なら--connect-timeoutがあるよ。
0485名無しさん@お腹いっぱい。2006/05/25(木) 21:18:45
>>480
Smokepingが良いよ。
単体のコマンドはechopingとか
0486名無しさん@お腹いっぱい。2006/05/26(金) 17:45:13
すいません。質問があります。
あるファイルの中の情報が
正しいフォーマット(各情報がタブで分けられている)
かどうか確認する方法はありますか?
たとえば、example.txtというファイルの中が

picture.jpg<tab>jpg
word.txt<tab>txt
music.mp3<space>mp3

だとすると、
このファイルのフォーマットは正しくない(3行目がスペースで分けられている)ので、
falseを返すというようなスクリプトを知りたいです。
よろしくお願いします
0487名無しさん@お腹いっぱい。2006/05/26(金) 17:50:20
>>486
「正しい」の定義がよくわからんが
grep -v ' ' <example.txt >/dev/null && echo false
とか。
' ' の中は TAB 文字で。
0488名無しさん@お腹いっぱい。2006/05/26(金) 17:58:17
>>487
「falseを返す」というのは「falseという文字列を表示する」という意味なのかw
0489名無しさん@お腹いっぱい。2006/05/26(金) 18:05:58
>>488
まぁ、例として挙げたまで。
その辺は好きなように変えてくれ。
04904862006/05/26(金) 18:21:45
説明が下手ですんません。
あるファイルの中の各ラインの情報が
すべてタブキャラクターで分けられているか確認したいのです。

上記のexample.txtの場合、
1行目と2行目は

picture.jpg<tab>jpg
word.txt<tab>txt

とタブで分けられていますが、
3行目は

music.mp3<space>mp3

タブではなくスペースで分けられているので、
このexample.txtの書式は間違っているということが知りたいのです。
0491名無しさん@お腹いっぱい。2006/05/26(金) 18:28:37
>>490
それなら >>487 がすでに答えてるじゃん。

もっと厳密にするなら
grep -v '\<.*\> \<.*\>'
でいいかな。途中の空白に見えるところは TAB文字でね。
0492名無しさん@お腹いっぱい。2006/05/26(金) 18:28:56
>>490
> あるファイルの中の各ラインの情報が
> すべてタブキャラクターで分けられているか確認したいのです。
さっきと変わってないな。
ここをきちんと定義しないとまともな解は出てこないよ。
たとえば以下のような行をどう扱うか
これじゃわからんでしょ。

a<space><tab>b
a<space>b<tab>c
<tab>b
a<tab><tab>b
a<tab>b<tab>c
0493名無しさん@お腹いっぱい。2006/05/26(金) 19:22:02
>>490
a=$(cat $1 | wc -l)
b=$(cat $1 | sed -nr "/[^\t]*\t[^\t]*/p" | wc -l)
[ $a = $b ] && echo "OK" || echo "NG"
0494名無しさん@お腹いっぱい。2006/05/26(金) 20:16:12
カレントディレクトリ内(サブディレクトリ含む)の特定の拡張子を持つファイルを
一括で処理させたいと思い以下のようなシェルスクリプトを組んだのですが
サブディレクトリ内の一部ファイルが重複して処理されてしまいます
どこがダメなのでしょうか?

recursive_func()
{
for i in *
do
if [ -d $i ]
then
cd $i
recursive_func
cd ..
fi

if echo $i | grep '\.c$' > /dev/null || echo $i | grep '\.h$' > /dev/null
then
//ここに処理
fi
done
}

recursive_func
0495名無しさん@お腹いっぱい。2006/05/26(金) 20:21:54
>>494
find と xargs じゃだめなん?
0496名無しさん@お腹いっぱい。2006/05/26(金) 20:40:57
>>494
シェル変数iはローカル変数じゃないよ。
再帰呼び出しした時に iの値を変化させてしまうから、
呼び出し元の iまで狂ってしまう。
0497名無しさん@お腹いっぱい。2006/05/26(金) 20:41:55
>>495
find自体は知ってたんですが、まさかこんな使い方があるとは知りませんでした・・・orz
下の様に書き換えることで目的の処理は達成できました
ありがとうございました&お騒がせしました・・・


find . \( -regex ".*\.c" -o -regex ".*\.h" \) -exec //ここに処理 \;
0498名無しさん@お腹いっぱい。2006/05/26(金) 20:45:38
>>496
そういうことだったんですか。シェルスクリプトはちょっと齧っただけなので
ついCの感覚で書いてました・・・
元の方も関数先頭で local i とすることでうまく動くようになりました
わざわざありがとうございました
■ このスレッドは過去ログ倉庫に格納されています