1 名前:login:Penguin [2007/07/10(火) 23:17:13 ID:qGthZdME] UNIX板のスレを見ている方も多数おられるかと思いますが、 まあそれはそれとして、BASHウゼーとか言われる心配なく 平和にLINUX的スクリプト談義しましょうよ。 初めての自作スクリプト、自信ないから見てください。な初心者から トリッキーな技を駆使した作品を披露したい、蘊蓄を語りたい上級者まで いろいろな人に参加して頂けると嬉しいです。 perlやらPythonやらの話が混ざっても良いんでない? 【sed】シェルスクリプト総合@LINUX Part2【awk】 pc11.2ch.net/test/read.cgi/linux/1154578200/ pc8.2ch.net/test/read.cgi/linux/1121994321/ >>2-5 あたりに色々と。
74 名前:login:Penguin mailto:sage [2007/08/28(火) 16:31:19 ID:kk6ZVe0N] >>73 つcsplit
75 名前:login:Penguin mailto:sage [2007/08/28(火) 22:47:28 ID:WiEkAmOg] cat /tmp/test.txt | gawk '/^# time = 0\.3/{exit} /^# time = 0\.2/{flag=1} flag==1 { str = str$0"\n" } END{print str}' こんな漢字か。酔っているので合っているのかどうだか。 0.000000...の部分は付け足してクレイ
76 名前:login:Penguin mailto:sage [2007/08/28(火) 23:05:57 ID:WiEkAmOg] cat /tmp/test.txt | gawk '/^# time = 0\.20+E-01 *$/,/^ *$/ {print $0}' あと仕様の意味が、#time=...から始まる一ブロックだけ出す(空行が出たらオシマイ) という意味ならもっと単純になる
77 名前:login:Penguin mailto:sage [2007/08/28(火) 23:48:14 ID:Gt/lw90m] >>70 すげーまさにOK!ですた! awk の ? と : の使い方に感動 >>71-72 ls -lh とかでやろうとしたのは漏れ様も同じww
78 名前:login:Penguin mailto:sage [2007/08/29(水) 12:08:46 ID:NEtL1MxO] >>74 >>75 さっそくにありがとうございます。 試してみます。
79 名前:login:Penguin [2007/08/29(水) 22:41:00 ID:4pERO676] 再帰的に2つのディレクトリをdiffしたいのですが存在するかしないか と違うファイルだということだけわかればいいので わかりやすく比較する方法はありませんか? diffのマニュアルみてもそれらしいのはないようで
80 名前:login:Penguin mailto:sage [2007/08/29(水) 22:50:35 ID:UIgvqpQI] >>79 diff -rq dir1 dir2 ではだめなの?
81 名前:login:Penguin mailto:sage [2007/08/29(水) 22:51:26 ID:N3MeiS9e] >>79 www.gnu.org/software/diffutils/manual/html_node/Comparing-Directories.html#Comparing%20Directories $ LANG=C diff -r dir1 dir2 | grep Only とかである程度分かるかも。
82 名前:login:Penguin mailto:sage [2007/08/29(水) 22:52:42 ID:N3MeiS9e] む、-qで違いが分かるのか orz
83 名前:login:Penguin mailto:sage [2007/08/29(水) 23:16:46 ID:9GyP78LH] デジャヴなんだが俺だけか?
84 名前:login:Penguin [2007/08/30(木) 01:02:14 ID:F11xsKF5] パッケージようなのバージョンを比較する方法がわかりません。 イメージ的には、こんなことがしたいんです↓ ---------------------------------- hoge="1.3.37" foo="1.11.12" if [ "$hoge" -gt "$foo" ]; then echo "OK" else echo "NG" fi ---------------------------------- これだと、以下のようjにエラーになってしまいます。。。。 [: 1.3.37: bad number NG
85 名前:login:Penguin mailto:sage [2007/08/30(木) 04:22:00 ID:GmS5dPb3] hoge="1.3.37" foo="1.11.12" hoge=`echo $hoge | gawk -F. '{print (($1*100+$2)*100)+$3}'` foo=`echo $foo | gawk -F. '{print (($1*100+$2)*100)+$3}'` if [ "$hoge" -gt "$foo" ]; then echo "OK" else echo "NG" fi ピリオド区切りの数が固定(この場合は3) ピリオド内の桁数が固定(この場合は1-2桁) という条件付だけど。これらが不定なら、$1,$2,$3...を$iにして、 NFまでループさせればいいと思う
86 名前:login:Penguin mailto:sage [2007/08/30(木) 07:19:55 ID:QpfKAJKg] そのバージョン表記の書式にもよるけど、 oldv=1.11.12 newv=1.3.37 として if [ `echo $newv -gt $oldv | sed 's/\.//g'` ]; then echo OK; fi もしくは、 if [ `echo $newv.$oldv | tr . ' ' | xargs printf "%d%.3d%.3d -gt %d%.3d%.3d"` ]; then echo OK fi あたりでどうかな。
87 名前:login:Penguin mailto:sage [2007/08/30(木) 18:00:56 ID:bHskgKzh] >>84 rpmver ってのがある。 $ rpmver -v 1.3.37 1.11.12 RPM version 1.3.37 is lesser than version 1.11.12. Vine,VineSeed の RPMS.main SRPMS.main にある。 他のディストリは知らないけど パッケージが用意されてるかもしれない。
88 名前:login:Penguin mailto:sage [2007/08/30(木) 23:05:03 ID:nhWZyH15] $ which rpmver rpmver not found うえーん。。。
89 名前:login:Penguin mailto:sage [2007/08/31(金) 00:47:12 ID:U99N+hxP] >>84 Linux板だからbashでもいいよね。 #!/bin/bash v2n () { local IFS=. set $1 echo -n $(($1 * 1000000 + $2 * 1000 + $3)) } hoge="1.3.37" foo="1.11.12" echo $(v2n $hoge) $(v2n $foo) if [ $(v2n $hoge) -gt $(v2n $foo) ]; then echo "OK" else echo "NG" fi 添削してぇ
90 名前:73ですが mailto:sage [2007/09/01(土) 15:15:18 ID:uwRTp3HZ] >>76 おくればせながらありがとうございました。
91 名前:73ですが mailto:sage [2007/09/01(土) 22:39:45 ID:uwRTp3HZ] >>76 仕様はおっしゃるとおりです。 その際のスクリプトも教えてくだされば幸いです。 なお、他のスクリプトは現在のところ動作していません。わたしの知識不足なのだろうと思うのでもうすこし調べてみます。 #0は補ってはあるのですが... ついでといってはなんですが、awkの本でおすすめの本などありましたら教えていただけませんか?
92 名前:login:Penguin mailto:sage [2007/09/02(日) 04:19:30 ID:WMH1r7G1] >>91 オライリーの sed & awk てかawkの本なんて何冊もないって。
93 名前:login:Penguin mailto:sage [2007/09/02(日) 08:46:56 ID:ToB27R8d] 本命 足立さんの訳してる awk 本 大穴 awk 256 本
94 名前:login:Penguin mailto:sage [2007/09/02(日) 20:47:44 ID:VmAuZafy] awk256倍はDOS時代からある骨董本で内容もふざけまくっているが、初心者が 「正規表現」「連想配列」という二つのキモを学習するにふさわしい内容。 読み終わったあとも、巻末の関数一覧がずっと使える。未だに刷を重ねてるけど 愛用者もおおいんじゃない? 大して御本家3人の書いたawk本は内容が高度な上に散発的で、調べたいことが すぐに出てこなくて使いにくい >>91 >>76 のがその仕様のスクリプトなんだけど。うまく動かないのは、スペースとかが ちゃんとコピペされてないからなんじゃないの?
95 名前:73ですが mailto:sage [2007/09/02(日) 21:37:03 ID:71yMDj2y] >>92-94 本の紹介ありがとうございました。 >>94 気づきませんでした。すいません。スペースの問題などを再確認してみます。 またなにかあったら伺うかもしれません。よろしくおねがいします。
96 名前:login:Penguin mailto:sage [2007/09/02(日) 21:40:05 ID:QLbcFUyG] DOS時代ってのはいつまでを言うんだ?
97 名前:login:Penguin mailto:sage [2007/09/02(日) 21:55:05 ID:ToB27R8d] awk 256 本の話の文脈としては、MS-DOS上のawk実装の時代かな
98 名前:login:Penguin mailto:sage [2007/09/02(日) 22:03:47 ID:VmAuZafy] >>97 そう。今の版じゃ改訂されてるのかもしれないが、俺の持ってるのだと gawkをDOSに移植したjgawkとかいうのを下敷きにしていて、中には486を乗せたキューハチだと スクリプトの速度が向上したとか、パイプの実行速度が遅いのはUNIXみたいな本物のパイプじゃないからとか、 そんな話題が満載
99 名前:login:Penguin mailto:sage [2007/09/02(日) 22:04:37 ID:QLbcFUyG] MS-DOS上のawk実装の時代ってのはいつを言うんだ?
100 名前:>>84 [2007/09/04(火) 00:34:58 ID:3rxVdbk9] おくらばせながら、ありがとうございますm(_ _)m
101 名前:login:Penguin mailto:sage [2007/09/06(木) 08:15:09 ID:33eRwNa2] 指定されたディレクトリ以下にあるディレクトリ一覧を返してくれるコマンドはありませんか? /data/ をTOPディレクトリとしますと /data/hoge/ /data/piyo/ /data/moge/ 等が帰ってくるコマンドです。で、この際 /data/hoge/direc/ みたいに、TOPディレクトリの 孫ディレクトリ以下は返さないで欲しいんです。TOPディレクトリの子ディレクトリのみを 返して欲しいのです。そして for TARG in command; do 処理; done のように for文で1つ1つのディレクトリを処理したいのです。 それからもう1つ、指定されたディレクトリ以下の子ディレクトリの数を返すには ls -l /data/ | grep ^d | wc -l でいいのでしょうか?ディレクトリだと ls -l した時に必ず最初が dから始まるので これでディレクトリのみがマッチして、後はwcでその行数を数えればいいかと思っているのですが 今の所これでちゃんと動作していますが、不具合が発生するようなケースは想定されますか? ディレクトリの数も孫ディレクトリ以下は数えません(再帰処理しない)。 昨日 basename と言う便利なコマンドを知った程度のレベルの人間ですので awk や sed 等の難しいコマンドはなるべく使わずに実現したいのですが、出来ませんかねぇ? 宜しくお願い致します。
102 名前:login:Penguin mailto:sage [2007/09/06(木) 08:27:57 ID:QTrKtnCG] >>101 ls -d /data/*/
103 名前:login:Penguin mailto:sage [2007/09/06(木) 08:30:08 ID:QTrKtnCG] /data/.x/ とかも考慮したいなら find で。
104 名前:login:Penguin mailto:sage [2007/09/06(木) 08:31:55 ID:33eRwNa2] >>102 あっちゃー・・・・そんな簡単なコマンドでこんな素晴らしい出力が得られるんですか! LinuxのCUIって本当に高機能ですね・・・素晴らしいです。本当にありがとうございます。 ls -l /data/ | grep ^d | wc -l ってやるより ls -ld /data/*/ | grep ^d | wc -l ってやる方が良いのでしょうか?どんなファイルやディレクトリがあっても確実に動作するような 書き方をしたいのですが・・・。
105 名前:login:Penguin mailto:sage [2007/09/06(木) 08:32:01 ID:QFjDOBHf] 属性が見えて良ければ ls -d /data/*|grep "^d"
106 名前:login:Penguin mailto:sage [2007/09/06(木) 08:33:56 ID:QFjDOBHf] -l忘れてた
107 名前:login:Penguin mailto:sage [2007/09/06(木) 10:26:24 ID:QTrKtnCG] >>104 > ls -ld /data/*/ | grep ^d | wc -l なんで grep するんだ?
108 名前:login:Penguin mailto:sage [2007/09/06(木) 11:58:40 ID:rZQRUej8] ls -1d /data/*/ /data/.*/ /data/../ もヒットするのが難点だけどな。ってかあれだ。つ「man ls」
109 名前:login:Penguin mailto:sage [2007/09/06(木) 16:47:27 ID:40ywKZW4] >>101 求めてることが出来たのであればどんなコマンドでもいいけど find の使い方も知っておいたほうがいいと思う。 > 不具合が発生するようなケースは想定されますか? > ディレクトリだと ls -l した時に必ず最初が dから始まる ディレクトリへのシンボリックリンクがあった場合の扱いをどうするか。 さらに言えばリンクの対象がどこにあるか ln -s /data/A /data/B と ln -s /tmp/C /data/B の違いとか。
110 名前:login:Penguin mailto:sage [2007/09/06(木) 16:55:32 ID:QTrKtnCG] ls -Ap /data | grep /$ でよかったか。 >>109 > find の使い方も知っておいたほうがいいと思う。 同意。
111 名前:login:Penguin mailto:sage [2007/09/06(木) 17:08:55 ID:ZccH/OF/] なのに誰もfindを使った答を書かないのはなんでだw 101への課題?
112 名前:login:Penguin mailto:sage [2007/09/06(木) 20:00:39 ID:QTrKtnCG] >>111 それもあるし、単にめんどうだし。
113 名前:login:Penguin mailto:sage [2007/09/07(金) 11:30:33 ID:BZSReuYl] んじゃ、俺の回答に採点してくれ find /data -type d -maxdepth 1
114 名前:109 mailto:sage [2007/09/07(金) 17:14:59 ID:NgwMB5/h] >>113 二ヶ所で減点。 1) find の出力に TOPディレクトリ(/data 自身)も含まれてる。 >>101 を読むとTOPディレクトリそのものは不要だと思う。 2) GNU find version 4.2.27 だと -maxdepth の位置で warning が出た。 find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.
115 名前:login:Penguin mailto:sage [2007/09/07(金) 17:35:19 ID:BZSReuYl] >>114 なるほど。非常に参考になった。 模範解答を頼む。
116 名前:login:Penguin mailto:sage [2007/09/07(金) 17:39:52 ID:aiZtBudz] >>115 もう一回自分で書いてみたら?
117 名前:login:Penguin mailto:sage [2007/09/07(金) 19:24:55 ID:Txvf/Wl4] find /data -mindepth 1 -maxdepth 1 -type d -exec ... shopt -s nullglob for i in /data/{,.{[!.],.?}}*/ do ... こんなんでいかが
118 名前:login:Penguin mailto:sage [2007/09/07(金) 19:45:52 ID:ezpNZgi5] cat hoge | awk に似ている。
119 名前:login:Penguin mailto:sage [2007/09/07(金) 20:30:25 ID:BZSReuYl] >>116 OK。これでどうだ? find /home/* -maxdepth 0 -type d
120 名前:login:Penguin mailto:sage [2007/09/08(土) 04:46:18 ID:WlyFgm6n] >>117 でもう答え出てるじゃん。 >>119 /home/.xxx/ とかが出ない。 * 使うなら find 使う意味ない。
121 名前:login:Penguin mailto:sage [2007/09/08(土) 14:42:47 ID:vllGfkN4] >120 >* 使うなら find 使う意味ない。 上下別々の回答なんじゃないの?
122 名前:login:Penguin mailto:sage [2007/09/11(火) 03:08:21 ID:997sWGjJ] bashrc の書き方もこのスレでいいですか?
123 名前:login:Penguin mailto:sage [2007/09/12(水) 11:40:47 ID:EatE1MlG] #!/bin/sh -f ls *.dat > list.txt なぜか走らん。
124 名前:login:Penguin mailto:sage [2007/09/12(水) 17:16:53 ID:A49nKXNq] >>123 子プロセスとして(?)起動するシェルに -f が渡らないんだと思う。 /bin/sh -f hoge.sh とか あらかじめ /bin/sh -f で起動したシェルで ./hoge.sh みたいにすると -f が有効になる。
125 名前:login:Penguin mailto:sage [2007/09/12(水) 17:21:21 ID:EatE1MlG] >>124 エラーで *.dat: ファイルもディレクトリもありません とでる ワイルドカードが原因かと思ったけど、hoge*でも同様のエラー シェルにしたら走らず、コマンドラインで直接投げたら走る なんでだろ
126 名前:124 mailto:sage [2007/09/12(水) 17:27:12 ID:A49nKXNq] >>125 /bin/sh -f の -f がどんな意味かわかってる? あと、シェルとシェルスクリプトはちゃんと区別したほうがいい。
127 名前:login:Penguin mailto:sage [2007/09/12(水) 17:33:44 ID:EatE1MlG] !/bin/cshで走ったわ コンソールがcshだった
128 名前:login:Penguin [2007/09/12(水) 20:01:20 ID:9HkBr7tD] 複数のpasswdファイル(passwd_A、passwd_B)を結合して、同じユーザ名があった場合 passwd_Aのものだけを残すというようなことをしたいのですがどうすればよいでしょうか?
129 名前:login:Penguin [2007/09/12(水) 20:12:55 ID:nfcPR4Gc] いったんファイルを結合する 一行ずつ上から順に読んでパスワードファイルに書き込む 書き込んだらそのユーザー名を別ファイルに書き出す その別ファイルにユーザー名がないことを確認してから パスワードファイルに書き込めばよい
130 名前:login:Penguin mailto:sage [2007/09/12(水) 22:19:22 ID:qqfxe9V8] while read t ;do if [ "`grep ^${t%%:*}: passwd_A`" ];then continue else echo $t >>passwd_A fi done <passwd_B
131 名前:login:Penguin mailto:sage [2007/09/12(水) 22:53:21 ID:SML918nz] んだば awk で。 awk -F: '{ t[$1] = $0; } END { for (e in t) print t[e]; }' passwd_B passwd_A
132 名前:login:Penguin mailto:sage [2007/09/12(水) 23:49:46 ID:lhLTsTba] awk -F: '!($1 in t){print;t[$1]=1;}' passwd_A passwd_B
133 名前:login:Penguin [2007/09/13(木) 21:53:28 ID:8j1+julM] aaa.txtの中身 20070109,170000,170000,167000,170000,4 20070110,168000,168000,168000,168000,10 20070115,171000,171000,163000,169000,500 を 2007/01/09,170000,170000,167000,170000 2007/01/10,168000,168000,168000,168000 2007/01/15,171000,171000,163000,169000 のように YYYY/MM/DDと表示を変更する 最後の,からあとを削除してbbb.txtとして出力したいと思っています どのようにすればいいものでしょうか 4文字目と5文字目の間に/を挿入するということがsedでできなくて悩んでおります よろしくお願いいたします
134 名前:login:Penguin mailto:sage [2007/09/13(木) 22:06:02 ID:OVx1tSlg] cat /tmp/aaa.txt | gawk -F, '{printf("%04d/%02d/%02d,%s,%s,%s,%s\n", substr($0,1,4),substr($0,5,2),substr($0,7,2),$2,$3,$4,$5)}' > bbb.txt
135 名前:login:Penguin mailto:sage [2007/09/13(木) 22:08:03 ID:G9V8Phhb] \(\)でグルーピング、\{\}でマッチする回数の指定。 グルーピングしたパターンは後で\1,\2で参照出来る。 \を忘れるなよ。
136 名前:login:Penguin mailto:sage [2007/09/13(木) 22:09:20 ID:G9V8Phhb] あ、ごめん、>135はGNU sedの話
137 名前:login:Penguin mailto:sage [2007/09/13(木) 22:25:32 ID:8j1+julM] >>134 ありがとうございます gwakというのも勉強してみようと思います
138 名前:login:Penguin mailto:sage [2007/09/13(木) 22:52:13 ID:8j1+julM] >>134 manを見てみたら いろんなところで使用できそうです 本当にありがとう
139 名前:login:Penguin mailto:sage [2007/09/13(木) 23:24:02 ID:saILvvtf] >>134 catは要らんだろ。
140 名前:login:Penguin mailto:sage [2007/09/14(金) 00:50:00 ID:uh85VpLs] 正規表現も勉強した方がよろしいかと>>138
141 名前:login:Penguin mailto:sage [2007/09/14(金) 12:28:52 ID:hH9EcwDJ] ある XXX っていう名前を含んだプロセスを全て殺したい時、 ps aux | grep XXX | grep -v grep | awk '{print $2}' | kill ではだめなのに ps aux | grep XXX | grep -v grep | awk '{print $2}' | xargs kill ではOKなのはなぜですか?
142 名前:login:Penguin mailto:sage [2007/09/14(金) 12:34:24 ID:18sjQ9F0] >>141 kill って標準入力を受け付けないんじゃない。 ところで pkill XXX じゃだめなの?
143 名前:login:Penguin mailto:sage [2007/09/14(金) 12:37:30 ID:hH9EcwDJ] >>142 そうなのかなと思って for p in $(ps aux | grep XXX | grep -v grep | awk '{print $2}'); do kill "$p" done ってのもやってみたんですが、だめだったんですよ。
144 名前:login:Penguin mailto:sage [2007/09/14(金) 17:32:35 ID:Ney/3ygS] スクリプトでタイマー作れませんか? 一定間隔ごとに単純にコマンド出すだけじゃなくて 処理ごとに条件分岐してタイマーを止めたりコマンドが成功 するまで繰り返したりしたいのですが
145 名前:login:Penguin mailto:sage [2007/09/14(金) 20:21:33 ID:KxObz0sB] >>144 sleep使って、て程度で良いなら作れるような気しかしないんだけど、具体的にどうしたいのか書いたのが良いと思うぞ。
146 名前:login:Penguin mailto:sage [2007/09/14(金) 20:32:43 ID:RM0kquC+] >>144 どこまで出来たの?
147 名前:login:Penguin mailto:sage [2007/09/14(金) 23:57:41 ID:XHXILi6a] >>143 だめってどうダメだったのかわからんと。 for p in $(ps aux | grep smbd | grep -v grep | awk '{print $2}'); do "kill "$p" done これでやったらちゃんと動いたよ。スクリプトの問題じゃなくて 単に権限がなくてkillできなかっただけでは?
148 名前:login:Penguin mailto:sage [2007/09/15(土) 16:55:13 ID:/cIKvz/T] >>147 さっきやってみたら出来た。。。 間違って mplayer を40個くらい起動してしまって、そこでそのスクリプトを 叩いたつもりだったんだけど、焦ってなんか間違ってたのかもしれない。 とりあえず今度からは xargs のほうを使うようにするよ。
149 名前:login:Penguin mailto:sage [2007/09/15(土) 17:28:32 ID:YiwEKkpX] いやだからpkill使えって
150 名前:login:Penguin mailto:sage [2007/09/15(土) 17:49:23 ID:X+i1f7J3] command | command みたいな 例 cat hoge.txt | grep piyo 書き方があるじゃないですか? cat hoge.txt で出力される標準出力をパイプかませて その出力内容に対して grep piyo をかける と言うような。 これと xargs ってコマンドがあるじゃないですか?その違いがよく分からないのですが・・。 cat hoge.txt | xargs grep piyo みたいな?
151 名前:login:Penguin mailto:sage [2007/09/15(土) 18:13:14 ID:YiwEKkpX] 「cat hoge.txt | xargs grep piyo」=「grep piyo `cat hoge.txt`」
152 名前:login:Penguin mailto:sage [2007/09/15(土) 18:42:58 ID:X+i1f7J3] >>151 ほぉほぉ・・・・ cat hoge.txt | xargs grep piyo が grep piyo `cat hoge.txt` と同じならば cat hoge.txt | grep piyo は grep piyo hoge.txt ん?なんか混乱してきた・・・イマイチはっきりと分からない・・・
153 名前:login:Penguin mailto:sage [2007/09/15(土) 19:03:27 ID:8eNJORpc] argっていうぐらいだから引数に展開してくれるのだろ その場合hoge.txtの中身はファイル名でないとだめ
154 名前:login:Penguin mailto:sage [2007/09/15(土) 19:15:07 ID:jJyNjt7I] もう分かってるかもしれないけど、xargsは標準入力をコマンドライン引数に変換するだけ。 echo 'file1 file2 hoge' | xargs rm ↓ rm file1 file2 hoge
155 名前:login:Penguin mailto:sage [2007/09/15(土) 19:47:59 ID:X+i1f7J3] むぅ・・・ echo `file1 file2 hoge` | xargs rm が rm file1 file2 hoge となるならば echo `file1 file2 hoge` | rm は どう展開されるんですか? すみません、ほんと頭弱くて。
156 名前:login:Penguin mailto:sage [2007/09/15(土) 19:51:39 ID:YiwEKkpX] 引数と標準入出力の区別がまだついてなくて、全部「入力」として ごちゃまぜの段階でしょ?まずそれを考えてみるんだ>155
157 名前:login:Penguin mailto:sage [2007/09/15(土) 23:18:03 ID:+DsxitZ3] >>154 の echo 'file1 file2 hoge' | xargs rm >>155 の echo `file1 file2 hoge` | xargs rm どこが違うか理解してからにしろ
158 名前:login:Penguin mailto:sage [2007/09/15(土) 23:25:38 ID:PpA5ThvC] こんな初歩の初歩みたいなことに、どうしてそんなに高飛車になれるんだ。
159 名前:login:Penguin mailto:sage [2007/09/16(日) 01:01:56 ID:S5o7UTSR] 初歩の初歩は自力で身に付けてから来てくれよ。
160 名前:login:Penguin mailto:sage [2007/09/16(日) 01:06:18 ID:BSYCrrV+] タコタコ
161 名前:login:Penguin mailto:sage [2007/09/17(月) 04:16:34 ID:nqz563FT] convmv -r -f sjis -t utf-8 * --notest で、再帰的にカレントディレクトリ以下のファイル、ディレクトリ全てに対して sjisからutf-8に変換をかけるコマンドを打ったのですが、sjisとeuc-jpが混在していて convmvの仕様だと 1ファイルでも -f で指定した文字コード以外の文字コードのファイルが 存在した場合はそこで全ての変換処理が実行されなくなってしまいます。 違う文字コードの場合は除外して残りを全て処理してくれるオプションは無いかとman convmv を読んで見ましたが、無いようです。 仕方が無いので、これをシェルスクリプトで実現したいと思います。 実際にやりたいコマンドは convmv -r -f sjis -t utf-8 /data/* --notest で、これで変換できないファイルは convmv -r -f euc-jp -t utf-8 /data/* --notest で、全てのeuc-jpとsjisをutf-8にする事です。 for TARG in `find /data | nkf -w8` do convmv -f sjis -t utf-8 ${TARG} --notest convmv -f euc-jp -t utf-8 ${TARG} --notest done これで、sjisのファイルだろうがeuc-jpのファイルだろうが必ずutf-8になると思われますが いけると思いますか? | nkf -w8 をかませているのは、こうしないとターミナルで見た限りだと 文字化けしたファイル名でそのまま表示されるので、これだと多分ファイルにアクセスできないだろう との配慮から、ちゃんとしたファイル名で見えるようにしたつもりです。
162 名前:login:Penguin mailto:sage [2007/09/17(月) 08:49:52 ID:hnYIly1T] >>161 qkc最強伝説
163 名前:login:Penguin mailto:sage [2007/09/17(月) 11:57:35 ID:nqz563FT] >>162 hp.vector.co.jp/authors/VA000501/ これですよね? しかしこれはconvmvとは全く別物のようです。 convmv => ファイル"名"の文字コードを変換する ←私はコレが必要 qkc => テキストファイルの"中身"の文字コードを変換する ←これは違う・・・ なので使えないみたいです。 ちなみに >>161 で書いたスクリプトを実際に動かしてみた所、LinuxサーバのCPU使用率が 100%になって固まっちゃいました。無限ループをしているかファイル名取得に失敗しているか よく分かりませんがダメでしたOTL
164 名前:login:Penguin mailto:sage [2007/09/17(月) 12:18:44 ID:CDwJTqgj] よくわからんのだが、nkf -gで文字コードの判別してやりゃ良いんじゃねぇの?
165 名前:login:Penguin mailto:sage [2007/09/17(月) 12:56:16 ID:RA5G8Fdp] while ! convmv -f sjis -t utf-8 -r /data --notest ; do convmv -f euc-jp -t utf-8 -r /data --notest done なんか、どうよ? 文字コード判定がいまいちなのか誤認してくれたりするので --notest とって、ざっと眺めてからやる事を推奨。
166 名前:login:Penguin mailto:sage [2007/09/17(月) 13:00:08 ID:85s13mgP] --notest 外して試してみればーじゃん。
167 名前:login:Penguin mailto:sage [2007/09/17(月) 13:21:00 ID:hplwR1nR] echo $RANDOM で結果に乱数を返したいんですけど、 0〜9までの一桁の結果のみ返したい場合の指定方法とかってありますか?
168 名前:login:Penguin mailto:sage [2007/09/17(月) 13:53:15 ID:MlIRuyKv] $RANDOM % 10
169 名前:login:Penguin mailto:sage [2007/09/17(月) 15:09:07 ID: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はずして試してみてますが、エラーで弾かれます。
170 名前:login:Penguin mailto:sage [2007/09/17(月) 15:30:26 ID:kUn2DAgf] >>169 いや、ファイル名のコードをnkfで調べりゃいいじゃん、てことだったんだけど。
171 名前:login:Penguin mailto:sage [2007/09/17(月) 15:35:55 ID:kUn2DAgf] 念のため。 for T in `ls ~` do C=`echo "$T" | nkf -g` echo $T,$C done ファイル名の文字コードを調べてると思うんだが。
172 名前:login:Penguin mailto:sage [2007/09/17(月) 16:38:42 ID:nqz563FT] >>170-171 違うと思うなぁ・・・。 >>171 のスクリプト実行してみたけど これは ls ~ で表示されるファイル名リスト全体、、、そうだなぁ、、例えば a.txt b.mp3 c.tar d.gz e.tar.gz とか日本語も含むファイル名全てが列挙されると思うけど、それらのファイル名リスト 全体を1つのテキストファイルとみなして、テキストファイルの中身(つまりファイル名が列挙されてる) に対して文字コード変換をかけた結果を echo で出力しているんじゃないですか? だからnkf は ファイル"名"の文字コードを調べるんじゃなくて、あくまでもテキストファイルの中身 の文字コードを調べるんだと思いますが。それこそqkcみたいな動作? convmvは全くそれとは性格が異なる物だと思いますが、、非常にこの辺ややこしい・・・。
173 名前:login:Penguin mailto:sage [2007/09/17(月) 16:45:55 ID:8vN1DPCo] なんでこんなに全然わかってないのに自信満々なのだろうか
174 名前:login:Penguin mailto:sage [2007/09/17(月) 16:47:06 ID: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 の文字コード判定の 精度はあまりよくないが、やらないよりはマシだろう。