トップページ⇒linux
988コメント336KB

シェルスクリプト総合@LINUX Part3

■ このスレッドは過去ログ倉庫に格納されています
0001login:Penguin2007/07/10(火) 23:17:13ID:qGthZdME
UNIX板のスレを見ている方も多数おられるかと思いますが、
まあそれはそれとして、BASHウゼーとか言われる心配なく
平和にLINUX的スクリプト談義しましょうよ。

初めての自作スクリプト、自信ないから見てください。な初心者から
トリッキーな技を駆使した作品を披露したい、蘊蓄を語りたい上級者まで
いろいろな人に参加して頂けると嬉しいです。

perlやらPythonやらの話が混ざっても良いんでない?

【sed】シェルスクリプト総合@LINUX Part2【awk】
http://pc11.2ch.net/test/read.cgi/linux/1154578200/
http://pc8.2ch.net/test/read.cgi/linux/1121994321/

>>2-5あたりに色々と。
0165login:Penguin2007/09/17(月) 12:56:16ID:RA5G8Fdp
while ! convmv -f sjis -t utf-8 -r /data --notest ; do
convmv -f euc-jp -t utf-8 -r /data --notest
done
なんか、どうよ?
文字コード判定がいまいちなのか誤認してくれたりするので --notest とって、ざっと眺めてからやる事を推奨。
0166login:Penguin2007/09/17(月) 13:00:08ID:85s13mgP
--notest 外して試してみればーじゃん。
0167login:Penguin2007/09/17(月) 13:21:00ID:hplwR1nR
echo $RANDOM

で結果に乱数を返したいんですけど、
0〜9までの一桁の結果のみ返したい場合の指定方法とかってありますか?
0168login:Penguin2007/09/17(月) 13:53:15ID:MlIRuyKv
$RANDOM % 10
0169login:Penguin2007/09/17(月) 15:09:07ID:nqz563FT
>>164
nkf はファイル"名"ではなくて、ファイルの"中身"についての文字コードを
調べるんですよね?テキストファイルに対して実行するとShift-JISと言う出力が得られ、
.exeファイル等に実行すると Binary と表示されました。
なので、これは全く別物です。

>>165
おお・・・
それはつまり
convmv -f sjis -t utf-8 -r /data --notest
で、元ファイルがsjisじゃなかったときは元ファイルがeuc-jpとして処理を繰り返すんですね。
しかしその場合、仮に1つでも元ファイルがsjisだった場合は?と言うか・・・

それ実行してみたのですが、無限ループに陥りました。何度も同じファイルを判定して
これsjisじゃないよ〜って帰ってきます。

よくよく考えると -r /data で既に再帰的に繰り返す処理なのに、それをさらにwhileでループさせて
いるんですよね。二重ループ状態ですか。
while ! convmv -f sjis -t utf-8 -r /data --notest ; do
これで、とりあえず convmv -f sjis -t utf-8 -r /data --notest が実行される
→実行された時に1つでも違うファイルが存在していてエラー
→convmv -f euc-jp -t utf-8 -r /data --notest が実行される
→実行された時に1つでも違うファイルが存在していてエラー
またconvmv -f sjis -t utf-8 -r /data --notest が、最初にエラーで止まったファイルも含んで
最初から実行される>当然また同じファイルでエラーを起こす>convmv -f euc-jp -t utf-8 -r /data --notest が
また実行されてまたこれも最初から処理してしまう>これを永遠に繰り返して無限ループに陥る。
ダメみたいですOTL

>>166
--notestはずして試してみてますが、エラーで弾かれます。
0170login:Penguin2007/09/17(月) 15:30:26ID:kUn2DAgf
>>169
いや、ファイル名のコードをnkfで調べりゃいいじゃん、てことだったんだけど。
0171login:Penguin2007/09/17(月) 15:35:55ID:kUn2DAgf
念のため。
for T in `ls ~`
do
C=`echo "$T" | nkf -g`
echo $T,$C
done
ファイル名の文字コードを調べてると思うんだが。
0172login:Penguin2007/09/17(月) 16:38:42ID:nqz563FT
>>170-171
違うと思うなぁ・・・。

>>171のスクリプト実行してみたけど
これは ls ~ で表示されるファイル名リスト全体、、、そうだなぁ、、例えば
a.txt
b.mp3
c.tar
d.gz
e.tar.gz

とか日本語も含むファイル名全てが列挙されると思うけど、それらのファイル名リスト
全体を1つのテキストファイルとみなして、テキストファイルの中身(つまりファイル名が列挙されてる)
に対して文字コード変換をかけた結果を echo で出力しているんじゃないですか?
だからnkf は ファイル"名"の文字コードを調べるんじゃなくて、あくまでもテキストファイルの中身
の文字コードを調べるんだと思いますが。それこそqkcみたいな動作?
convmvは全くそれとは性格が異なる物だと思いますが、、非常にこの辺ややこしい・・・。
0173login:Penguin2007/09/17(月) 16:45:55ID:8vN1DPCo
なんでこんなに全然わかってないのに自信満々なのだろうか
0174login:Penguin2007/09/17(月) 16:47:06ID:rlyHM/pf
>>161
>>164 の意見を採用して書いてみた。
for を while に変えたのは俺の趣味。

find /data | while read TARG ; do
 File=$( nkf -g <<< "$TARG" )
 case "$File" in
   Shift_JIS*) Code=sjis ;;
   EUC-JP*) Code=euc-jp ;;
UTF-8*) continue ;;
 esac
 echo "$File: Convert to $Code" ## お好みで
 convmv -f "$Code" -t utf-8 "$TARG" --notest
done

ファイル名程度の短い文字列だと nkf の文字コード判定の
精度はあまりよくないが、やらないよりはマシだろう。
0175login:Penguin2007/09/17(月) 16:52:30ID:HxbR0j5A
文字コードが違うファイル名が混在しているディレクトリって。
どうしてそうなったかが気になる
0176login:Penguin2007/09/17(月) 16:55:54ID:4XOwAbVo
ローカルで作ってSambaで作ってWebDAVあたりで作ってとやってしまうと
起きるな?>混在。

後はデータ中の文字列を元にファイルを作ったりすると、うっかり
混在状態になったり。
0177login:Penguin2007/09/17(月) 17:22:02ID:kUn2DAgf
>>172
>>173と同意なんだが、想像の斜め上な方向に理解してるのね。と理解。
なして>>171を実行してみた上で>>172になるのかわからん。。。
つまり、>>172としては、「a.txt あ.txt い.txt」の3つのファイルがあると、
 a.txt, ASCII
 あ.txt,UTF-8(とか)
 い.txt,EUC-JP(とか)
てならず、
 a.txt,BINARY
 あ.txt,BINARY
 い.txt,BINARY
となった、てこと?

>>174
半角カナ使ってなけりゃ、それなりの精度なんじゃねぇかと思うんだけど、どうだろ。
0178login:Penguin2007/09/17(月) 17:29:26ID:kUn2DAgf
>半角カナ使ってなけりゃ、〜
↑勘違い。すま。
0179login:Penguin2007/09/17(月) 19:31:50ID:nqz563FT
>>173
すみませんOTL。

>>174
そのスクリプト動かしてみたのたですが、 echo ${File}を加えて確認した所
ほとんどのファイルが ASCII と出力されていて、少しだけ Shift-JISという出力が得られました。
って事は?Shift-JISとASCIIが混在しているという事でしょうか?
と言うかそもそもASCIIっていったいどういう・・?
euc-jp sjis utf-8 の3種類しか基本的には知らなくていいと思っていたのですが、4つ目の文字コード
も混在している(というよりeuc-jpのファイルは存在しなくてsjisとASCIIの2つが混在?)と言う事でしょうか。
と言うか convmv --list してみたら asciiってあるし・・・・。

>>176
そうそう、さらにFTPも混ざったりssh + rsyncとかでファイル持ってきたりすると
もう今ぐちゃぐちゃになってて、UTF-8に統一したいんですよ。。。
>>177
.txtの拡張子のファイルは BINARYはでません。

ん?って事は nkf -g ではファイル"名"の文字コードを判別しているって事ですか?
で、その出力がASCIIとShift-JIS、その他としてはBINARYの3種類の状態(だと思う)の場合は
convmv -f ascii -t utf-8
convmv -f sjis -t utf-8
でそれぞれ変換かければいいのかな・・・。なんか難しすぎて頭痛くなってきたOTL。
でもなんか全面的に私が間違っていた感じがするので、その点については皆様方には
大変ご迷惑をお掛けしておりまして申し訳ありません。
0180login:Penguin2007/09/17(月) 20:51:38ID:kUn2DAgf
>>179
なんていうか、なぁ。

ASCIIってのは日本語使ってなけりゃASCIIだわな。ちと語弊あるけど。「a.txt」とか。
で、オレの>>177で示したのは、>>174をオレ解釈したところ、
「a.txt」と「(UTF-8な)あ.txt」と「(EUC-JPな)い.txt」が混在してると、いっしょくたになったのが
コード判別にかかって、結局コード判別できなくって「BINARY」って判別されるってことか? と。
オレの説明わかり難かったとは思うけどな。

でもってnkf -gだが、たんに「入力された」のの文字コード体系を調べるだけであって、それが
「ファイルの中身」なのか「ファイル名」なのかは、どっちを指定、てか、nkfに入力したか、て
違いだけ。わかる?

ついでに日本語のファイル名がShift-JISだけなら、SJIS→UTF8に変換指定するだけでokやな。

そんなわけで、まちっと勉強しれ。
0181login:Penguin2007/09/17(月) 21:22:34ID:rlyHM/pf
>>179
ああ、そういや ASCII を忘れてた。w
解説は >>180 を見てもらうとして、
それを踏まえて >>174 を改良すると、こんな感じかな。
後は自分で調べてみな。

find /data | while read TARG ; do
 File=$( nkf -g <<< "$TARG" )
 case "$File" in
   Shift_JIS*) Code='sjis' ;;
   EUC-JP*) Code='euc-jp' ;;
   ISO-2022-JP*) Code='iso-2022-jp' ;;
   ASCII*|UTF-8*) echo "$TARG: $File"; continue ;;
   *) echo "$TARG: $File: Not supported format."; continue ;;  
 esac
 echo "$File: Convert from $Code to UTF-8." ## お好みで
 convmv -f "$Code" -t utf-8 "$TARG" --notest
done

>>180
> 「a.txt」と「(UTF-8な)あ.txt」と「(EUC-JPな)い.txt」が混在してると
判定はファイルごとに行うからこれで「BINARY」にはならないはず。

「(UTF-8)あ(EUC-JP)い.txt」とか、複数の文字コードで構成された
ファイル名だと誤判定と言うか、期待通りにはならないと思う。

こういうのもきちんと判定したいのなら ack がお勧め。
こんなファイル名に出くわす事はまずないだろうけどな。w
0182login:Penguin2007/09/17(月) 22:20:42ID:nqz563FT
>>180
なるほど、英数字だけの場合はASCIIなんですね・・。
では、 a.txt(ASCIIですよね) を convmv -f ascii -t utf-8 a.txt --notest
なんて有り得ないわけですよねぇ。
BINARYって判別されたのは 例えば vncviewer.exe とかのファイルです。バイナリファイルだし。。。
この結果を見て私は vncviewer.exe と言うファイル名自体は英数字のみなので ASCIIかと
思いますが、しかしvncviewer.exeのファイルの"中身"はBINARYなので、nkf ってのは
ファイルの中身を見てコードを判別して返してくれるんだなぁと思った次第です。
(nkf がファイル"名"を見て返してくれるのなら vncviewer.exeはBINARYではなくASCIIで
かえって来ないといけないからです。) でも nkf に対して何を入力するかによって
返してくるものは違うんですね。ファイル"名"をnkfに入力すればファイル"名"のコードが帰ってくるし
ファイルの内容を入力すればファイルの内容のコードが帰ってくると。
>>181
度々具体的なスクリプトを示して頂いて本当にありがとうございます。
しかしですね・・・よくエラーを見てみると no such file or directory が帰ってきてるんですよね・・・。
つまり find /data をした結果、文字化けしたファイル名が返ってくるわけじゃないですか。
その文字化けしたファイル名の場合、そのファイルにはアクセスする事が出来ないですよね。
文字化けしたファイルに唯一アクセスする手段があるとすれば、それは "*" を使う事ですよね。
だから for や while で1ファイルずつ処理するっていう最初のアイディア自体がそもそも不可能
だったと言う事に今更ながら気づきました。ほんと文字化け問題って大変ですね・・。
"*"を使うと言っても find /data/* だと結局1ファイルずつ文字化けしたものが帰ってくるので
ダメっぽいです。 convmv に 直接 * を渡す必要があるみたいで、そうすると混在している場合に
全く処理をしてくれなくて結局ダメと。。。参ったなぁ・・・OTL。
それと1つシェルスクリプトスレなのでお聞きしておきたいのですが
File=$( nkf -g <<< "$TARG" ) ←これなんですが、 <<< って何ですか?普通 < か << ですよね。
<<<は初めて
01831652007/09/17(月) 22:30:38ID:RA5G8Fdp
>>169
エラーの起こる直前までは変換してくれるのかと思ってた。
いらぬ時間をとらせてすまねぇ。
んで(w)、また懲りずに考えてみたんだが、nkf使うんだったら
find work/ -type f -exec sh -c 'FN="`dirname \"{}\"`"/"`basename \"{}\" | nkf -w`"; [ -f "$FN" ] || mv -v "`echo \"{}\"`" "$FN"' \;
とかいかが?

ディレクトリ含まれてないんだけど、含むと末端からやらないといけないからシェルスクリプトでやるのは面倒くさそうだなァ、と思って逃げたw
0184login:Penguin2007/09/17(月) 23:04:07ID:nqz563FT
>>183
うぐぅ・・・・

そのfind 以下のスクリプト難しすぎて私には何をどうしているのかさっぱり分かりませんです。。
awkとか正規表現とかそこら辺全然知らないので、なんかそれっぽいコードに見えて読めないOTL。

ディレクトリを含まないって言うのも問題ですねぇ・・・。

例えばですが hoge.txt と piyo/ っていうディレクトリが存在していて、それぞれのファイル名
もしくはディレクトリ名の文字コードを知りたい場合はnkfではどのようにコマンド入力したらいいんですか?

ls -d piyo/ | nkf -g
nkf -g < hoge.txt
nkf -g | `ls -d piyo/`
nkf -g <<< hoge.txt
等など色々試してみましたが、文字コードが見えませんでした。

# convmv ももう少し気を利かせて --force オプションなんて作ってくれて処理できないファイルは
スキップして処理可能なファイルだけ全部処理するみたいな機能盛り込んでくれてれば助かったんだけどなぁ・・・。
0185login:Penguin2007/09/17(月) 23:10:07ID:kLzbccVO
無理してシェルで書くより
perl かなんかで書いちゃった方が早い気がする。
0186login:Penguin2007/09/17(月) 23:26:23ID:hplwR1nR
すいません、いろいろやってみたけど出来ないので教えてください。

aaaa,bbbb,cccc,"hoge,hoge",ddd,eee,ffff

みたいなCSVが有ります。
※カンマがある列は必ず「""」で括られています。

# cut -d, -f 4

とかでカンマが含まれる行を出力しようとすると 結果に「"hoge」とのみ出力されてしまいます。
本当は「"hoge,hoge"」が出力されてほしいのです。
「"hoge,hoge"」の出力結果を得るためにはどの様にすれば良いですか?


自分的には、
sedコマンドでいったんワークファイルwor.csvなどに「"hoge\,hoge"」と
エスケープシーケンスを追加してからcutコマンドを実行すればうまく行くような気がしているのですが、
sedをどのように記述して良いのかすら解りません(泣)


どなたか教えてください。。。。
0187login:Penguin2007/09/17(月) 23:42:08ID:kUn2DAgf
実は混在なんかしてない、ていうことはないのんか? もしくはかなり偏っている。
なら、ある程度手作業でその他一括、のが楽かも知れん。
0188login:Penguin2007/09/17(月) 23:45:48ID:msAJx7Dr
結局カンマ関係なしに""で括られたのが欲しいんじゃねぇのか?
0189login:Penguin2007/09/18(火) 00:04:13ID:hplwR1nR
186です。

>>187

1000行近くのCSVファイルで確実に混在しています。
例えば、↓↓↓みたいな行です。
(「US」の後ろにカンマがありますよね?)

75,0,,,-,,-,"LOG3\.0.*123456 .....5.*\(US, 21\): NOTICE:.*",,,,,,,AAAA,BBB,"TEST",WARN,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,1,,,,,,,,,,,,,,,,,,,75


この行から特定の列だけ抜き出し&抜き出しした列を引数にコマンドを実行しています。

>>188

そんなことないです。
実際には初期値の列も多いので。
0190login:Penguin2007/09/18(火) 00:16:17ID:u/C4qzX6
>>182
read に -r オプションつけたらどう?

旧) find /data | while read TARG ; do
新) find /data | while read -r TARG ; do
                 ^^^
> File=$( nkf -g <<< "$TARG" ) ←これなんですが
man bash のヒア・ストリングス (Here Strings) の項を参照。
0191login:Penguin2007/09/18(火) 00:35:05ID:u/C4qzX6
>>189
う〜ん、難しいね。
クォートされたエントリが一行に一つだけなら
↓で取り出すことはできるけど。

sed '/"/ s/.*\(".*"\).*/\1/'

俺なら一度 csv を Excel に放り込んでから
特定の列を抜き出すかな。w
0192login:Penguin2007/09/18(火) 02:15:13ID:AGCqK3mV
sed -n 's/\(\("[^"]*"\)\|\([^,]*\)\)\(,\|$\)/\n\1\n/4;s/[^\n]*\n//;P'

sedでやってみた。
0193login:Penguin2007/09/18(火) 07:39:01ID:+nqx9VGy
186です。
ありがとうございます。

191,192を実行してみたんですけど、正しく表示されませんでした(泣)
0194login:Penguin2007/09/18(火) 12:30:11ID:Gq30BMp3
>>186
センス悪いけどこんなのでよければ
#!/usr/bin/gawk -f
BEGIN{n=ARGV[1];ARGV[1]=""}
function parse(s,c,f,i,j,k){
while(1){c=substr(s,i,1);if(c=="")return;else if(c=="\"")f=(f>0)?0:1
else if(c==","&&f==0){array[k++]=substr(s,j,i-j);j=i+1}i++;}}
{parse($0);print array[n]}
01951922007/09/18(火) 18:40:20ID:AGCqK3mV
/^o^\懽懽懽懽懽懽懽
自分の環境では、186と189は上手くいってるぽいんだが。

例えば、189は192の4の所を8にすれば
"LOG3\.0.*123456 .....5.*\(US, 21\): NOTICE:.*"
って出るし、15にすれば
AAAA
と、出る。

sedのバージョンと実データがどんなのか知りたい所。
0196login:Penguin2007/09/18(火) 18:48:06ID:mMDRvNP8
>>195
スマソが懽の隣の文字のフォントが無いのだが
E3
5E
って表示になってる
0197login:Penguin2007/09/18(火) 19:09:24ID:AGCqK3mV
半角カナで書いたら化けた模様w
0198login:Penguin2007/09/18(火) 21:50:07ID:En+WDn3C
bashでスクリプトと組んでいる途中でつまづいてしまいました

~/tmp/ 以下にあるファイルすべてに対してファイル変換したいのです(例 aaaaa ⇒ aaaaa.txt)

~/tmp/aaaaa
~/tmp/bbbbb
:
~/tmp/nnnnn

=============
cd ~/tmp/
ls_result1=`ls`

for list1 in $ls_result1
do
#便宜上 (変換コマンド) (変換前) (変換後) とします
(変換コマンド) ~/tmp/$(list1) ~/tmp/tmp/$(list1).txt ←listの使い方が間違っているのだと思います
done
=============

list1 not found というエラーがたくさん出てきてしまい困っております。

~/tmp/ 以下にあるファイル名をそのまま使いたいので、どなたかご教授ください。
0199login:Penguin2007/09/18(火) 22:05:47ID:9R+Y1frn
>>198
×(変換コマンド) ~/tmp/$(list1) ~/tmp/tmp/$(list1).txt
○(変換コマンド) ~/tmp/${list1} ~/tmp/tmp/${list1}.txt
02001982007/09/18(火) 22:15:47ID:En+WDn3C
>>199

できました♪ ありがとうございました m(_ _)m
0201login:Penguin2007/09/19(水) 06:55:54ID:OLZv4Z+v
sed で/、\を多用できるようになりますたww
\tとか技も覚えますたww

みなさん�d�d!
02021982007/09/19(水) 12:51:22ID:OlaeIc6l
~/tmp/ 以下にある txtファイル だけファイルの中で置換したいのですが、
またつまづいてしまいました

# その前の処理で year month day hour という変数が与えられています
txtファイルの1行目 2007090100AB ⇒ year month day hour AB(変数の間のスペースなし、ABは固定文字列)
txtファイルの2行目 2007/09/01 ⇒ year/month/day

そこで以下のように作ったのですが、~/tmp/ に bakファイルが作られておらず、
echo $ls_result を見ると /home/myname/tmp/*.txt となっていました
想定では *.txt だったのですが・・・

=================
ls_result=`ls ~/tmp/*.txt`

for list in $ls_result
do
cp -p $list ${list}.bak

sed -e '1 s/2007090100AB/${year}${month}${day}${hour}AB/' ${list}.bak
sed -e '2 s/2007\/09\/01/${year}\/${month}\/${day}/' ${list}.bak

mv &{list}.bak $list
#rm -f ${list}.bak
=================

どなたか教えてください。よろしくお願いします。
0203login:Penguin2007/09/19(水) 15:41:53ID:Ii4uF/l/
これではまともに動いてもbakファイルはないだろ
0204login:Penguin2007/09/19(水) 18:36:32ID:42fTFu0H
>>202
これだと置換後のファイルを.bakに作って、そのあと出来た.bakをオリジナルに
重ね書き(しかもムーヴ)してるように見えるけど。

.bakとオリジナルの2個とも残したいなら、mvじゃなくてcpだろうね。

それ以前に、こういう処理だと普通は.bakに変換前のオリジナルを残すと思うが。

最初にオリジナルを.bakにcpしてあるんだから、.bakは触らずに、元のファイルに
sedかけて、最後のmvは不要では
02051982007/09/19(水) 20:34:50ID:OlaeIc6l
>>203-204
コメントありがとうございます
いただいたアドバイスどおり、bakにはさわらずにオリジナルでsedかけてみました

ところが、シェルを動かした後のファイルを見ると動かす前とまったく同じ状態でした。
タイムスタンプも動かす前と同じでした。

sedの使い方が間違っているのでしょうか。今一度教えてください。

=================
ls_result=`ls ~/tmp/*.txt`

for list in $ls_result
do
cp -p $list ${list}.bak

sed -e '1 s/2007090100AB/${year}${month}${day}${hour}AB/' ${list}
sed -e '2 s/2007\/09\/01/${year}\/${month}\/${day}/' ${list}

#rm -f ${list}.bak
=================
0206login:Penguin2007/09/19(水) 20:37:21ID:NIZBsTRK
>205
sedは-iオプションを指定しないと結果を標準出力に書き出すだけだよ。
0207login:Penguin2007/09/19(水) 21:25:46ID:gh8Zvftq
sed -i.bak -s \
-e "1s/2007090100AB/${year}${month}${day}${hour}AB/" \
-e "2s,2007/09/01,${year}/${month}/${day}," \
~/tmp/*.txt

で、よくね?
02081982007/09/19(水) 21:44:56ID:OlaeIc6l
>>203-204,206-207

207さんのとおりにしたら、想定どおりに動きました!
みなさんありがとうございました。m(_ _)m

ずっと調べてたらこんな時間に…
今からごはん作ります (^o^)/
0209login:Penguin2007/09/21(金) 15:18:02ID:5N/Tidqv
ディレクトリーA(ファイルが入ってます)を
10/1〜10/31の日付名でコピーしたいのですが
なんかいい方法無いでしょうか?

Zshだと cp -R  A 10[1-31]なんてできるのでしょうか?
0210login:Penguin2007/09/21(金) 15:27:31ID:KLJI/R6G
>>209
for i in {01..31}; do cp -pR A A10$i; done

zsh と bash で挙動違うな。
0211login:Penguin2007/09/21(金) 15:37:28ID:KLJI/R6G
>>209
< - > のことなら、ちょっと用途が違うよ。
こんなんやってみ。

% touch B2
% ls B{1..3}
% ls B<1-3>
0212login:Penguin2007/09/21(金) 15:46:39ID:5N/Tidqv
>>210 ハヤッ! ありがとうございます!

ディレクトリーAにhoge01〜100ってファイルを作ったときは
Zshでさらさら〜って逝けたのですが
現在bash環境なのでそれなりに書かないといかんなと思いつつ
3行になってしまう、漏れの脳みそでした il||li○| ̄|_

1行でやりたかったww さすがです>>210様 1行でばっちりコピーできますた
0213login:Penguin2007/09/21(金) 15:49:11ID:5N/Tidqv
>>211 すみません −じゃなくて..でした
なかなか参考になるスッドレですね
正規表現もきっちり覚えないといけませんねorz
0214login:Penguin2007/09/22(土) 04:00:27ID:DSw3XQMb
for d in {01..31} ; do printf "%02d " $d; done
021573ですが2007/09/22(土) 22:02:55ID:TBL9KN2J
>>94
おくればせながらスクリプトが動くようになりました。
御指摘のとおりスペースの数などがあっていませんでした。

ありがとうございました。
0216login:Penguin2007/09/26(水) 09:48:46ID:kfTmpMA+
時間の逆算っていい技ないですか?
やぱ現在時刻から60進法で計算したほうが早い?

現在時刻 21:24 残り時間 36分で22時  って感じ

で、やてみたい
0217login:Penguin2007/09/26(水) 09:54:08ID:lgPbyfYB
>>216
coreutilsのdateを使う。
0218login:Penguin2007/09/26(水) 13:11:02ID:kfTmpMA+
date --date xxmin とかできるのですね!!
しらなんだポカーン

>>217 ありが�dクス
0219login:Penguin2007/09/26(水) 14:13:45ID:kfTmpMA+
echo $((59 -` date  '+%M' | awk '{print $1}'` ))  $((59 -` date  '+%S' | awk '{print $1}'` ))

これでもでけた!
0220login:Penguin2007/09/27(木) 18:47:27ID:Qh1DP+hx
date,sleep, atは使い込めばラーメンタイマーも・・・・・・・いやなんでもない
0221login:Penguin2007/10/02(火) 23:24:08ID:57QYWA2W
ほしゅ
0222login:Penguin2007/10/09(火) 18:07:07ID:lJCQFIXV
モデムをオンフックにするのに
今のところcuを使って対話的にATH0を
送っているのですが、これを
シェルスクリプト内で実行して
自動化する方法はありますか?
0223login:Penguin2007/10/09(火) 23:58:35ID:rK7+VmTA
対話的といえば expect ぐらいしか思いつかないな
02242222007/10/10(水) 19:31:25ID:TchaYqjx
>>223
manを眺めましたが奥が深そうですね。じっくりと勉強してみます。
ありがとうございました。
0225login:Penguin2007/10/11(木) 00:25:04ID:0rD2It5e
>>222
草の根BBSでもやるんかい?
0226login:Penguin2007/10/11(木) 02:33:49ID:8ZTBNRII
モデムで思い出したが、ミャンマーで対外ネット回線が一時遮断されたって
報じてたじゃん。
こんなときにもなんとかなるよう在外公館にアナログモデムを常備してたりは
しないだろうか。
02272222007/10/11(木) 06:32:06ID:o32fDZEh
>>225
これまでCCT-98IIIのマクロで自動巡回してたんですが
Linuxにしたら使えなくなるそうなので・・・・。
って、いやそうじゃなくて、vgettyで留守電のテストを
やってたら回線をつかんだまま切れないことがあって
それを切断させたいわけです。

>>226
自分はいざというときのためにジャストシステム製の
音響カプラ持ってます。(処分してないだけかも)
0228login:Penguin2007/10/11(木) 08:26:20ID:A6nFaf5V
kermitをperlで操作するnifty4uというパッケージが、前世紀にあった。
NIFTY フォーラム自動巡回スクリプトなので、CCT-98な人には改造が容易かも。

ダイアルアップpppスクリプトを書けば済むんじゃないかと思うけど、やったことないから分かりません。。。
0229login:Penguin2007/10/11(木) 13:36:28ID:wykYuUw8
#!/bin/bash

cd /home/hogehoge

というシェルスクリプトを作成し、実行してみても、移動でき
ません。
ディレクトリを移動するにはどのようなスクリプトを書けばい
いでしょうか?
0230login:Penguin2007/10/11(木) 13:41:47ID:wNnhF+3E
>>229
シェルスクリプトとバッチファイルは違う。
シェルスクリプトはシェル内で動作する子プロセスだ。
0231login:Penguin2007/10/11(木) 13:44:37ID:wNnhF+3E
>>229>>230
一部訂正。
s/シェルスクリプトは/単純に実行したシェルスクリプトは/

解決方法は "source" 。
02322292007/10/11(木) 14:10:15ID:wykYuUw8
>>230>>231

ありがとう。今手元に環境がないので明日試してみます。
0233login:Penguin2007/10/11(木) 18:43:47ID:KODaF1AT
>>232
shell.sh がシェルスクリプトのファイル名だとして
chmod a+x shell.sh で実行権限与えて
shell.shがあるディレクトリで
./shell.sh
したら移動するよ。
02342292007/10/12(金) 09:38:40ID:EbLcx1Gh
>>231
sourceやってみたら無事cd出来ました。
>>233
やってみたけど、上手くいきませんでした。

お二方ともありがとうございました。
0235login:Penguin2007/10/12(金) 10:44:01ID:7zE2B01m
シェルプロンプトにコマンド名を叩き込んで実行すると、
子シェル(sh,cshなど)が新たに作られて、その子シェルがスクリプトを実行する。
で、スクリプトが終わるとその子シェルもろとも消えて親シェルに戻ってくる。
だから、シェルスクリプト内でcdしたり、環境変数をセットしても、その影響は
子シェルの中にとどまって、スクリプト終了と共に消えてなくなる。
cshのsourceやshの.(ドット)は、子シェルを作らないで自分の中でスクリプトを実行する。
だからcdやsetenv、exportの結果が、起動した親シェルに反映される
0236login:Penguin2007/10/12(金) 11:22:55ID:5+kNLqtp
. の他に alias とか関数使う手もあるよ。
02372332007/10/12(金) 17:40:09ID:sUVuIX9s
>>234
ごめん!間違った。
./shell.sh じゃなくて
. ./shell.sh でした。
. を打って1個スペース空けて シェルスクリプトファイル指定。
0238login:Penguin2007/10/12(金) 17:46:35ID:5+kNLqtp
>>237
なんで ./ を付けるの?
0239login:Penguin2007/10/12(金) 17:59:22ID:+Kk0eMQd
Yeah!めっちゃホリデイ
0240login:Penguin2007/10/15(月) 14:50:05ID:NjtHefoB
特定のURLを一定時間に読み込むシェルスクリプトをつくりたいのです。
今のところwgetを使ってwget http://hogehoge をクーロンで動かす予定ですが
もっとスマートなやりかたはありますか?
0241login:Penguin2007/10/15(月) 22:15:04ID:yaqxWPIK
>>240
それでいいんじゃね?
0242login:Penguin2007/10/15(月) 23:35:58ID:6xnjJ9Cn
>>241
じゃあ1分に1回よりも高頻度(30秒に1回とか、15秒に1回とか) やりたい場合はどうすれば?
0243login:Penguin2007/10/16(火) 00:24:31ID:7lwU6GvW
アタックしたいのか?
0244login:Penguin2007/10/16(火) 01:36:38ID:IhGBMLbJ
>>242
wget http://...; sleep 30; wget http://...
するスクリプトを毎分実行するとか。
0245login:Penguin2007/10/16(火) 08:18:30ID:a72PxkLH
>>243
アタックしたいわけじゃないですよ。
ただcronって最高でも1分に1回しか実行できないはずなので、それよりももっと短い間隔で
処理をさせたい場合とかどうするのかなぁとふと疑問に思ったもので。

>>244
なるほど・・。 しかし wget http://... ; のところで1分ぐらい処理に時間がかかった場合
その後の sleep 30 ; がきて、そしてまた wget http://... がくるから、タイミングと言うか場合によっては
30分に1回キッチリ実行されるとは限りませんね。31分かかって、その後実行されて
今度は29分後に実行されるみたいなズレ方はしますよね。
0246login:Penguin2007/10/16(火) 08:26:34ID:IhGBMLbJ
>>245
バックグラウンドで実行するとか。
つーか、何分もかかる処理を30秒ごとに実行していいのか?
0247login:Penguin2007/10/16(火) 11:46:31ID:wfMufGFC
cronはプロセスが無限増殖するのを抑えるために、同時実行数に制限があるので注意
Solarisだと、確か同時実行数が100個を超えるとそれ以降は時刻が来ても起動しなくなる
LinuxだとOOMキラーが動いて刈り取られるかもしれん

cronの起動間隔 ≒ プロセスの実行時間

となるような長めのプロセス、特に通信関係とかで長めのタイムアウトが発生しそうな
プロセスをcronに仕込むときは、注意したほうがいい
02482292007/10/16(火) 13:58:23ID:EtpWijek
環境が手元にないもので、遅レスになってしまいすみません。

>>235
なるほどです。ありがとうございました。
>>236
ありがとう。aliasでも出来そうでした。
>>237
.の後に続けて入力したところ、うまくcdできました。

>>238
素人なのでよく分かりませんが、実行ファイルを実行するときに付けるんでは?

それでは、みなさんありがとうございました。
0249login:Penguin2007/10/16(火) 14:09:44ID:IhGBMLbJ
>>248
. shell.sh
でもいっしょだよ。
やってみ。
0250login:Penguin2007/10/16(火) 17:45:32ID:a72PxkLH
./ を つけるのは カレントディレクトリのファイルを指定する為。

つけないと 環境変数 $PATH の中から該当する物が無いかを探してなかったら
エラー返すので。 カレントディレクトリのファイルを指定する時にいちいち
./ をつけるのが面倒だからって $PATH に ./ も含めてしまうとセキュリティホールになるので
やらないでね。
0251login:Penguin2007/10/16(火) 17:50:59ID:IhGBMLbJ
>>250
>>249
0252login:Penguin2007/10/16(火) 18:39:11ID:tU6zGUOB
シェルスクリプトで端末の現在の行数を得るにはどうしたらいいですか
0253login:Penguin2007/10/16(火) 19:18:04ID:iHfKM46h
stty -a とかかな。
0254login:Penguin2007/10/16(火) 19:45:06ID:tU6zGUOB
>>253
情報ありがとうございます。
行数を表示するだけでなくて、
シェルスクリプトの中で行数を変数に格納して、
なんらかの処理を行いたいと思っているのですが
何かうまい方法はありますでしょうか
0255login:Penguin2007/10/16(火) 21:12:10ID:pdm4T3SF
>>254
ROWS=`stty -a | tr ";" "\n" | grep rows | sed "s/.*rows //"`
0256login:Penguin2007/10/16(火) 21:36:05ID:tU6zGUOB
>>255
できましたありがとうございました。
0257login:Penguin2007/10/16(火) 23:32:43ID:sWAUZpv3
$LINES じゃだめなの?
0258login:Penguin2007/10/17(水) 04:58:42ID:d5Vjha9K
シェルスクリプトの中で$LINESがとれるとでも?
0259login:Penguin2007/10/17(水) 10:00:57ID:9KXOUzKW
ROWS=`tput lines`
COLS=`tput cols`
0260login:Penguin2007/10/17(水) 22:15:42ID:VuOM9tU/
eval `resize`
echo $LINES $COLUMNS
0261login:Penguin2007/10/18(木) 12:39:19ID:fyMSNeWa
>>260
resize は X がインストールされていない環境では使えない。
xterm の付属物なので。
0262login:Penguin2007/10/23(火) 17:14:39ID:OMh5qn/O
ちょっと相談に乗ってください。

日付.pc名.サイト名_access_log
ex)
20071023.pc-local01.hoge_access_log
20071023.pc-local02.hoge_access_log
20071023.pc-local01.hagehoge_access_log
20071023.pc-local02.testhoge_access_log

と言うログファイルをサイト名別のフォルダに移動した後
1つのログファイルにマージさせるスクリプトを書きたいのですが。
とりあえず、スクリプト書いてみたのですが正直何がなんだか
分かりません。アドバイスを下さい。


#!/bin/sh
timestamp=`date +%Y%m%d`
log=`find /home/hoge/log -name $timestamp.*`
list=`echo "$log" | sed -e 's/_access_log//g' | cut -c57-`

スクリプトでは、今日のタイムスタンプを取ってlogファイルを検索し
その結果のサイト名以降の”_access_log”を消して、サイト名より前
も入らないので、表示させないようにする。これから、サイト別にフォルダを
作ってそこに移動させるのですが、mkdir "$list"では上手く行きません。
何かいいアドバイスを教えてください。よろしく御願いします。
0263login:Penguin2007/10/23(火) 17:19:48ID:4jX2ZQqu
>>262
cut -c57- ってのは何?
0264login:Penguin2007/10/23(火) 17:20:31ID:XqFIvlF4
>>262
シェルスクリプト以前の話だな。
まずは最終的に何をやりたいのかをはっきりしろ。
0265login:Penguin2007/10/23(火) 17:26:06ID:4jX2ZQqu
>>262
$log にたくさんファイル名が入ってるのに
echo $log をいじろうとするのがよくわからんな。

>>264
まずは日本語の勉強からだな。
■ このスレッドは過去ログ倉庫に格納されています