シェルスクリプト相談 ..
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 〜
って感じですね!
ありがd!
後いい忘れたけど固定長ファイルで置換部分は必ず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.
プロセスが存在してそのプロセスにシグナルを送る権限があれば正常終了。
それ以外はエラー。つまり、プロセスの生存確認に使用できる。
588:デフォルトの名無しさん
07/04/23 20:58:56
>>587
なるほど。
日本語man読んでも意味がわかんなかったんだ
ありがとう
589:デフォルトの名無しさん
07/04/27 13:30:22
シェルブリッド
590:デフォルトの名無しさん
07/04/28 16:07:15
♪ア・ソ〜レ
ア・チョン! ア・チョン!
ア・チョン! チョン! チョン! バカ!
591:デフォルトの名無しさん
07/05/04 00:27:06
a.txt
2
4
23
87
483
3
b.txt
89
34
111
8
3
97
とある場合
program a.txt b.txt
と打てば
以下のようにに表示されるシェルスクリプトってできませぬか?
2+89=91
4+34=38
23+111=134
87+8=95
483+3=486
3+97=100
次ページ最新レス表示スレッドの検索類似スレ一覧話題のニュースおまかせリスト▼オプションを表示暇つぶし2ch
5114日前に更新/248 KB
担当:undef