シェルスクリプト相談室at TECH
シェルスクリプト相談室 - 暇つぶし2ch200:デフォルトの名無しさん
05/11/27 02:14:08


























200

201:デフォルトの名無しさん
05/11/27 10:30:51
>>195
>パスが通ってなかったら、sh 打ったって実行できん。
へ?


202:デフォルトの名無しさん
05/11/28 00:05:03
俺も>>195は意味不明だが、スルーした方がよい気がする

203:デフォルトの名無しさん
05/12/04 19:53:23
ファイル名を一括置換するシェルスクリプト

#! /bin/sh

for nm in temp*;
do
mv $nm HOGE${nm#tr};
done

temp → HOGEにするのはわかるのですが、
hhh_a_xxxxxxxxx.txt → hhhaxxxxxxxxx.txt  のように _ を削除(一括置換)するスクリプトを教えてください。
※xxxxxxxxxは可変

204:デフォルトの名無しさん
05/12/04 21:14:19
>>203
方法は色々あるけど tr -d あたりがお勧め。


205:デフォルトの名無しさん
05/12/04 22:40:36
>>204

tr のコマンドの意味はわかったんだけど、どうやってコマンド組み合わせればいいの?
tr は標準出力のものを対象にしてると書いてあったけど、コマンドの組み合わせ方が、わかんないです。

206:デフォルトの名無しさん
05/12/04 23:17:46
>>204

#!/bin/sh
for f in hoge*
do
mv $f `echo $f | tr -d 削除文字`
done

できたよ。ありがとう。

207:デフォルトの名無しさん
05/12/09 19:09:12
質問なんですけど、
NTのコマンドプロンプトで
テキストファイルが二つあって
中身を片方にアペンドしたいのですが
どう記述したらいいでしょうか?
マニュアルも何もなくて一人で困ってます

208:デフォルトの名無しさん
05/12/09 19:10:20
type a.txt >> b.txt

209:デフォルトの名無しさん
05/12/09 20:00:54
ありがとうございました
ホント助かります

210:デフォルトの名無しさん
05/12/10 02:05:23
helpコマンドがある

211:デフォルトの名無しさん
05/12/12 13:58:44
数100人のユーザがいるLinuxで
全ユーザのパスワードを一括で設定できる
シェルスクリプトを教えろよ。

212:デフォルトの名無しさん
05/12/12 14:04:46
sed 's/:[^:]:/:hoge:/'

213:デフォルトの名無しさん
05/12/12 22:19:23
evalって問答無用に変数を展開しちゃうんですよね?

214:デフォルトの名無しさん
05/12/12 22:39:28
どういう局面のことを言ってるのかわからんけど、
変数を展開するのはevalじゃないと思われ。
多分だけど、eval以前に変数が展開されてるんちゃうか。再確認してみ。
evalは展開された結果を評価してるだけのはず。

215:デフォルトの名無しさん
05/12/19 15:43:31
user> ./a.out < a000001.txt > result.txt

で結果をtxt化しているのですが、a000001.txtをa100000.txtまで処理させて
一個一個の結果を足して一つのtotal_result.txtしていきたいのです。
どのようにしたら良いのでしょうか?

具体的にはa000001.txtは以下のように出力されたとします。
1 0 3
2 4 3
3 7 7
4 8 3
5 8 1
6 2 8
7 0 4
8 2 3

a000002.txtも以下のように出力されたとします。
1 0 3
2 2 6
3 4 7
4 6 3
5 2 2
6 6 9
7 1 1
8 1 2


216:デフォルトの名無しさん
05/12/19 15:44:16
これが10万まで続くのですが、結果の2列目と3列目を足していきたのです。

1 0  6
2 6  9
3 11  14
4 14  6
5 10  3
6 8  17
7 1  5
8 3  5

(これは先ほどの二つの結果の合計です)


217:デフォルトの名無しさん
05/12/19 16:06:02
スレ違い回答だが
awk '{x[$1]+=$2;y[$1]+=$3;} END {for(i=1;i<=3;i++)printf("%d %d %d\n",i,x[i],y[i]);}' result*.txt


218:215
05/12/19 18:20:06
>>217さん
レスありがとうございます。
UNIX初心者な者で解答をみてもよく分からないのが現状です。

gccでコンパイルした後、どうしていけば10万のファイルの結果を合計していけるのでしょうか?
スレ違いとは思いますが、ご指導いただけたらと思います

219:デフォルトの名無しさん
05/12/19 19:12:10
んなのプログラムの方変更した方が早いよ


220:デフォルトの名無しさん
05/12/19 19:14:39
んなのが調べられないぐらいのレベルなら
聞いてボーッと回答待つより1万行のバッチ書け。


221:デフォルトの名無しさん
05/12/20 20:43:04
変数置換えで入れ子したい!
${${NAME##*/}%.*}
こゆー事したい場合どんなのがスマート?
わかりにくいね、上のはbasename ${NAME%.*} なんだけど


222:デフォルトの名無しさん
05/12/21 02:55:27
>>221
$ x=/a/b/c.d
$ y=${x#${x%?}}
$ echo $y
d

こういう事ならできるけど、前後を一変に取り除く方法は知らない。

$ x=/a/b/c.d
$ y=${x%.*}
$ y=${y##*/}
$ echo $y
c

これじゃダメなの?

223:デフォルトの名無しさん
05/12/21 09:50:00
>>215
joinを知れば何かが見えてくる。

224:デフォルトの名無しさん
06/01/07 16:12:11
質問です。
例えばdateで現時刻をvar.txtに出力するとします。
date > var.txt

txtファイルの中身は時間が書いてあると思うのですが、
もう一度↑のコマンドを実行した場合に、中身も上書きされてしまいますよね?
それで同じファイルに↑のコマンドの実行結果を書き足していくことは不可能ですよね。
可能でしたらその方法をおしえてくだしあー

225:デフォルトの名無しさん
06/01/07 16:19:45
>>224
date >> var.txt

226:デフォルトの名無しさん
06/01/07 16:20:23
>>225
どうも

227:デフォルトの名無しさん
06/01/09 18:04:46
ある年月が入力された時に、その前後の年月を出力するには
どのようにすればよいでしょうか?

例:
200512と入力されると、200511 200601が出力される

228:デフォルトの名無しさん
06/01/09 18:07:50
>>227
つ date コマンド

229:デフォルトの名無しさん
06/01/09 18:21:10
dateコマンドでどのようにして前の月や次の月を
表示させるのですか?

230:デフォルトの名無しさん
06/01/09 18:21:27
>>227
cut,sed,date,exprくらいでできそう

231:デフォルトの名無しさん
06/01/09 20:53:50
>229
すくなくともgnuのdateはできるよ
URLリンク(www.linux.or.jp)


232:227
06/01/09 22:31:15
>231
おおこんなことができるのですね。
勉強になりました。
これでなんとかできそうです、ありがとうございました。

233:デフォルトの名無しさん
06/01/09 22:38:31
どんな気持ちでこんなものを通したのか・・・
date --date '2 days ago'
days agoって・・・

234:227
06/01/09 23:50:58
行けそうと思ったのですが、現在時からの日にち計算しかできませんでした。
うーん。。
特定した日にちから指定するのは無理かもしれません。。

235:デフォルトの名無しさん
06/01/10 00:05:08
試してないので外れだったらスマンが
date --date '20060101 + 1 month'


236:227
06/01/10 00:12:55
>234
いけました汗
ずっと1 monthの部分を外に出して実行してた大馬鹿者でした。
ありがとうございました。

237:デフォルトの名無しさん
06/01/10 05:42:11
bash
って何て読むんですか?

ばっしゅ
ヴぁっしゅ
びーしぇる
ヴぉーんしぇる
ヴぉーんあげいんしぇる
ぷろんぷと・ヴぁっしゅ
ヴぁにっしゅ

皆さん何て読んでますか?

238:デフォルトの名無しさん
06/01/10 06:54:52
bash

239:デフォルトの名無しさん
06/01/10 06:59:25
シーシェルは孤高

240:デフォルトの名無しさん
06/01/10 10:36:42
csh使ってる奴って変態なの?

241:デフォルトの名無しさん
06/01/10 12:13:36
Solarisだと標準がcshだし。

242:デフォルトの名無しさん
06/01/10 17:05:01
tcshが使えるのにcshを使ってたら変態
スクリプト書くのにもcshを使ってたら変態


243:デフォルトの名無しさん
06/01/10 20:09:55
>>241
こらこら、嘘を教えなさんな。

244:デフォルトの名無しさん
06/01/10 20:22:49
Solaris 1 のころならな

245:デフォルトの名無しさん
06/01/10 21:42:11
>>243
Admintoolでshとcsh以外選べたっけ?

246:デフォルトの名無しさん
06/01/10 22:10:04
>>245
admintool 自体が obsolete.

247:デフォルトの名無しさん
06/01/10 22:33:06
そうだったのか。

248:デフォルトの名無しさん
06/01/11 03:43:32
Oracle入れるとcsh押し売りされるよね


249:デフォルトの名無しさん
06/01/11 04:03:14
あれは謎シェルだねw
何で直さないんだろうか。

250:デフォルトの名無しさん
06/01/22 17:16:33
command | tee log | grep hoge
としたときに、commandの終了ステータスを知る方法はありませんか?
command > log
ret=$?
grep hoge log
としとけばretを見ることで可能なんですが、それ以外で。

251:デフォルトの名無しさん
06/01/23 00:42:08
kwsk

252:デフォルトの名無しさん
06/01/23 16:39:20
(command; echo $? >/tmp/hoge) | ....
じゃだめ?

253:デフォルトの名無しさん
06/01/26 12:23:51
>>252
おお、なるほど!
ありがとうございます。

254:デフォルトの名無しさん
06/01/27 22:18:39
シエル先輩をいぢくるスレはここですか?

255:デフォルトの名無しさん
06/01/31 06:00:01
>>250
もう遅いかな?

bash には PIPESTATUS ってシェル変数があるよ。

$ true | false | exit 3 | true
$ echo ${PIPESTATUS[@]}
0 1 3 0

256:デフォルトの名無しさん
06/02/19 05:53:58
ファイルの更新日時を取得する方法を教えてください

257:デフォルトの名無しさん
06/02/19 12:04:08
>>256
stat
でもSunとかHPとかないOSもあるかも。

258:デフォルトの名無しさん
06/02/19 13:39:39
>>256
つ[`ls -l`]

259:デフォルトの名無しさん
06/02/25 01:29:18
超初心者な質問で恐縮なのですが、、

*.jpgと*.JPGのファイルを判断して

*-new.JPGのように名前を変更するには

どのようにしたら良いでしょうか?

お知恵をお貸しください。

よろしくお願いします。


260:デフォルトの名無しさん
06/02/25 01:53:34
ls *.jpg|sed -e 's/\(.*\).jpg/mv \1.jpg \1-new.JPG/' > /tmp/foo
とでもして、
source /tmp/foo
でどう?

261:デフォルトの名無しさん
06/02/25 02:50:31
bash + find ならこんな感じ?

find . -regex '.*\.\(jpg\|JPG\)' |while read i; do mv "$i" "${i%.*}-new.JPG"; done

262:デフォルトの名無しさん
06/03/14 17:51:21
@@@

263:デフォルトの名無しさん
06/03/14 18:29:29
【積年の】旦那にしてる密かな仕返し【恨みじゃー】
スレリンク(ms板)

8 名前:可愛い奥様[] 投稿日:2006/03/07(火) 11:05:23 ID:8dtluKkp
夫の歯ブラシで洗面所の排水溝掃除。
洗面所をビショビショに汚した罰だ。

20 名前:可愛い奥様[age] 投稿日:2006/03/08(水) 00:40:17 ID:pRrk6A21
前に頭きた時あって
1度だけ歯ブラシで肛門カキカキしちゃった

22 名前:可愛い奥様[] 投稿日:2006/03/08(水) 01:27:12 ID:gU5mHc7J
よかった。どこのお宅も同じようなことしてて。

24 名前:可愛い奥様[] 投稿日:2006/03/08(水) 01:36:35 ID:SSSFsTqE
そうそう、ヘンなモノはダンナのお皿へ直行だよね。

41 名前:可愛い奥様[] 投稿日:2006/03/08(水) 11:55:18 ID:sjj+/60Q
見てるだけで気が晴れるな!
皆さん、頑張ってね!

42 名前:可愛い奥様[sage] 投稿日:2006/03/08(水) 20:33:51 ID:Ju2N1s7+
年金分割が楽しみじゃのう

63 名前:可愛い奥様[] 投稿日:2006/03/10(金) 08:55:20 ID:qLfJYpJR
家族で密かにはぶっている。

男性は肉体が汚く、精神が美しい傾向がある。(気に入らない相手に肉体的攻撃を加える⇒精神的攻撃も加える男は猛者)
女は肉体が美しく、精神が汚い傾向がある。(気に入らない相手に精神的攻撃を加える⇒肉体的攻撃も加える女は猛者)
女は隠れて悪事をする。気に入らない女子を便所でボコったり、便器舐めさせたり、男の友人を使ってレイプ、仲間外れにしたり。陰口、嫉妬。
女は対人関係において、この汚い性格を隠そうとするため、外面が非常によくなる。(猫かぶり)
男性諸君は外面に騙されないように気を付けて下さい。

264:デフォルトの名無しさん
06/03/18 01:37:12
²


265:http://www.vector.co.jp/soft/win95/util/se072729.html
06/03/18 20:34:48
TextSS のWindowsXP(Professional)64bit化おながいします

もしくは64bitにネイティブ対応したテキスト置換ソフトありますか?

266:デフォルトの名無しさん
06/05/30 23:27:37
質問です。Solaris9で、

rsh 192.168.1.1 su - user -c

267:デフォルトの名無しさん
06/05/30 23:30:23
質問です。Solaris9で、

rsh 192.168.1.1 su - user -c "ls -l"

みたいな事やりたいんですけど、
"ls -l"のオプション部分が有効になりません。
なんとかならないでしょうか?

268:デフォルトの名無しさん
06/05/31 03:19:58
>>267
リモートで実行するコマンドをまとめて括れ

rsh 192.168.1.1 'su - user -c "ls -l"'


269:デフォルトの名無しさん
06/05/31 11:10:05
初歩的ですみませんがファイルのreadで質問があります
以下のreadの仕方では最終行にリターンコードがないと
最終行を読んでくれません。※リターンコードがあればreadしてくれますが・・・。
読む方法はないでしょうか

cat /aaa.txt | while read FILE
do
echo $FILE
done

aaa.txtの内容(この例だとghiを読み込まない)
abc
def
ghi

270:デフォルトの名無しさん
06/05/31 11:43:23
>>269
catじゃなくて、必ず改行するタイプのフィルターに通せばいい。
例えば、awk '{print;}'でもいける。

271:デフォルトの名無しさん
06/06/09 13:30:25
~日前のファイルを削除するようなスクリプトを作成したいのですが
どのような感じになりますか?

272:デフォルトの名無しさん
06/06/09 13:34:39
>>271
findではいけない理由があるのかね。
取り敢えず、1日(24時間)以上前のファイルを無条件に削除するならこんな感じ。
find . -mtime +1 -exec rm {} \;


273:デフォルトの名無しさん
06/06/09 14:18:24
ctimeじゃないのか

274:デフォルトの名無しさん
06/06/09 23:03:08
>>269
それ、最後の行まで普通にでたんだが、OSによるもんなのか
当方HP

275:デフォルトの名無しさん
06/06/10 08:59:55
何となく本末転倒な対処

perl -wne 'chomp;print $_."\n";' ./aaa.txt | while read FILE
do
echo $FILE
done

276:デフォルトの名無しさん
06/06/12 17:01:03
こんな感じかなあ。(以下は Linux でシェルは bash 3.00.16 使ってます)。

$ perl -e 'print "abc\ndef\nghi"' >a
$ od -c a
0000000 a b c \n d e f \n g h i
0000013
$ cat a | while read s ; do echo "* $s" ; done
* abc
* def
$ ( cat a ; echo '' ) | while read s ; do echo "* $s" ; done
* abc
* def
* ghi
$ awk 1 a | while read s ; do echo "* $s" ; done
* abc
* def
* ghi
$


277:デフォルトの名無しさん
06/06/13 11:26:53
>>272
数日前のファイルは無条件に削除という認識ではあってるのですが
ディレクトリの指定をする場合にはどのようになりますか?

278:デフォルトの名無しさん
06/06/13 12:03:13
>>277
man で調べりゃいいじゃないか。


279:272:'.'はカレントディレクトリとその配下
06/06/13 12:12:52
>>277
取り敢えずディレクトリ指定しているんだけどなぁ。

280:デフォルトの名無しさん
06/06/13 13:19:34
>>279
例えば、フォルダを指定した場合(/tmp)
find /tmp -mtime +1 -exec rm {} \;
上記で/tmpディレクトリ以下の1日以上経過したファイルの削除が行われる
と思って、よろしいのでしょうか?

281:デフォルトの名無しさん
06/06/13 14:05:59
URLリンク(www.google.com)

282:デフォルトの名無しさん
06/06/13 14:19:50
「(::´┏┓`:)なんでそんなに英語を使ってやんのが好きなの?」

283:デフォルトの名無しさん
06/06/13 14:52:23
>>280
何が消されるのか不安なら -exec から後ろをなくしてみればいい。


284:デフォルトの名無しさん
06/06/13 16:54:29
>>280
どうして、マニュアル見て自分で確認せずに聞いて済まそうとするかねえ。
嘘教えられて、重要なファイル消すはめに陥ったらどうするんだよ。

285:デフォルトの名無しさん
06/06/14 16:04:58
初歩的なことを一つ教えてください。

bshで関数定義したものを別のシェルで呼び出すことは出来ますか?
出来るとすると呼び出し方はどのようになりますでしょうか。

286:デフォルトの名無しさん
06/06/14 17:02:26
できます。
関数が入ったファイルfoo.shをbar.shの中で使いたければ、bar.shの中で
. ./foo.sh
などとすれば普通に呼べます。

287:デフォルトの名無しさん
06/06/14 17:06:41
なんだ別のシェルって、そういう意味か。

シ ェ ル ス ク リ プ ト っ て 書 け よ。


288:デフォルトの名無しさん
06/06/14 21:09:56
bshスクリプトを/bin/sh以外のシェル、たとえばcshから呼べますか?だったら
「呼べない」が答えですな。というか、そういう質問なのか?

289:285
06/06/15 00:14:48
bshで書かれたシェルスクリプト内の関数を、
別のbshで書かれたシェルスクリプトで使用することはできますか?

ということで・・・(´・ω・`)

290:デフォルトの名無しさん
06/06/23 14:19:28
while文で一つのリストファイルから呼び出しをかけて、ループさせることは
可能だと思うのですが同じwhile文中で違うリストファイルから呼び出しをかけて
変数として扱うことは可能でしょうか?

291:デフォルトの名無しさん
06/06/24 01:05:24
リストファイルって?
呼び出しって?
かけるって?


292:デフォルトの名無しさん
06/06/24 13:18:35
>>290の要求がどうなのかは知らんけど、俺も心当たりある。

... | while read var; do ...; done
っていうパターンあるじゃんか。そうじゃなくて
while [ ... ]
do
if [ ... ]; then read var1 ただしファイルディスクリプタ1(パイプやファイル)から;
else read var2 ただしファイルディスクリプタ2(別なパイプやファイル)から;
fi
done
のようなことをやりたいと思うことはあったわ。

俺はexecによるディスクリプタコピーととサブシェルプロセスを組み合わせて
やろうとして挫折して、perlに日和った。

293:デフォルトの名無しさん
06/06/25 02:48:36
sudo等でパスワードを求めるプロンプトに
expect以外で自動入力する方法はありますか?


294:271
06/07/03 10:12:10
教えていただいた通りにやってみたのですがディレクトリを削除しようとします。
find /tmp -mtime +1 -exec rm {} \;
ディレクトリ内のファイルのみ削除させる方法はあるのでしょうか?
よろしくお願いします。

295:デフォルトの名無しさん
06/07/03 10:42:10
-type f

296:271
06/07/05 10:00:59
どうやっても上手く動作しません。
どうやってもエラーが出てしまいます。
エラーの出ない方法があれば、御教示願います。
よろしくお願いします。

297:デフォルトの名無しさん
06/07/05 11:18:04
>>296
>>295

298:271
06/07/05 11:31:26
何度もすみません。
295さんの使い方が良くわかっていませんでした。
-type fとすることでファイルを見るというオプションだったのですね。
これで解決することができました。ありがとうございます。

299:デフォルトの名無しさん
06/07/06 12:01:34
DSCN0001.jpg~DSCN9999.jpgのファイルを全てtravel2006GW0001.jpg~travel2006GW9999.jpgに変更したいのですが
これを実現するLinuxのシェルスクリプトはどう記述したらいいですか?
それと
travel2006GW0001.jpg
travel2006GW0002.jpg



のようにtxtに打ち出すのもお願いします


300:デフォルトの名無しさん
06/07/06 13:16:58
>>299

マルチ死ね。これだからLinux使いの糞は... (ry

301:デフォルトの名無しさん
06/07/06 13:23:53
もう用済みじゃぼけぇwww

302:デフォルトの名無しさん
06/07/06 14:08:25
>>300
用済みなのは君だけ

303:デフォルトの名無しさん
06/07/06 23:21:48
>>299
#!/bin/sh
echo # | tee foo$$
cd $1
ls DSCN*.jpg | sed -e 's/\(.*\)\([0-9][0-9]*\)\(.*\)/mv \1\2\3 travel2006GW\2\3/' | tee -a foo$$
source foo$$
rm foo$$

304:デフォルトの名無しさん
06/07/07 08:21:44
>>299
$ for i in `seq -w 1 9999` ; do
for> mv DSCN${i}.jpg travel2006GW${i}.jpg
for> echo travel2006GW${i}.jpg
for> done > list


305:デフォルトの名無しさん
06/07/13 14:49:15
>>299

#!/bin/sh
for f in DSCN*.jpg
do
 f2=`echo $f | sed 's/DSCN/travel2006GW/'`
 echo $f2
 mv $f $f2
done


306:デフォルトの名無しさん
06/07/13 16:41:26
>>305
>f2=`echo $f | sed 's/DSCN/travel2006GW/'`

f2=${f/DSCN/travel2006GW}
でいいんじゃねんか

307:デフォルトの名無しさん
06/07/13 18:24:56
>>306
ああ、そうだ。bash はそれで行ける。


308:デフォルトの名無しさん
06/07/14 15:56:42
Bシェルを使用しています。
質問させてください。

ファイル(hoge.dat)の中のデータが下記のように3行あるとします。
1,2,3,4,5
6,7,8,9,10
11,12,13,14,15

この中から「8,9,10」だけを取りたいと思っています。

cut -d "," -f3- $hoge.dat
では

3,4,5
8,9,10
13,14,15

を取って来るのですが、何かよい方法はないでしょうか?

よろしくお願いします。

309:デフォルトの名無しさん
06/07/14 17:59:15
そのあと普通に grep かますんじゃ駄目なの?
cut -d "," -f3- $hoge.dat | grep '8,9,10'



310:デフォルトの名無しさん
06/07/14 18:23:08
だよな
何を根拠に8,9,10なのか何も書かずにいたら
echo 8,9,10
だってりっぱな回答だ

311:デフォルトの名無しさん
06/07/14 19:00:32
これでどうだ!

awk -F, 'NR==2{for(i=3;i<=NF;i++)if(s!="")s=s","$i;else s=$i;print s}' hoge.txt

でも、未確認。


312:デフォルトの名無しさん
06/07/14 20:50:24
これでも喰らえ!
head -2 hoge.txt | tail -1 | sed 's/....//'

313:デフォルトの名無しさん
06/07/14 21:06:11
マジレス
grep -v 1,2 hoge.txt | grep -v 11 | cut -b 5-10

314:デフォルトの名無しさん
06/07/14 21:37:57
head -c 21 hoge.txt | tail -c 7

315:デフォルトの名無しさん
06/07/14 22:33:44
クマー
echo `sed -e 's/$/,/' hage.dat` | cut -d "," -f8,9,10

316:デフォルトの名無しさん
06/07/14 23:29:04
こっちのほうがいいや。
sed -ne '1h;1!H;${x;s/\n/,/g;p}' hoge.dat | cut -d "," -f 8-10

317:デフォルトの名無しさん
06/07/18 09:56:22
ええい。これでどうだ。

perl -ne 'if($.==2){chomp;print join(",",(split/,/)[2..4])."\n";}' hoge.dat

ていうか >>308 はどこ行った?

318:Linax初心者
06/07/24 23:32:10
b-shallとc-shallで入力された日付が有効かどうかの確認のシェルスクリプトを作りたいのですがうるう年の計算や入力された日付が正しいかどうか判断して
正しい日付を入力させるスクリプトなんですが、初心者でわかりませんので
よろしくお願いします。


319:デフォルトの名無しさん
06/07/24 23:42:20
>>318
なんか死ね。

320:デフォルトの名無しさん
06/07/25 01:03:54
Linaxに関しては我々も初心者なもので・・・

321:デフォルトの名無しさん
06/07/25 01:25:39
えーと、スクリプトを作りたいと言うことは理解できました。
で、なにをお願いされたらよいのでしょう。

322:Linax初心者
06/07/25 06:33:39
すいません初心者で。まずは日付をキーボードから
入力して存在する日付かどうか判断して、うるう年の
計算して入力された日付が正しければ、正常表示を
間違いなら、再入力を促すものです。たとえば20061313はありえない
日付ですが20060220は正しい日付でその年がうるう年かどうか
判断して2006年 2月20日 水曜日と表示したいのですが
教えていただけますか。よろしくお願いします

323:デフォルトの名無しさん
06/07/25 08:45:49
えーと、なにを教えればよいのでしょう。

324:Linax初心者
06/07/25 09:42:19
すいませんが、会社の嫌がらせでまったくコンピュータ
したことがパソコンぐらいの45才です。リストラされそうなのですが
まったく知識がなくて本を読んでもよくわかりませんから
できましたらはじめから教えていただけませんか。
お願いします。うるう年の計算がわかりませんしその日が何曜日かも
わかりませんのでよろしくお願いします

325:デフォルトの名無しさん
06/07/25 09:55:25
>>324
それ以外にも足りん能力がわんさかあると見受けられるので、あきらめてホームレスって下さい。

326:デフォルトの名無しさん
06/07/25 10:16:18
とても45歳に見えない若々しいおじ様なのかしら♪

327:デフォルトの名無しさん
06/07/25 20:40:45
しかもマルチポスト

どうやって釣られてあげればいいのかな?

328:デフォルトの名無しさん
06/07/25 22:15:54
まずはマスタファイルを作るんだ

20060725,火
20060726,水
20060727,木
20060728,金
 :
 :


あとはわかるな?

329:デフォルトの名無しさん
06/07/25 22:33:45
そうそう、マスタファイルを作るスクリプトを作ればかなり効率が上がるよ


330:デフォルトの名無しさん
06/07/28 21:58:18
ディレクトリがさ
abc/ def/ ghi/
ってな風に同じ階層に3つあって、それぞれの中に
srcに対応したMakefileがあんだけどmakeすると
abc/ def/ ghi/  ~lib.a
とか自ディレクトリより一つ上に生成されてるのよ
んでabc、def、ghiどれmakeしても同じ名前のライブラリ作ってんだけど

これ作った人は何したかったのかわかんねぇ?

これが今日発生したバグですた・・・。
ぼすけてw


331:デフォルトの名無しさん
06/07/30 22:56:47
>>330
お前にはうかがい知れないすごい思想なのは分かった。


332:デフォルトの名無しさん
06/07/31 09:15:04
sed -f henkan.txt input.txt のhenkan.txtの部分を
ヒアドキュメントで書く方法ないでしょうか。無いか。
たんにテキストファイル増やすのが面倒なだけなんですが…

333:デフォルトの名無しさん
06/07/31 11:13:36
>>332
もしかして、sedスクリプトのコメントをスクリプトファイルに入れたいって話?
それともその行が書かれたシェルスクリプト内にコメントを入れたいって話?
シェルもsedもコメントは#で始まるから、どちらの場合も好きなところに書けばいいとおもうが。

334:デフォルトの名無しさん
06/08/01 00:07:14
>>333
はぁ?

335:デフォルトの名無しさん
06/08/01 04:00:04
>>332
複数処理なら、以下の何れかでいけると思う。

1) sed -e '処理1' -e '処理2' ... file

2) sed '
処理1
処理2
....
' file
※ 複数行をシングルか、ダブルの引用符で囲む
    囲みの中が複数行でも、sedには1つの引数として渡される

3) sed '処理1^J処理2^J...' file
※ ^J は vi で入力するなら ctrl+ESC 後に ctrl+J

OSの違いやsedのバージョンによっては駄目な方法もあるかも
シェルによって駄目とかはないと思うが、c系は自信ない

336:335
06/08/01 04:16:53
>>332
追加でこんなんでもいいわけだが・・・

4) sed '処理1' file | sed '処理2' | sed ...

つうか、何がしたいの?
複数処理をしたいんじゃないならスレ汚し、すまんす



337:335
06/08/01 04:28:16
ついでだからもう一つ、スレ汚しすまん
ヒアドキュメントに拘るなら、sedの代わりにedかex使え

ed file <<EOF
...
EOF


338:デフォルトの名無しさん
06/08/01 10:14:10
332です。ありがとうございます。
これだけ方法があるのにsedのmanを見て何も思い付かなかった
頭の悪さに恥じ入るばかりでございます

339:デフォルトの名無しさん
06/08/02 06:38:49
>>335
処理の中身にもよるが、こういう書き方でもたいていは動くはず。
一行でかけるし、プロセスを一つにまとめられるのでわりとお勧め。

$ sed '処理1; 処理2; 処理3; ...' file

340:デフォルトの名無しさん
06/08/02 08:28:05
>>339 プロセスを一つにまとめられるので

それじゃまるで>>335はプロセスが一つじゃないと言ってるように聞こえる。

341:デフォルトの名無しさん
06/08/02 14:19:39
>>340
そういやプロセスが複数なのは >>336 だけだったな。
レス番を間違えた


342:デフォルトの名無しさん
06/08/02 22:11:20
>>339
みんなが4000行かかるプログラムをたった1行で書いてやるぜ!的な。

343:デフォルトの名無しさん
06/08/02 22:49:29
よーし、俺がたった1行でコンソール埋め尽くしちゃる
echo *{,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,}


344:デフォルトの名無しさん
06/08/03 11:12:37
毎月定期的に取得しているファイル名を、例えば、
filename_`date +%Y%m%d`.txt
などとして日付けを付けて保存しています。
これが先月のものと差がない場合、新しい方を破棄したくて、
date コマンドで先月の同じ日を吐き出すことができないかと思っているのですが、
date は現在の日付けを表示することしかできないのでしょうか?具体的には、
diff filename_20060801.txt filename_20060701.txt
で内容が完全に同じだったら、filename_20060801.txt を削除するようにしたいです。
環境は Linux、kernel-2.6.9-34 です。CentOS です。
どなたかアドバイスをお願いいたします。

345:デフォルトの名無しさん
06/08/03 11:53:21
>>344
date -d "last month" +%Y%m%d

346:デフォルトの名無しさん
06/08/03 12:32:05
うおお、それでいいんですか!
どうもありがとうございます。

347:デフォルトの名無しさん
06/08/03 13:22:13
>>345
HPUXのdateはそんな便利な機能ないからうらやましいな。
前日とかならTZ変えればいいけど

348:デフォルトの名無しさん
06/10/12 15:54:09
申し訳ありません。
cshで①引数が、空であるかどうかと、②引数が、数字(何桁でも可)のみ受けとる
という条件文を書きたいのですが、
①は、if ( $# -eq )や if(x$name =x)とやってもうまくいきません。
②は、ダイレクトにif(0<=#1<=9) というやりかた?しかわかりません。

もうしわけないのですが、ご教授願えませんか?
ヒントや参考文献でもかまいません。宜しくお願いします。

349:デフォルトの名無しさん
06/10/12 23:34:19
cshやめたらいいんじゃない

350:デフォルトの名無しさん
06/10/13 17:12:45
>>348
1. 引数が空

if ( $#argv == 0 ) then
echo 空
else
echo なんかある。
endif

2. 数値かどうか

わかんねえ。こんな風にでもすれば?

set n = `echo "$argv[1]" | sed 's/[0-9][0-9]*//g'`
if ( '' == "$n" ) then
echo "$argv[1] は数値だ。"
else
echo "$argv[1] は数値ではない。"
endif


351:デフォルトの名無しさん
06/10/13 18:56:57
>>350
ありがとうございます。大変助かります。
やはり、sedコマンド使うんですね。
sedとawkを使うべきかなと思いながら、
あまりよく分かっていなかったんです。

これから試してみます。

352:デフォルトの名無しさん
06/10/13 20:31:27
>>351
本当は何か別の方法あるかも知れないけど、俺は知らない。

あと、その sed の使い方だとマイナス記号や小数点や数字と数字の途中にスペースが
あった場合とかが考慮されていないので、その辺は自分でなんとかして。


353:デフォルトの名無しさん
06/10/19 10:01:09
cshの環境で、アプリケーションログを
/backup/apl -mtime +6 -exec rm {} \;
上記のようい週次バックアップしています。

これを、直近のデータのみリストアする場合、
(最新のデータのみで、あとはいらない)
どのような表現を使えばいいのでしょうか?



354:デフォルトの名無しさん
06/10/19 21:09:43
日本語でおk

355:デフォルトの名無しさん
06/10/20 22:47:35
rshについて質問させて頂きます。
ある書籍に以下の記述がありました。

$ STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`

\マークが1個多いと思うのですが・・・。
正誤表には記載がありませんでした。
分かる方がいましたら是非回答をお願い致します。

356:デフォルトの名無しさん
06/10/21 00:09:39
>>355
引数が二回展開されるから。

まず local のシェルが引数を展開して rsh に
(hostname) と (sh -c 'ls; echo \$?') を渡す。

で、rsh が hostname のシェルで (sh -c 'ls; echo \$?') を実行する。
この時にもう一度展開される。


357:デフォルトの名無しさん
06/10/21 11:56:53
>>356
早速のご回答ありがとうございます。

>で、rsh が hostname のシェルで (sh -c 'ls; echo \$?') を実行する。
>この時にもう一度展開される。
ダブルクォーテーションで囲まれた中の$は、
シェルによってメタキャラクタと認識されてしまうので
\マークでクォートしなくてはいけないのですが、
シングルクォーテーションで囲まれた$は
メタキャラクタとは認識されないので、
\マークでクォートする必要はない、
というのが私の認識です。

よって、hostnameのシェルで実行される
(sh -c 'ls; echo \$?')の$はメタキャラクタとは
認識されないので、\マークは不要であると
思っています。

ご指摘の程よろしくお願い致します。

ちなみに今回の質問は、
書籍「入門UNIXシェルプログラミング 改訂第2版」
のP.132についてです。

358:デフォルトの名無しさん
06/10/21 19:23:38
>>357
csh 系や zsh の挙動は良く知らないが
bash のクォート除去はそこまで賢くない。

ダブルクォートの中にシングルクォートがあっても
その中身は保護されない。

例)
$ echo "$SHELL" '$SHELL' "'$SHELL'"
/bin/bash $SHELL '/bin/bash'



359:デフォルトの名無しさん
06/10/21 20:31:06
cshなんですが、
ヒアドキュメントの内容を変数に格納するのはどうやったらいいんでしょうか

360:デフォルトの名無しさん
06/10/22 04:00:06
負の遺産を量産するな。shか最悪kshで書き直せ。
(t)cshが許されるのはログインシェルまで。

361:359
06/10/25 13:13:03
古いsoralisのメンテしてる上に周りがcshしか理解できないんで仕方なく・・・
本当はbash使いたいんですけどね



362:デフォルトの名無しさん
06/10/29 15:43:34
別に仕方ないことないだろに。


363:デフォルトの名無しさん
06/10/29 18:22:40
>>356
エスケープの処理はバッククォートとダブルクォートのときじゃないか?
rshが受け取る文字列は(sh -c 'ls; echo $?')だと思うんだけど。

(STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`)
ローカルのシェルが、バッククォートとして実行する文字を解釈 -> (rsh hostname "sh -c 'ls; echo \$?'")
バッククォートが、rshを呼び出す為に引数を展開 -> (hostname) (sh -c 'ls; echo $?')
rshがhostnameに入って、ホストのシェルで第二引数を実行 -> (sh -c 'ls; echo $?')
sh -c の処理 -> (ls; echo $?)

>ダブルクォートの中にシングルクォートがあっても
>その中身は保護されない。
ダブルクォートの中のシングルクォートは単なる文字なのでこれはこれで合ってるけど。



364:デフォルトの名無しさん
06/10/29 23:14:19
>>363
bash の man を参照するとわかるがクォートの除去は
各種展開が終わってから行われる。
冗長に処理の流れを書くとこうなる。

1. コマンド実行 -> (STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`)
2. ローカルのシェルがコマンド置換(バッククォートの処理)を行う -> (rsh hostname "sh -c 'ls; echo \\$?'")
3. サブシェルが起動してバッククォートの中身を展開する -> (rsh) (hostname) (sh -c 'ls; echo \$?')
4. サブシェルが rsh に引数 (hostname) (sh -c 'ls; echo \$?') を渡す
5. rsh が hostname のシェルに (sh -c 'ls; echo \$?') を渡す
6. hostname のシェルが引数を展開する -> (sh) (-c) (ls; echo \$?)
7. hostname のシェルが sh に (-c) (ls; echo \$?) を渡す
8. sh が引数を展開、実行する -> (ls; echo $?)
9. sh -> hostname のシェル -> rsh -> サブシェルの順に返り値が渡り、コマンド置換が終了
10. STAT に返り値が代入される

365:デフォルトの名無しさん
06/10/30 02:27:55
>>364
> bash の man を参照するとわかるがクォートの除去は
> 各種展開が終わってから行われる。
EXPANTIONSのとこにあるこれ?
The order of expansions is: brace expansion, tilde expansion, parameter, variable and arithmetic expansion and
command substitution (done in a left-to-right fashion), word splitting, and pathname expansion.

ここにあるのは、どの順で実行されていくかの説明で、クォートの解釈は別の段階だぞ。
Expansion is performed on the command line after it has been split into words.
ってあるとおり、(1)シェルが一行読み込まれる → (2)単語への分割 → (3)各要素を展開する
のうち(2)の話だ。(3)にある単語分割とは別物
#1行じゃない場合はちょっとおいといてくれ


> 2. ローカルのシェルがコマンド置換(バッククォートの処理)を行う -> (rsh hostname "sh -c 'ls; echo \\$?'")
これの前に単語への分割があって、バッククォートを使っているとバックスラッシュの前にあるバックスラッシュはエスケープとして扱われるから、
(STAT=`rsh hostname "sh -c 'ls; echo \\$?'"`) -> (STAT) (=) (`rsh hostname "sh -c 'ls; echo \$?'"`)
この段階でバックスラッシュは一個になる。
(っていうか、そうじゃないと入れ子になったバッククォートの範囲を確定できないし)

コマンド置換の展開が実行されると、サブシェルがまた単語への分割を実施して、
今回はダブルクォートのルールに従ってバックスラッシュは$に対するエスケープ文字になる。
(rsh hostname "sh -c 'ls; echo \$?'") -> (rsh) (hostname) ("sh -c 'ls; echo $?'")


「bash -v -x」してから「echo `echo "'\\$abc'"`」ってやってみ。
読み込んだ文字と、展開結果が出てくる。
サブシェルが読み込んだ文字列は
echo "'\$abc'"
になってて、すでに一回バックスラッシュが処理されてる。

366:デフォルトの名無しさん
06/10/30 03:36:14
>>365
ほー、そうだったのか。
やっぱりこういう事は自分で検証しないとダメだな。
的確な突っ込み感謝。

367:デフォルトの名無しさん
06/10/30 12:33:25
>366
そういや、肝心の355はどこいったんだ?

368:デフォルトの名無しさん
06/11/02 23:45:43
355です。

はっ!、と思って只今本スレを確認しました。
しばらくの間に様々な回答を頂き、本当にありがとうございます。
これからじっくり読ませて頂きます!

369:デフォルトの名無しさん
06/11/04 20:27:36
微妙にスレ違いかもですが

あるファイルに対する処理をパイプで繋げて、
最終的に同名のファイルに書くのはアリなんでしょうか

cat hoge.txt | grep "foo" | uniq | sort > hoge.txt

現状動いてはいるんですが・・・

ちなみにbashです


370:デフォルトの名無しさん
06/11/04 21:33:13
>>369
途中のコマンドがエラーを吐くと空になるが、いいのか?

期待通りに動いているのなら、アリではあるが
どこの環境でも動くという保証は無い。

俺ならいったん変数に入れてから書き出すかな。

a=`grep "foo" hoge.txt | sort -u`

if [ -n "$a" ] ; then
echo "$a" > hoge.txt
fi

371:デフォルトの名無しさん
06/11/04 21:35:18
あ、よく考えたら uniq | sort と sort -u は違うな。
適当に読み替えてくれ。

372:デフォルトの名無しさん
06/11/04 21:37:33
>>369
>最終的に同名のファイルに書くのはアリなんでしょうか
ダメ。


373:デフォルトの名無しさん
06/11/04 23:26:40
特定の時間帯のログだけ抽出したい場合ってどうしたらいいんでしょうか?


374:デフォルトの名無しさん
06/11/04 23:29:03
awk

375:デフォルトの名無しさん
06/11/05 04:29:12
PM18::00からAM1:00までの場合はどうすれば?

376:デフォルトの名無しさん
06/11/05 04:31:11
ログファイルの仕様は?

377:デフォルトの名無しさん
06/11/05 04:34:07
やりかたはログによる

378:デフォルトの名無しさん
06/11/05 04:46:30
2006/11/04,01:37:33,xxxxxxxxxxxxxxxxxxxxxxx
2006/11/04,02:37:33,xxxxxxxxxxxxxxxxxxxxxxx
2006/11/04,03:37:33,xxxxxxxxxxxxxxxxxxxxxxx
2006/11/04,04:37:33,xxxxxxxxxxxxxxxxxxxxxxx
2006/11/04,16:37:33,xxxxxxxxxxxxxxxxxxxxxxx
2006/11/04,21:37:33,xxxxxxxxxxxxxxxxxxxxxxx

こんなかんじ

379:デフォルトの名無しさん
06/11/05 04:52:32
ぱっと思い付かないけど、俺ならperl使うかな。

ログをとる時間とタイミングが決まってるなら検討付けて
timeコマンドで1:00にtail -10とかでがばっと適当にログを切り出して保存する。

380:デフォルトの名無しさん
06/11/05 04:56:47
>>378のフォーマットなら1行野郎でできる

awk -F '[,:]' '$2>=18||$2<1' logfile

381:379
06/11/05 05:24:52
>>380
お前マジ頭いいな

382:デフォルトの名無しさん
06/11/05 10:47:41
>>375
>PM18::00
それは一体何時なんだ?
もし、18時のことを書きたいなら6PMと書かないと意味が通じないわけだが。

383:デフォルトの名無しさん
06/11/05 10:48:59
通じなくてよし

384:デフォルトの名無しさん
06/11/05 14:16:24
なんか、awkの話になってるんで便乗で質問ですが

シェルスクリプトから

awk -f 手続きファイル 参照ファイル

とやって、-vでawkスクリプトに引数を渡してawk内で使用するのって具体的にはどうやればいいんですかね?



385:デフォルトの名無しさん
06/11/05 14:28:58
・・・・・<dateAndTime>20061101130655</dateAndTime>・・・・・・・・・・・・・・・・・
・・<dateAndTime>20061101160213</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・・・・<dateAndTime>20061101180159</dateAndTime>・・・・・・・・・・・・・・・・・
・・・<dateAndTime>20061102200159</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・・・・・・・・・・・<dateAndTime>20061103210159</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・<dateAndTime>20061104220159</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・・・・<dateAndTime>20061104131259</dateAndTime>・・・・・・・・・・・・・・・・・
・・<dateAndTime>20061104011359</dateAndTime>・・・・・・・・・・・・・・・・・
・・<dateAndTime>20061104052359</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・・・・<dateAndTime>20061105062059</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・<dateAndTime>20061106072159</dateAndTime>・・・・・・・・・・・・・・・・・
・・・<dateAndTime>20061106114359</dateAndTime>・・・・・・・・・・・・・・・・・
・・・<dateAndTime>20061107221359</dateAndTime>・・・・・・・・・・・・・・・・・
・・・・・・<dateAndTime>20061108230559</dateAndTime>・・・・・・・・・・・・・・・・・

ログがタグ形式で、こんな感じだったらawkではどうする?

386:明日まで
06/11/05 14:36:03

こういうシェルを私みたいな女の子にも理解できるように解説してよ


引数付(1~5)で実行したshellが何を引数として入力
  したかを,switch文を使って表示させたい。。

【その1】引数無し、もしくは引数が1~5以外の場合
% ./test.sh
Invalid number.
%

【その2】引数が1~5の場合
(5を入力した場合)
% ./test.sh 5
You have imput 5.

387:デフォルトの名無しさん
06/11/05 14:52:33
>>384
たぶん勉強すればどうにかなるんだろうけど、
awkで引数に関することでごにょごにょするのがめんどくなったのでPerlに移った。
awkは短い命令やパイプラインで使ったりはするけど、引数でごにょごにょするのは
Perlでやることにした。

>>

388:デフォルトの名無しさん
06/11/05 14:55:02
>>386
case文でnull,$1~$5までのケース書いて、その他は(*にでも書けば良いじゃん

389:デフォルトの名無しさん
06/11/05 15:30:16
>>384
別にawkに限った話じゃないので、普通に引き数で渡せば宜しい。
後は、awkかnawkかgawkか、変数定義かARGVを使うかの違いがあるだけ。

>>385
外部プロセスでsedを呼んで処理するか、awkを呼び出すシェルスクリプト側でsedを呼んで処理する。

390:デフォルトの名無しさん
06/11/05 20:52:42
誰かこのシェル作って
今日中にやらないといけないんです、お願いします。

引数付(1~5)で実行したshellが何を引数として入力
  したかを,switch文を使って表示させたい。。

【その1】引数無し、もしくは引数が1~5以外の場合
% ./test.sh
Invalid number.
%

【その2】引数が1~5の場合
(5を入力した場合)
% ./test.sh 5
You have imput 5.


391:デフォルトの名無しさん
06/11/05 22:22:18
シェルスクリプトの中身↓

awk -f xxx.awk -v awkNoHensu=${shellNoHensu} aaa.txt


xxx.awkの中身↓

{
print ${awkNoHensu}
}

awkってよくわかんないけど引数ってこんなかんじでいけるのかな?
横レスですが、外部プロセスでsedを呼ぶってひょっとしてsystemコマンド(system関数)?

392:デフォルトの名無しさん
06/11/05 23:29:32
awkはCのpopen()相当をかなり変態的かつシンプルな形で表現できる。
Ex.
--
#!awk -f
BEGIN {
if (ARGC > 1) {
cmd = "wc -l " ARGV[1];
cmd | getline fileLineCnt;
close(cmd);
}
}
{
if (fileLineCnt) {
printf("%d/%d %s\n", NR, fileLineCnt, $0);
}
}
--
sedで前処理するのも、これと同じ要領。

393:392
06/11/05 23:33:02
おっと、折角だから最後のブロックを訂正。
--
{
if (fileLineCnt) {
printf("%d/%d:", NR, fileLineCnt);
}
print;
}
--
これでコマンドライン引き数がないときはただのフィルターになる。
#>392のは引き数がないと何もしなかった。

394:デフォルトの名無しさん
06/11/06 02:23:46
>>391

awkスクリプトの中で参照するときに$つけなくてもよい。つかつけちゃダメ。
$つけたらフィールド参照になっちゃうから。

awk -v foo=ほげほげ ...

で渡したのなら、単に foo で参照できる。


395:デフォルトの名無しさん
06/11/06 17:18:33
grepでは1行が2048バイトの制限がありますが、
awkやsedの制限はどうなっているのかどなたか教えてください


396:デフォルトの名無しさん
06/11/06 20:23:22
知らない。不安なら perl 使っとけ。メモリの続く限り無制限だから。


397:デフォルトの名無しさん
06/11/06 22:09:24
2048バイト制限のあるgrepって、どのgrepのこと?


398:デフォルトの名無しさん
06/11/07 00:30:09
>>392
それはawk -v で引数を渡せばいいですか?

399:392
06/11/07 03:18:46
めんどくさい香具師だなぁ。
>393のスクリプトにfooとでも名づけて実行ビット立てたら foo foo とでもして味噌。

400:デフォルトの名無しさん
06/11/07 23:31:42
>>395
sedにも制限あったはず。それでperlにしたことがある。
てか試せ

401:デフォルトの名無しさん
06/11/07 23:49:35
>>391
awkに-vでシェルの変数を引数で渡す場合、BEGIN内でしか参照できないからあんまり意味ないですよー
嘘言ってたらごめんなさい

402:デフォルトの名無しさん
06/11/08 00:30:45
>>401
ぇ…(´Д`υ)
% awk -v foo=hello 'END { print foo }'
^Dhello
%

403:デフォルトの名無しさん
06/11/08 01:25:16
---------------
BEGIN{}

/○○/{

print$1



END{}
---------------


○○のところにシェルから持ってきた変数って使えますかね?
使えたら変数によって検索条件を変えられるんでawk最強って話になるんですが。

404:デフォルトの名無しさん
06/11/08 01:41:35
例えば,↓のようにできる

% cat emp.data
Beth 4.00 0
Dan 3.75 0
Kathy 4.00 10
Mark 5.00 20
Mary 5.50 22
Susie 4.25 18
% awk -v name=Kathy '$1 ~ name { print $2 }' emp.data
4.00
%

405:デフォルトの名無しさん
06/11/08 01:50:47
>>395

GNU sed とか gawkなら多分制限はない(メモリの許す限り)。
SUSv3をみたところ、OSごとに一行の最大の長さを定義している
LINE_MAX という定数があって、そこまでは使えることが保証
されているだけみたい。

で、FreeBSDとSolarisはこのLINE_MAXは2048バイトのようだ。


406:403
06/11/08 02:00:33
テキストをawkでカンマ区切りなどに成型した後ならそれはかなり使えそう技ですね。
しばし感心してしまいました。

でも、仮に以下のような感じのデータだったらやっぱできないんでしょうかね?
行にある、特定の文字列だけにヒットするような感じで。
たとえば/○○/のところに、BOOという引数を与えて、BOOを含む行だけ検索して特定の処理をするみたいな?

TXT
---------------
AAAAADSLADLAS
UEJNDNKA
KDJSALJDLKSA
HHHHHBOOA+aDSA
DSKAJDKASL
DSKLA+KDAS
---------------

AWK
---------------
BEGIN{}

/○○/{

何かしらの処理



END{}
---------------




407:デフォルトの名無しさん
06/11/08 02:07:10
>>406
awk -v pattern=BOO '$0 ~ pattern { print }'

408:デフォルトの名無しさん
06/11/08 13:59:33
>>403
そんなもんこうやって無理矢理やってしまえばできる。

awk '/'"$x"'/{ ... }'


409:デフォルトの名無しさん
06/11/08 21:08:39
つうかもうちょっとawkを勉強して、試した上で聞けよな・・

410:デフォルトの名無しさん
06/11/09 22:19:29
>>409
でも、Awk神がいるからか、
最近のこのスレの話の流れはなかなか為になってるよ。
まあ、シェルはある程度分かるが、
長年Awkを馬鹿にして敬遠してきた俺から言わせてもらえばだけどね。
んで、このスレ読んでAwkでも勉強してみようと思い立ち
オライリーの書籍を注文してしまったw
今思えば、俺が今まで仕事でやってきた案件なんぞ
PerlやRuby使うまでもないことばっかりってことが判明してちと鬱だがね・・・orz...

411:デフォルトの名無しさん
06/11/09 22:25:23
ファイル処理に便利だしね
シェルスクリプト作ってた筈なのに
気がつくとawkとsedの処理が8割だった事がある


412:デフォルトの名無しさん
06/11/10 00:34:43
下手な文字列処理なんかだと、Cで書くよりよっぽど早いしメンテナンスしやすいからな。

413:デフォルトの名無しさん
06/11/10 13:50:16
うちの高専で半年くらいawkばっかりやらせてた測量学の教官がいた

414:デフォルトの名無しさん
06/11/10 13:53:17

授業で

415:デフォルトの名無しさん
06/11/10 15:36:22
ときどきでいいのでawkスレのことも思い出してあげてください。

スレリンク(tech板)

416:デフォルトの名無しさん
06/11/12 16:23:26
>>410
「一寸、微笑ましい」という本心をコメントする。

417:デフォルトの名無しさん
06/11/13 17:30:40
>>380
23:15~03:15とか
04:30~9:30とか
分の単位がある場合でも
一行で簡潔にかけたりする?


418:デフォルトの名無しさん
06/11/13 19:14:24
>>417
awk -F '[,:]' '$2$3>="2315"||$2$3<"0315"' logfile

awk -F '[,:]' '$2$3>="0430"&&$2$3<"0930"' logfile

419:デフォルトの名無しさん
06/11/13 21:42:59
>>417
$2>=23&&$3>=15||$2<2||$2<3&&$3<15
こんな感じの書き方をすりゃいいんでないの?とアドバイスをしようと思ったら
>>418がなんかすごい技を繰り出してて…恥ずかしくなってきた罠。

420:デフォルトの名無しさん
06/11/13 21:59:53
>>412
AWKの文字列処理ってCより速いの?

421:デフォルトの名無しさん
06/11/13 22:18:38
>418
-F ×
-f ○


422:デフォルトの名無しさん
06/11/13 22:56:55
>>421
been opened if it were a file name. The option -v followed by var=value is
an assignment to be done before prog is executed; any number of -v options
may be present. The -F fs option defines the input field separator to be
the regular expression fs.
/usr/share/man/cat1/awk.1 line 26/250 (11%)

423:デフォルトの名無しさん
06/11/13 23:05:47
>>421
コマンドラインで FS の設定をしてるから間違っとらんよ。

424:デフォルトの名無しさん
06/11/13 23:38:44
リストファイルから一行ずつパターンを読み込ませて
テキストファイルを一行ずつパターン検索したいんですが
awkでファイルから入力する方法ってありますか?


425:デフォルトの名無しさん
06/11/13 23:51:26
getline関数は現在の入力ファイルから次の入力レコードを $0 に代入する。
getline < file は file から次の入力レコードを $0 に代入する。
getline x は変数 x に代入する。
cmd | getline は cmd の出力を getline にパイプする。
getline は入力が成功すると1,ファイルの末尾で 0,エラーで -1 を返す。

426:412
06/11/13 23:56:23
>>420
「速い」じゃなくて「早い」だ。つまり、どっちが早くプログラミングできるかってこと。

427:デフォルトの名無しさん
06/11/13 23:57:53
変数を受け取って、一連の処理を行うようにしたコマンドの羅列だろ。
ひとつずつコマンドを打ち込んで処理するのが面倒くさいから
判定とか分岐とか呼び出しとかを使って、処理自体を複雑・多様化するようにしたんだろ。
更に、ひとくくりの処理を名前を付けて登録できるから、コマンドはそれひとつで
自分で組んだ複数の処理をしてくれる。

基本的に古臭いものだし、フロントエンドを設けてGUI化したのを
使うのが最適だと思うのに、何故に今更ながらのコマンドシェルなんだ?

馬鹿?

428:デフォルトの名無しさん
06/11/14 00:08:47

〃∩ ∧_∧
⊂⌒( ・ω・)
 `ヽ_っ⌒/⌒c   はいはいわろすわろす
    ⌒ ⌒

429:デフォルトの名無しさん
06/11/14 07:07:15
>>424
同じファイルの次行レコードをgetlineで読めるはずだけど
処理中に別ファイルは読めないんじゃないかな
fopenとかないし引数とらせるとかなら方法あるかもな

430:デフォルトの名無しさん
06/11/14 07:37:30
>>429
>425

431:デフォルトの名無しさん
06/11/14 19:44:15

パターンファイルに一致するレコードを削除したいのですが、どうやったら実現できるでしょうか?
シェルでもアークでも構いません。御指南下さい。

テキストファイル(テキスト.txt)
20061110,AAA
20061111,BBB
20061112,CCC
20061113,DDD







パターンファイル(パターン.ptn)
AAA
CCC
GGG

432:デフォルトの名無しさん
06/11/14 19:45:09
>シェル
失せろ

>アーク
消えろ

433:デフォルトの名無しさん
06/11/14 20:35:18
% cat foo.awk
BEGIN {
    while (getline < ptn == 1)
        pattern[n++] = $0
}

{
    for (i = 0; i < n; i++)
        if ($0 ~ pattern[i])
            break
    if (i == n)
        print
}
% awk -f foo.awk -v ptn=pattern.ptn text.txt
20061111,BBB
20061113,DDD
20061114,EEE
……

434:デフォルトの名無しさん
06/11/14 20:51:08
grep -v -f パターン.ptn テキスト.txt

435:デフォルトの名無しさん
06/11/14 21:52:58
>431
アークじゃないよ。
オークって読むよ。


>433
awkって何でもできるんだな。

436:デフォルトの名無しさん
06/11/14 22:07:46
>>415にも書いてるけどawkスレも使ってやってください。
awkについて語るスレ
スレリンク(tech板)

437:デフォルトの名無しさん
06/11/14 23:03:02
>>433
オークってよむんですか。
ありがとうございます。

438:デフォルトの名無しさん
06/11/15 00:37:29
bashなんですが、daemonの起動スクリプトとかで
変数にブレースがついてたり、ついてなかったりするのは
どういう意図があるの?

439:デフォルトの名無しさん
06/11/15 00:58:40
>>438
1. 変数と文字列を明示的に区切りたいから
ex) ${foo}bar

2. ブレース展開を使っている
ex) ${foo%.*}

3. ただの気まぐれ

440:デフォルトの名無しさん
06/11/16 00:52:32
getline 変数 で、次のレコードを読んで変数に代入になると思いますが、
更にgetline 変数を使うと更に次の行が読み込まれるのでしょうか?
そのあとawk処理を終えて次のレコードをawkが読みに行ったとき、getlineの影響を受けて読んでいる行が進んでしまいますか?

AWKスクリプト

getline A
PRINT A
getline A
PRINT A


読み込みファイル
AAAAA
BBBBB
CCCCC
DDDDD

出力結果はこう?
AAAAA
BBBBB
CCCCC
DDDDD

出力結果はこう?
AAAAA
BBBBB
BBBBB
CCCCC
CCCCC
DDDDD

441:デフォルトの名無しさん
06/11/16 00:57:16
やってみればいいじゃん。
つーか、シェルからの起動も絡まないawkの話はawkのスレでやれよ。

442:デフォルトの名無しさん
06/11/16 01:02:20
スレ名変えればいいだろ、

【シェルって】サーバ用途のスクリプト【貝殻?】

443:デフォルトの名無しさん
06/11/16 01:07:00
sedなんかを使って特定のタグで囲まれたところを出力することって可能ですか?

sdak;dkslakdas;das<TAG>dkalkdlas;kdsla;kds;akdsal;dkslad;</TAG>dlaskldkalsfocmdcsdlc,ds



444:デフォルトの名無しさん
06/11/16 01:12:20
行内に開始タグ終了タグが1セットだけあるなら、
sed -ne 's/<TAG>\(.*\)<\/TAG>/\1/p'

445:デフォルトの名無しさん
06/11/16 01:14:40
>>441
たとえば>433のawkスクリプトでやってることをシェルスクリプトで実現したらどうなるかとかってのを
>441自身が率先してレスしてやるとかすればこのスレももっと進歩するんじゃないの?
絡まない話と切って捨てるのではなく絡める努力なんてこともしてみたらいかがか?

446:デフォルトの名無しさん
06/11/16 01:20:07
AwkにはSYSTEM関数もあるし
UNIXのコマンドも使えちゃうので
必ずしも無関係とは言えないか

447:デフォルトの名無しさん
06/11/17 00:46:21
寂しいスレになったね。

448:デフォルトの名無しさん
06/11/28 00:16:29
あるファイルの一部(何行もある)を違うファイルに書き換えるのはどうやるの?
例えば、

aaa aaa aaa
aaa aaa aaa
abc 1 2
abc 3 4
bbb bbb bbb

というファイルを

abc 1 10
abc 3 20

と言うファイルを使って

aaa aaa aaa
aaa aaa aaa
abc 1 2 10
abc 3 4 20
bbb bbb bbb

にしたいんだけど。。
どえらく行があって普通にsedの置換する行を書かせて実行したら
一日で終わらないくらい時間がかかってしまって。。。
もしくは、行単位で置換じゃなくて、数行単位で置換は出来ないのでしょうか?

偉い人教えてください。

449:デフォルトの名無しさん
06/11/28 02:05:01
>>448
正直説明が分かりづらいです。
というか全くわかんない。
ちゃんと質問した方が良い。
その質問じゃ法則がいまいちわからない。

ファイルの一部を違うファイルに書き換える??
catとか使って結合したらいかが?

450:デフォルトの名無しさん
06/11/28 02:11:28
マルチ乙

451:デフォルトの名無しさん
06/11/28 11:34:00
>>448
それはスペース区切りで先頭の項目をキーにして残りのデータは重複なしで
マージするという処理をしたいということか? あれ? でも、 aaa とかは
元から重複してるな。

駄目だ。やっぱ法則が分からん。


452:デフォルトの名無しさん
06/11/28 14:02:55
>>448

二つのファイルを第1フィールドと第2フィールドを“,”とかでくっつけて
(それぞれ test1.txt, test2.txt とする)、join(1) する:

 join -a1 test1.txt test2.txt

最後に“,”を削る。

それか、awk の連想配列を使って join する。

453:デフォルトの名無しさん
06/11/28 23:56:25
回答ありがとうございました。
分かりずらかったかと思いますので再度書き込ませてください。

一連の序列が混ざったファイルがあります。
例えば、
aaa bbb ccc ddd
.
ccc ddd eee fff
.
こんな感じの序列が続いた後に
linux 123 987 786 0
linux 123 903 673
linux 123 876 986 0
.
linux 234 983 934 0
linux 234 073 345 0
.
linux 345 093 945 0
linux 345 495 384
.
xyz abc def ghi
xyz ade dfe sdg
.
となっていて変えたいところはlinux~です。

454:デフォルトの名無しさん
06/11/28 23:57:11
ここの行を
linux 123 987 786 22
linux 123 903 673 22
.
linux 234 983 934 85
linux 234 073 345 85
.
linux 345 093 945 45
linux 345 495 384 45

としたいのです。
最後の0はあったりなかったします。
最後の行に各々の22,85,45を追加(または0を置換)したいのです。
2列目は123,234,345のようにまとまりがあります。
あとはランダムです。
存在するファイルは
123 22
234 85
345 45
.
というファイルです。

455:デフォルトの名無しさん
06/11/28 23:59:27
自分は一行ずつ置換するためsedを作成するためのプログラムを作成しました。
ですが、数が一万行を超えるので、一日ではとても終わらないものになりました。
ファイルを分割してlinuxを含まない上下のファイルをとっておいて、
置換ではなくてlinux~のファイルを作ってしまいcatで付けようとか考えていますが、
cutとかで分割する際にそんな指定って出来るんでしたっけ?
質問ばかりですいません。
宜しくお願いします。

456:デフォルトの名無しさん
06/11/29 00:10:55
追加ですが、
linux 123 987 786 22
linux 123 903 673 22
.
linux 234 983 934 85
linux 234 073 345 85
.
linux 345 093 945 45
linux 345 495 384 45
というファイルは作成出来るのですが、
これを元のファイルに反映させたいです。
手動でやるしかないですかね。。。

457:デフォルトの名無しさん
06/11/29 00:21:19
元ファイルをtest1.dat 参照ファイルをtest2.datとして
join -a1 -o 1.1 1.2 1.3 1.4 2.2 test1.dat test2.dat
とすればいいですかね。。。
joinは使ったことが無いので分かりませんが。。。

458:デフォルトの名無しさん
06/11/29 08:07:28
例示ばかりで、肝心の変換のための法則について
何も書かれちゃいねぇ!

「変えたいところは」「ここの行を…としたい」
「あったりなかったりします」

場所と結果だけ示されてもねぇ。。

459:デフォルトの名無しさん
06/11/29 08:12:43
ここはこうだから、これをこれと入れ換えます。
という説明はできないもんだろうか。

関係ないけど先日会社に面接に来た香具師。
「自己アピールは大切ですから」と言いつつ何ら具体的なことは何も言わないで帰った。
要は、客観視できていないし説明することもできないらしい。
#そのくせ、ランバ・ラルの台詞を語ってはいたのだが。

460:デフォルトの名無しさん
06/11/29 08:17:11
何か耳が痛いな。

461:デフォルトの名無しさん
06/11/29 08:23:42
言語機能の差が、スクリプト処理の決定的差ではないという事をおしえてやる

462:デフォルトの名無しさん
06/11/29 11:23:46
1万行の処理なんて一瞬で終わると思うんだが……
仮に行数Lに対して実行時間が O(L^2) だとしてもちょっと待てば終わるくらいだと思

463:デフォルトの名無しさん
06/11/29 12:06:13
すごい遅いマシン使ってるのかな?

464:デフォルトの名無しさん
06/11/29 17:32:54
シェルスクリプトじゃないけど。awkでやってみた。
BEGIN{
while(getline<ARGV[2]){
cv[$1]=$2;
}
ARGV[2]="";
}
$1=="linux"{
$5=cv[$2];
}
{
print;
}


465:デフォルトの名無しさん
06/12/05 21:39:41
csh で if($hoge == hoge) とかやったばあい、
$hoge が -f などの場合
ファイルに関する演算子の -f とみなされて
比較してくれません。
こういう場合、どうすればいいのでしょうか?

466:デフォルトの名無しさん
06/12/05 22:17:11
あ、適当な文字を両辺の先頭に付ければいけますね。
何か格好悪いので、もっといい解決法があればよろしくお願いします。

467:デフォルトの名無しさん
06/12/06 22:42:36
ファイル名の拡張子より前の名前を抽出するシェルを作っています。
例えばtest.shであれば

ls test.sh | awk -F '[.]' '{print $1}'
でtestと出力が得られるのですが、もしファイル名がtest_1.00.shの時は
test_1
のような出力になってしまいます。

awkの$NFで拡張子のshは得られるのですが、
$NF「以外全て」を出力を得るにはどのようにすればよいでしょうか?

468:デフォルトの名無しさん
06/12/06 22:48:02
>>467
man basenameでだめなんか。
それから、シェルスクリプトのことをシェル呼ぶなってば。

469:デフォルトの名無しさん
06/12/06 22:49:51
シェルスク?
シェクリ?
ルスクリ?

470:デフォルトの名無しさん
06/12/06 23:02:51
>>468
できますた。
ありがとうございました。

471:デフォルトの名無しさん
06/12/06 23:13:44
>>467
awkでやるなら
jgawk -F. "{print jsubstr($0,0,jlength($0)-jlength($NF)-1)}"
でどう?

472:デフォルトの名無しさん
06/12/06 23:28:06
>>471
試してみたのですが残念ながら、現在の環境ではjgawkというのが入ってないみたいです…
basenameはcaseで知ってる拡張子を洗いざらい場合分けするスクリプトかいて処理しました。
(txt f90 c c++ java shなど)

jgawkのインストールについて調べてみます

473:デフォルトの名無しさん
06/12/06 23:29:05
c++じゃなくてcppだった…

474:デフォルトの名無しさん
06/12/06 23:34:47
ちなみにローカルな目的は、
a2psを使ってpsファイルを作る事でした。

a2ps test1.00.sh -o test1.00.ps

拡張子を取り除いてpsの拡張子を付けるためのスクリプトを作る方法を考えていました。
basename&case文で対応はできたのですが、jgawkというのが使えるのであれば
より汎用性のあるスクリプトができそうですね。

475:デフォルトの名無しさん
06/12/06 23:40:59
ちなみに、gawkはありましたが
$ gawk -F. "{print jsubstr($0,0,jlength($0)-jlength($NF)-1)}" test1.00.sh
gawk: cmd. line:1: (FILENAME=test1.00.sh FNR=1) fatal: function `jsubstr' not defined
でした。

476:デフォルトの名無しさん
06/12/07 00:01:50
>>475
jgawkのjはJapanese(日本語)のj、
jlengthやjsubstrのjも同じ。
データーに日本語が入ってないならjは除けていいよ。


477:デフォルトの名無しさん
06/12/07 00:27:39
>>467
Solaris のawkみたいに腐ったやつだとわからないけど、gawkなら
NF--; print $0
で取れないか?


478:デフォルトの名無しさん
06/12/07 00:33:01
>>477
jgawkでやったら
aaa.bbb.ccc.dddが
aaa bbb cccになった。

479:デフォルトの名無しさん
06/12/08 01:05:00
NFってなに?
Systemコマンドの使い方教えて

480:477
06/12/08 01:21:03
>>478
スマソ。OFSを設定してクレイ。
gawk -F'[.]' -v OFS='.' '{NF--; print}
あたりでよろしこ。



481:デフォルトの名無しさん
06/12/13 21:04:58
shellってすごいね

482:デフォルトの名無しさん
06/12/22 23:27:33
#!/bin/sh
dump -0f /path/to/hda1.dump /dev/hda1
dump -0f /path/to/hda2.dump /dev/hda2

このスクリプトを実行して、hda1の実行途中でCtrl+Cを押したら
hda1は終了するけど次行のhda2のバックアップが開始されます。
スクリプト自体を終了するにはどうしますか?

483:デフォルトの名無しさん
06/12/24 10:47:11
>>482
dump は使ったことないので、勘ですが
dump -0f /path/to/hda1.dump /dev/hda1
if [ $? -ne 0 ]
then
dump -0f /path/to/hda2.dump /dev/hda2
fi
じゃ、だめですか?

484:デフォルトの名無しさん
06/12/24 12:55:55
#!/bin/sh -e
dump -0f /path/to/hda1.dump /dev/hda1
dump -0f /path/to/hda2.dump /dev/hda2


485:デフォルトの名無しさん
06/12/26 23:54:08
sedで-dオプションを使って、特定の文字列がヒットした時に、
その行を削除したいのですがうまくいきません。
manpageみても使い方がよくわからず、困り果てております。
どうやって使えばいいかご教授お願いします。

486:デフォルトの名無しさん
06/12/26 23:58:45
>>485
-dオプション???

単純に行削除だけなら例えば以下のように。
--
sed -e '1,5d' #最初の5行を削除
sed -e '/pattern/d' #patternを含む業を削除

487:デフォルトの名無しさん
06/12/27 06:42:35
>>486

使い方思いっきり間違ってました
ありがとうございます
助かりました

488:デフォルトの名無しさん
06/12/27 17:11:03
てか、パターンを含む行を削除したいだけなら grep -v でやれば良い。


489:デフォルトの名無しさん
06/12/28 01:09:04
きっとgrepでは業(カルマ)を削除できないのだろう。

490:デフォルトの名無しさん
06/12/29 16:00:50
sedでレコードのor検索やand検索ってできますか?


491:デフォルトの名無しさん
06/12/29 16:12:11
RDBでいうレコードの概念は、区切り文字とのパターンマッチでおおよそシミュレート可能。
その上で、パターン/X/と/Y/のandは/X/{/Y/}で、orは
/X/...
/Y/...
でシミュレート可能。

492:デフォルトの名無しさん
06/12/30 12:08:44
例えばレコードの100バイト目から105バイト目を置換したいんだけど、
全角・半角が不規則に混ざっているので、
s/(.{100,100})......)/\1abcdef/
とか正規表現でやってもうまくいかないんだよね。
良い方法あるかな?
ちなみにUNIX、sedでやるつもり。

493:デフォルトの名無しさん
06/12/30 15:00:03
>>492
多バイト文字を途中でぶった切ってもいいの?

$ LC_ALL=C sed -e 's/^\(.\{99\}\)\.\{6\}/\1abcdef/'
とか。LC_ALLは状況しだいでLANGとかLC_COLLATEあたりでもOK。
あとこの正規表現はGNU sed でないと多分食ってくれない。


494:492
06/12/30 23:40:41
うちはcshなので
env LC_ALL=C sed ~
って感じですね!
ありが㌧!
後いい忘れたけど固定長ファイルで置換部分は必ず1バイト文字なのでぶった切られることはないです。


495:デフォルトの名無しさん
07/01/02 14:18:06
RDB=ラーメンデータベース

496:デフォルトの名無しさん
07/01/03 00:18:43
よく勘違いされてるんだけど、
ラーメン(Rahmen)というのはドイツ語で、
英語のframeに相当する単語なんだ。
だから「枠」とか「骨格」とか「軸組み」とかいうような
ニュアンスなんだよ、本来であれば。

497:デフォルトの名無しさん
07/01/03 09:39:49
ラーメン違い。本来も糞もない。


498:デフォルトの名無しさん
07/01/03 12:33:20
遅レス気味すまそ。
>>483
そういうの書くなら
dump -0f path/to/hda1.dump /dev/hda1 || exit 1
と || exit の方が、見やすくって良くないか。


499:デフォルトの名無しさん
07/01/05 01:26:49
質問があります。
Vine4.0を使用していまして

#!/bin/sh
declare -i MAX
MAX=10
while[ $MAX -lt $1 ]
do
echo $MAX
MAX=$MAX+1
done

というスクリプトを書いたのですがいざ実行してみると下記のようなエラー?がでてしまします。
command not foundということは何かがたりないのでしょうか?
アドバイスお願いします。

. a05.sh 12
bash: while[ 10 -lt 12 ]: command not found
bash: a05.sh: line 5: syntax error near unexpected token `do'
bash: a05.sh: line 5: `do'


500:デフォルトの名無しさん
07/01/05 02:35:36
whileの後ろに空白がないんじゃないか?>499

501:デフォルトの名無しさん
07/01/05 03:45:07
>>499
空白入りの引数を渡すとエラーを吐くから
$1 の所をクォートしておくと吉

502:499
07/01/06 02:58:14
>>500,501
whileの後ろに空白をいれたら無事に動作しました。
クォートとは''の事ですよね?参考になりました。
ありがとうございました。

新しい質問なんですけど

#!/bin/bash
while [ -f .count.lock ]; do
sleep 0.1
done
touch .count.lock
declare -i INTEG
INTEG='cat access_count.txt'
INTEG=$INTEG+1
echo $INTEG >| access_count.txt
echo "$INTEG"
rm -f .count.lock

を動作させると

bash: cat access_count.txt: syntax error in expression
(error token is "access_count.txt")
15 ←access_count.txtの内容を書き換えてもどんどんインデントされていきます。
の様に吐き出されてしまいます。
INTEG='cat access_count.txt'の部分が悪い様なのですがINTEGにcatを使って
ファイルの内容を代入することはできないのでしょうか?
access_count.txtの中身は 0 とだけ入っています。

よろしくお願いします。

503:デフォルトの名無しさん
07/01/06 03:33:25
コーテーションの向きを確認すべきかと

504:492
07/01/06 11:02:47
すいません、また来ました…

\{99\}使えんかったorz
.を99個書くしかないんかね~


505:デフォルトの名無しさん
07/01/06 21:31:43
>>504
sedを使わない方法
(dd bs=1 count=99;dd bs=6 count=1 of=/dev/null; echo -n abcdef; cat)

506:デフォルトの名無しさん
07/01/07 02:48:47
>>504
使ってる sed がGNU sedでないとかない?

echo abcdefghijklmn | sed -e 's/^\(.\{5\}\).../\1XXX/'

abcdeXXXijklmn
になるよ(Fedora Core5)

あと、493は後ろのドットに余計な\がついてるからそれはとっておくんなまし。


507:デフォルトの名無しさん
07/01/10 15:39:41
>>504
awk '{print substr(1, 99, $0) "12345" substr($0, 105)}' hoge.txt


508:デフォルトの名無しさん
07/01/10 23:38:53
>>504
printf "%099d\n" |tr 0 \.

509:504
07/01/16 00:52:23
やっぱawkじゃね~
サンクスコ


510:デフォルトの名無しさん
07/01/16 17:35:01
ちょいとawkスクリプトでお尋ねしたいんだが、
2つ以上のファイルから文字列の切り出しってできますかね?
色々試してみたのだけれど全然できなかったんで

hoge1.dat の$1,$3 と hoge2.dat の$5,$2 を 1行でhogehoge.datに出力という形

GMTっていうマイナーなツールで絵を描いてるんだけど、GMT内の計算スクリプトで出たデータのお尻に
別のデータを加えてそのまま描けないかなぁって試行錯誤してるんですが。

511:デフォルトの名無しさん
07/01/16 17:44:04
できます。しかし、残念ながらスレ違いにつきawkスクリプトは割愛。

512:デフォルトの名無しさん
07/01/16 18:08:10
>>511
スクリプトが複数行に渡らずにできるならなんとかサンプル探してやってみる

513:デフォルトの名無しさん
07/01/16 18:33:03
>>512
なぜにワンライナーにこだわるん?

514:512
07/01/16 19:44:23
スレ違いだけど一応
>>513
簡単に言えば頭の悪い素人だから。
マニュアルになりそうなもんは見たりするんだけど、大体そういうのって一行で処理終わらせるのが多くて。
専門用語がてんでダメだし、

何故処理できるのか?を理解してなくて、「こうやればこういうのができる」でしか認識してなく
自分自身、誰かが書いたソースの簡単な処理や変数を弄るだけしかできないって分かってる。
複数行に渡ると検索でHITしにくいし、「できる」て事さえ分かれば後は調べたらなんとかなるかな、と

スレ読んでたら組み合わせ次第でなんとかできそうだわ

515:デフォルトの名無しさん
07/01/16 19:55:53
カラム数が固定ならpasteとawkをパイプで繋ぐのが楽かな。

516:デフォルトの名無しさん
07/01/17 00:33:49
一応、書いてみたんだがな…、1行ぢゃないから駄目か

#!/usr/bin/gawk -f
BEGIN{
    while( (getline line1 < "hoge1.dat" ) > 0 && \
           (getline line2 < "hoge2.dat" ) > 0 ){
        split(line1,col1)
        split(line2,col2)
        print col1[1],col1[3],col2[5],col2[2]
    }
}

517:デフォルトの名無しさん
07/01/17 01:45:36
>>510
bash 限定かも

$ paste <( awk '{print $1,$3}' hoge1.dat ) <( awk '{print $5,$2}' hoge2.dat )


518:デフォルトの名無しさん
07/01/24 10:59:01
対話式のスクリプトを作っており、read で入力されたIPアドレスを
正規表現でIPアドレス規則が正しいかを判断さえたいのですが、
どうしたらいいですかね。

519:デフォルトの名無しさん
07/01/24 11:51:57
関数やサブシェルについての質問です。
まずサブルーチンの方ですが、以下のようにしました。
「Name_sub.sh」
#!/bin/sh

echo "What is your name and age ?"
read your_name your_age

CHECK_NAME () {
echo $1 $2
}

CHECK_NAME $your_name $your_age

これ単体で実行すると、正常に$your_name $your_ageが戻ってくることを確認しました。
これを他のmainスクリプトから呼び出して使おうとしました。

「Name_main.sh」
#!/bin/sh

var=(`./Name_sub.sh`)
echo '${var[@]} = ' ${var[@]}

ここで、Name_sub.shの戻り値を配列varに入れようとすると、
Name_sub.shの対話部分が表示されませんでした。
対話部分をプロンプトに表示して、関数のCHECK_NAMEの戻り値のみ
配列varに代入するにはどうすればよいのでしょうか?

520:デフォルトの名無しさん
07/01/24 12:29:27
とりあえずtmp.txtファイルに値を保存して、その値をmainで読み込むことにしました。

521:デフォルトの名無しさん
07/01/24 13:17:20
source を使うケースじゃないのかな。


522:デフォルトの名無しさん
07/01/25 15:51:10
>>518
sh や bash の場合 (ksh もこうだったかも知れない)
IFS=.
とすると set で指定した変数は '.' で区切られて $n に入るようになる。
たとえば ipaddr に 172.24.1.2 と入っているときに

IFS=.
set $ipaddr

とやると $1 に 172, $2 に 24, $3 に 1, $4 に 2 が入り、更に $# が
4になる(4つに分割されたということ)。

なのでまずはこの直後に
if [ $# -ne 4 ]; then echo Error ; exit 1 ; fi
のようなことをして4つでなければエラー扱いにしてしまえば良いと思う。

更に $1 から $4 に入っているので for でループさせることもできる。
なのでここで数値が 0 ~ 255 になっていなければエラーにすれば良い。

# n に 172, 24, 1, 2 の順で代入されてループする。
for n
do
 if [ 0 -gt "$n" -o 255 -lt "$n" ]; then echo Error ; exit 1 ; fi
done

テストで数を先に書いている理由は n には何が入ってくるか分からないから。
('-' で始まるオプションのようなものを入れられてしまうとテストコマンドの
動作が変わってしまうかも知れないため)


523:デフォルトの名無しさん
07/01/25 16:05:50
どうしても正規表現を使わないと我慢ならんという場合はこんな感じかな。
なんか無理があるが。

if perl -e '$_='\'"$ipaddr"\'';if(/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/){if($1>=0&&$1<=255&&$2>=0&&$2<=255&&$3>=0&&$3<=255&&$4>=0&&$4<=255){exit 0}}exit 1;'
then
 echo ok
else
 echo ng
fi


524:デフォルトの名無しさん
07/01/25 17:38:15
正規表現の時は >=0 の判定はいらんと思う。
どちらにしろ面倒だけど。

525:デフォルトの名無しさん
07/01/25 22:03:14
あ、そうだね。いらないね。

526:デフォルトの名無しさん
07/02/07 22:53:33
[質問]
シェルスクリプト初心者です.

power 12.34 dBm
power 13.45 dBm
power 14.56 dBm

ある,power(電力) の変化を確認するのに

while true; do sleep 1 echo `command`; done

で 表示しているのですが

改行して新たな出力を出さないで,
前の出力を消し power 値 dBm の値のところだけが変わる

ようにしたいのですが,いい方法ありませんか?

clear は使わずにお願いします.

分かりにくい説明ですみませんがどうかよろしくお願いします.

527:デフォルトの名無しさん
07/02/07 23:09:16
>>526
キャリッジリターンを使うと吉。
command が複数行出力しているとこれでは上手くいかないけど。

while true; do sleep 1; echo -en "`command`\r" ; done

詳細は man printf かな?

528:デフォルトの名無しさん
07/02/11 11:20:30
シェルスクリプトって例外処理できます?
例えば一つ上の行でエラーが発生したときはそのシェルスクリプトの処理を終了するとか。

529:デフォルトの名無しさん
07/02/11 12:14:42
>>528
プロセスの終了ステータスを見て条件分岐することはできる。

530:デフォルトの名無しさん
07/02/11 13:13:06
>>528
普通は>>529の終了ステータスを使う。エラー時に終了するだけならこれで十分。
シグナルが飛ぶならtrapでシグナルハンドラを書くのもあり。

try/catch/throwに直接対応するものは、Bourne shell、csh、bashにはない。


531:デフォルトの名無しさん
07/02/11 20:02:45
set -eしとけば、(検査されていない)終了ステータスが0以外の場合は
スクリプトが終了する。終了処理はtrap "..." 0

532:デフォルトの名無しさん
07/02/12 08:56:55
どもですm(_ _)m

533:デフォルトの名無しさん
07/04/04 19:47:34
リダイレクトのことで質問なんですが
echo hoge > test
ls -l < test
とやるとlsは標準入力(つまりtest)の内容を読み込むのなら
普通にls -lとした場合はキーボードからの入力を読み込もうとすると思うんですが、
そうはならないのは何故なんでしょうか?

534:デフォルトの名無しさん
07/04/04 21:19:42
>>533
入力がリダイレクトされても、lsは何も読むわけではない。
つまり、ls -l < test と書いても ls -l と書いても同じ事。

535:デフォルトの名無しさん
07/04/04 21:42:01
たしかにls -l < testとやっても変わらないみたいです。
今、入門UNIXシェルプログラミングという本で勉強しているのですが、
その本の89ページには
echo abc nnn > xyz
ls -l < xyz
とするとls -l abc nnnとしたときと同じ結果になる。書いてあったのですが、
この本が書かれた時と今ではlsの動作が異なるということなんでしょうか?


536:デフォルトの名無しさん
07/04/04 21:55:46
いつの時代か知らんが、lsが標準入力から引数を貰うような作りになってる
という話は聞いたことがないな。

ls -l `cat xyz`とか xargs ls -l < xyz ならありえる。

xargsは、はしょって言うと、標準入力から受け取ったものを、自分に与えられ
た引数につなげたて、その全体を実行するコマンド。、


537:デフォルトの名無しさん
07/04/04 22:01:14
うーんサンプルコードを見ても特にxargsを使っているわけではないようです。
本のタイトル名で検索したらサポートページがあったので、後で
この件に関してメールを送ってみようかと思います。ありがとうございました。

538:デフォルトの名無しさん
07/04/04 22:12:21
>>537
物はこれか?
URLリンク(shop.sbcr.jp)
ここには載っていないようだな。
URLリンク(shop.sbcr.jp)

539:デフォルトの名無しさん
07/04/04 22:17:38
この本か。
会社に置きっぱなしだから明日確認してみる。

540:デフォルトの名無しさん
07/04/04 22:22:57
著者名のつづりのミスもみつけられんとこ信用するな

541:デフォルトの名無しさん
07/04/05 01:49:29
>>535
ls -l `< xyz` なら期待通りの結果になるよ。

bash 依存の記法だったと記憶しているけど。


542:539
07/04/05 10:21:44
入門UNIXシェルプログラミング(ソフトバンク株式会社、Bruce Blinn、初版)
の87ページに確かに載っているな

----------
$ cat xyz # xyzファイルの中身を確認
abc nnn
$ ls -l < xyz # xyzファイルを「標準入力」としてリダイレクトする
----------

ls (GNU coreutils) 5.97では動きませんでしたがええ。

543:デフォルトの名無しさん
07/04/05 12:53:34
リダイレクトのことで質問なんですが
中身がスペース一つのファイルsampleを
cat test | sed -e 's/ / /' > test2
とするとtest2にスペース10個が出力されるので
cat test | sed -e 's/ / /' > test
とするとtestの中にはスペースが10個入っていると思うんですが、
中身を見てみると空になってしまいます。
一つのコマンドの中で同じファイルに対して入出力のリダイレクトを行うと
空になってしまうのはわかるんですが、今回の場合はどうしてうまくいかないのでしょうか?

544:543
07/04/05 12:55:16
すいません、上の例でのtestはsampleの間違いですorz

545:543
07/04/05 12:57:52
何度もすいませんorz
どうやら連続した半角スペースは一つにまとめられてしまうみたいで、
上の例のs/ / /はs/スペース1個/スペース10個/ってことです。

546:デフォルトの名無しさん
07/04/05 13:50:57
>>545
一部のOSのようにパイプラインを非同期にしか実装してない環境ならいざ知らず、
まともなOSではパイプラインの前後のプロセスは同時に実行されるので、
パイプラインに接続する一つのファイルを読み書きしようとすれば当然そうなる。


547:デフォルトの名無しさん
07/04/05 14:50:40
つまり上の例だと
・最初に書き込み用にファイルを開く、当然ファイルの中身は空になる。
・catは空のファイルの中身を出力する
・空がsedに渡されるので当然空をファイルに書き込む
という順番で処理が行われるんでしょうか?

548:デフォルトの名無しさん
07/04/05 15:14:56
ちょっと違うな。
cat test | sed -e 's/ / /' > test
の場合、
シェルがtestを"w"で開いてからcatとsedを起動する筈だから、
catが起動された時点でtestは既に空の筈だ。
空の入力に対してcatは何も出力しないし、sedも同じように何も出力しない。
従って、空になるのはcatやsedが起動される前と言うことだ。

ちなみに、どうしても同じファイルに読み書きしたいなら
sed -e 's/ / /' < test | tee test
のようにしてしまえばいい。
これなら、シェルがtestを開いてからteeがtestを開こうとするので
(unixの開きっ放しのファイルは削除できたように見えてもそれは見掛けだけ仕様に基づき)
無事に処理される筈だ。

549:デフォルトの名無しさん
07/04/05 15:27:54
まず最優先でリダイレクトのための処理が行われて、それから
コマンドの処理が行われるんですね。わかりました。ありがとうございます。

550:デフォルトの名無しさん
07/04/05 17:02:21
なんか今一判っていない悪寒。

551:デフォルトの名無しさん
07/04/06 02:40:06
>>549
GNU sed 使ってるなら -i オプションつけとけ


552:デフォルトの名無しさん
07/04/07 19:35:57
シェルを初めて組みます。
Cシェルで、自分のグローバルIPを取得して、そのIPをメールで送信するようなプログラムを
組みたいと思っております。

で、グローバルIPの取得の仕方が分からないのですが、
どのようにかけばよいのでしょうか?

OSはRedHat10です。

553:デフォルトの名無しさん
07/04/07 20:07:14
シェルスクリプトのことをシェルゆーな。
Cシェルで書くな。

プライベートアドレス
10.x.x.x
172. {16-32} .x.x
192.168.x.x

割り当てられているIPアドレスは

LANG=C
/sbin/ifconfig |sed -n 's/inet addr:¥([^ ][^ ]*¥) .*/¥1/p'
で取れるから、あとはawkでも使って該当しないものを除外すれば
いいんじゃないか?

と書いてから気づいたが、家のダイアルアップルータに繋がっている
LinuxからグローバルIPアドレスを取ろうとするなら、Linuxにはプライ
ベートIPアドレスしか割り当てられてない。取るべきはルータに付いてる
グローバルIPアドレスになるから別の方法が必要だぞ。


554:デフォルトの名無しさん
07/04/07 22:25:30
>>553
すいません、ありがとうございます。
何もわかってないんで^^;
ずばり、そのとおりで、取得したいのはルータについてるグローバルIPです。。

555:デフォルトの名無しさん
07/04/07 22:42:16
>>554
ダイアルアップルータやモデムにはtelnetサーバが内蔵されていることがある。
叩くコマンドが分かれば、expectを使って取得できるかもしれない。

httpサーバを内蔵していることもあるが、こっちはずばりIPアドレスを確認する
ページを持ってるかもね。


556:デフォルトの名無しさん
07/04/07 23:00:35
>>554
誰もおまいのルータの仕様を知っているやつはいないからな・・・

うちのFLASHWAVE 2040 M1ならURLリンク(ID:PASS@)ルータのIP/doKeeping.htmlを
wgetで取得してvar sIpAddress="*.*.*.*";の場所を取得すればわかる。

557:デフォルトの名無しさん
07/04/08 00:37:43
何も考えずにメール出せば、大抵はReceived:にIPアドレスが自動的に書かれる。
書かれないならば、書いてくれるメールサーバを提供しているISPに乗り換える。


558:537
07/04/11 10:24:46
ソフトバンクさんからメールの返事が届きました。
正誤表も更新したみたいです。

559:デフォルトの名無しさん
07/04/11 12:36:15
alias定義で改行の前に入れる\にはどのような作用があるのでしょうか?
csh でいろいろと試してみたところ、下のようにwhile文などが使えるようになりますが、
一方で、引数を扱ったりwhile文のネストをしたりすると正常に動作しなくなってしまいます。

alias loop '\
set count = 1\
while ( $count <= 5 )\
echo hoge\
@ count++\
end\
'


560:デフォルトの名無しさん
07/04/11 12:45:23
未だだね。

561:デフォルトの名無しさん
07/04/11 12:46:29
あーいけね、>560は>558の話ね。

>>559
行末のバックスラッシュは改行文字をエスケープする。

562:デフォルトの名無しさん
07/04/11 13:19:26
>>561
「改行文字をエスケープする」の意味を具体的に教えて欲しいのです。
>>559のコードで\+改行を空白に置き換えると動かなくなります。
妙な副作用がなぜ出るのかも謎です。

563:デフォルトの名無しさん
07/04/11 22:34:26
>>552
診断君とかにアクセスしてIP抜いてもらって
それをパースするのはだめなんか?

564:デフォルトの名無しさん
07/04/11 22:36:33
ワンクリ詐欺サイトにアクセスすればIPアドレス教えてくれそうだな。



565:デフォルトの名無しさん
07/04/11 23:29:53
>>563
頻度にもよるけどあんま他人様のとこに頼るのもいかんと思う。
自前で取れるんならそうした方が優しいし確実。一応
URLリンク(info.ddo.jp)
とか使うとワンライナーでやれるけど。

566:デフォルトの名無しさん
07/04/12 12:59:30
>>562
シェルスクリプトにおける改行の意味を調べてみると良いよ。

alias loop 'set count = 1;while ( $count <= 5 );echo hoge;@ count++;end;'


567:デフォルトの名無しさん
07/04/13 05:02:58
>>566
while?

568:デフォルトの名無しさん
07/04/13 21:22:17
質問させてください。
以下のように、test-serverへ接続し、
date;hostname;whoamiを実行するスクリプトを書いてます。
date;hostname;whoamiの結果をリダイレクトし、
スクリプト本体があるサーバに保存したいのですが、
その場合、どう記述すれば良いでしょうか。

#/bin/bash
HOST=test-server
UNAME=root
PASSWD=***

expect -c "
set timeout 20
spawn telnet $HOST
expect login:\ ; send \"$UNAME\r\"
expect sword:\ ; send \"$PASSWD\r\"
expect \"$\" ; send \"ls\r\"
expect \"$\" ; send \"date;hostname;whoami\r\"
expect \"$\" ; send \"exit\r\"

569:デフォルトの名無しさん
07/04/16 11:40:37
そのスクリプトの出力をリダイレクトすればいいのではなくて?

570:568
07/04/17 21:48:16
その方法が分からないのです。expect内部でリダイレクトすると
接続先にファイルが出来てしまうんじゃ無いでしょうか

571:デフォルトの名無しさん
07/04/17 23:45:47
>>570
にほんごよめますか?

572:デフォルトの名無しさん
07/04/18 00:08:52
ラッパー側のスクリプトの出力をリダイレクトしようとしても、
expectの中で起動したプロセスの出力はexpectが全部食っちゃうん
じゃないの?


573:デフォルトの名無しさん
07/04/21 18:39:33
あるプログラムをバックグラウンド実行して、
そのプログラムが一定時間後に終了していなかったら終了させる、みたいなことはできますか?

こんなイメージです。

#!/bin/sh

/bin/hoge & # 数十分かかる。途中で固まるかもしれない。

sleep 3600 # 念のため一時間待ってみる

[ hoge が終了していなかったら hogeをkillする。終了していたら無視 ]

exit

574:デフォルトの名無しさん
07/04/21 18:41:17
あげ

575:デフォルトの名無しさん
07/04/21 18:50:35
>>573
こういう事?

#!/bin/sh -x
DURATION=3600

hoge &
PID=$!

echo ${PID}
sleep ${DURATION}

kill ${PID}
exit

576:デフォルトの名無しさん
07/04/21 18:51:49
>>573
pid控えておいて、atコマンドで終了スクリプトを仕込むとか。


577:デフォルトの名無しさん
07/04/21 19:30:31
一時間の間にpidが再利用されない保証があるなら。

578:デフォルトの名無しさん
07/04/21 19:44:35
kill する前に親プロセスの PID を確認すれば。

579:デフォルトの名無しさん
07/04/21 20:11:19
データを 1バイトだけ 読み込むコマンドってなんだっけ?

580:デフォルトの名無しさん
07/04/21 22:21:18
>>579
head -c 1 ?

581:573
07/04/21 22:39:07
>>575
こういうことです!ありがとうございます。

>>576
atd動いていないッス。。。

>>577
>>578
pidが再利用されない補償はもちろん無いです。
ググっていますがPPIDを確認をするコマンドが見あたらないorz
$!や$$でPIDが取れるようなのでpsコマンドの結果から何とかしてみます。


582:デフォルトの名無しさん
07/04/22 17:22:43
waitか何かで子プロセスの終了待てなかったっけ?

583:デフォルトの名無しさん
07/04/22 18:14:45
>>573

pid=$!
count=0
while [ $count -lt 60 ]; do
sleep 60
kill -0 $pid || break
count=`expr $count + 1`
done
[ $count -lt 60 ] || kill $pid

584:デフォルトの名無しさん
07/04/22 18:15:16
待つよ。

585:デフォルトの名無しさん
07/04/22 18:16:01
むぅ、30秒差で…

>>582
waitで待つよ。

586:デフォルトの名無しさん
07/04/23 11:19:01
>>583
kill -0 $pid
ってどういう意味?

587:デフォルトの名無しさん
07/04/23 20:32:55
kill -0 $pid 2>/dev/null || break
の方がベターだな。

>>586
man 2 kill
The kill() system call sends the signal given by sig to pid, a process or
a group of processes. The sig argument may be one of the signals speci-
fied in sigaction(2) or it may be 0, in which case error checking is per-
formed but no signal is actually sent. This can be used to check the
validity of pid.

プロセスが存在してそのプロセスにシグナルを送る権限があれば正常終了。
それ以外はエラー。つまり、プロセスの生存確認に使用できる。


次ページ
最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch