シェルスクリプト総合 その29
■ このスレッドは過去ログ倉庫に格納されています
シェルスクリプトに関する総合スレッドです。 全般 ・荒しは無視しましょう。 ・丁寧な姿勢を心掛けましょう。 ・ネチケット(死語)を意識しましょう。 前スレ: シェルスクリプト総合 その28 http://mevius.5ch.net/test/read.cgi/tech/1532397676/ 最近sedほとんど使わなくなった。 perl -peで代用しちゃう。 >>593 sedコマンド使うとめちゃくちゃ遅くなるぞ >>591 でめちゃめちゃ遅くなるって、頭大丈夫か? >>597 10〜100倍ぐらい遅くなるだろうね。 遅いからそれがなんなの?って意味なんだけど そんなに意味がない速さにこだわるなら、なんでもかんでもCで書くべきだろうにw 言っている意味がわからん。>>591 でって言っているんだけど >>591 は何度も繰り返すわけでもなく単なるタイマー起動するまでだけという、また、例の指定時間が1h30mという 起動するのに、0.1秒かかるのと0.01秒もしくは0.001秒でになんの差があるというのか、なんでそんなとこ気になんの?病気じゃないのってとこかな >>603 同じく。 なんで一回かぎりの処理(しかも要求される精度は1分程度)に そんなコンマ数秒の速度の違いを考慮しなくちゃならないんだろうか。 自分の方が賢いと思って知ったかぶりしてるだけでしょ。子供にはよくあることだよ。 ここには悪質な荒らしも来るんだから、スルーできないと荒らしの思う壺じゃないかな。 >>604 要求される精度は1分程度なんてお題に書いてあるっけ? >>606 引数が時・分なんだから、ふつーは秒単位は考慮不要と受け取るやろ >>608 それを言うなら,お題には「プログラムの起動が遅かったらだめ」とも書いてねーよw だからsedを使っても何ら問題ない。 ↓こんなのでいいんじゃないかな? ちょっと抜けがある(..h..mみたいな不正な指定も通してしまう)けど 自分で使うプログラムなら,これくらい入力時に注意できるから そこまで厳密な判定は要らないと判断した。 sleep $(echo "($(echo '1h30m' | sed -e 's/\([0-9.][0-9.]\)*h\([0-9.][0-9.]\)*m/\1 * 60 + \2/')) * 60" | bc -l) >>610 OSなに使ってる? Debianでは動くけど。1.5hとかで。 Ubuntu 19.04 だと (standard_in) 1: syntax error sleep: missing operand となる。 echo "($(echo '1.5h' | sed -e 's/\([0-9.][0-9.]\)*h\([0-9.][0-9.]\)*m/\1 * 60 + \2/')) * 60" が (1.5h) * 60 になるので bc でエラーになる >>613 ドットは \ でのエスケープが必用なのでは? >>592 は冗長やな echo 1h30m | { echo 'scale=0;'; sed 's/h/*3600+/;s/m/*60+/;s/s//;s/+$//;s:.*:(&)/1:'; } | bc echo 1h30m | sed 's/h/*3600+/;s/m/*60+/;s/s/+/;s:.*:scale=0;(&0)/1:' | bc scale=0はデフォルトだからいらんと思うけど >>613 仕様です。 ・1h23m45s みたいな秒には対応していません。エラーになります。 ・mは必須です。mを省略した場合エラーになります。1.5hの場合は1.5h00mと入力してください。 ・1文字のmには対応していません。エラーになります。1mは01mと入力してください。 ・mが3文字以上で文字数が奇数の場合は、対応していません。エラーになります。 ・mが4文字以上で文字数が偶数の場合は、下位2文字のみが使用されます。(例 1234m の場合 34、12.345の場合45) ・1文字のhには対応しています。 ・hの文字数が偶数の場合は、下位2文字のみが使用されます。(例 1234h の場合 34、1.23の場合23) ・hの文字数奇数の場合は、最初の1文字と下位2文字をあわせた、3文字が使用されます。(例 12345h の場合 145、123.5の場合1.5、1.23の場合23) 仕様漏れ ・hは必須です。hを省略した場合エラーになります。30mの場合は0h30mと入力してください。 >>616 > ・mが4文字以上で文字数が偶数の場合は、下位2文字のみが使用されます。(例 1234m の場合 34、12.345の場合45) この仕様の意味ってなに? この仕様を無視して, 「mの前の数字は2桁でなくてはならない」 という仕様に統一すれば,すごく書き易いシェルスクリプトになると思うんだけど。 >>616 追加で質問。 なんでhやmの前の数字の桁数の偶奇に拘るの? 例えば, ・mの前には二桁の整数(0埋め)しか許されない ・hの前には小数点以下一位の精度で99以下の数しか許されない という仕様のほうが,仕様も短かいし実装も簡潔になると思うんだけど。 Ruby では、 re = /([^h]+)h([^m]+)m/ # str = "1h0m" str = "1.5h0m" md = str.match( re ) # p md[ 1 ], md[ 2 ] #=> capture 部分 begin # 整数じゃなければ、浮動小数点にする hour = Integer( md[ 1 ] ) rescue ArgumentError hour = Float( md[ 1 ] ) end minute = md[ 2 ].to_i # 整数 p hour, minute #=> 1.5, 0 行き当たりばったりでコードを書く人(>>609 とか>>623 )ってのは お題がでたら、そのお題だけ通るコードを書く。 通らない例が現れたら、その通らない例のためのコードを追加する 別の通らない例が現れたら(以下同文 こんな感じでコードがどんどん長くなっていく ちゃんと考えてコードを書いている人は短いコードで実現できる 物事を抽象化して考える。そのせいでいろんな場合に対応できる。 行き当たりばったりでコードを書く人は、いろんな場合に対応したら コードが長くなると考える。だが抽象化するといろんな場合に対応し、かつコードは短くなる >>614 \([0-9.][0-9.]\)*m が入ってしまっているので、 echo "($(echo '1.5h00m' | sed -e 's/\([0-9.][0-9.]\)*h\([0-9.][0-9.]\)*m/\1 * 60 + \2/')) * 60" とかするしかない echo "($(echo '1.5h' | sed -e 's/\([0-9.][0-9.]\)*h\(\([0-9.][0-9.]\)*m\)\?/\1 * 60 + \3/')) * 60" なんてすると、 (1.5 * 60 + ) * 60 になって bc で syntax error >>626 行き当たりばったりのクソコードなんか相手にしなくていいで 代わりに俺が同じアプローチのまとなコード書いてやるからよ echo '1.5h' | sed -E 's/(([0-9.]+)h)?(([0-9.]+)m)?(([0-9.]+)s)?/(\2-0)*3600+(\4-0)*60+(\6-0)/' | bc (.0を消したければ>>615 を参考に /1 すればいい) クソコードはクソコードで終わりでいいって話 あ、クソコードですね♪使い物になりませんね♪でいいってことよ。 いちいちこういう場合にエラーがなりますとかやらなくていい さっさと廃棄処分してしまおう。 まず設計がおかしい! バグのほとんどは、設計がおかしいから起きる 時間は、0〜24 の整数のみ。 分は、0〜60 の整数のみ 最大で、24時間までとか 整数に変換できなければ、浮動小数点に変換するとか、こんなおかしな設計はない! >>623 = >>631 の発言 >>623 「整数に変換できなければ、浮動小数点に変換する」 ↓ >>631 「整数に変換できなければ、浮動小数点に変換するとか、こんなおかしな設計はない!」 つまりrubyを使うと統合失調症になってしまうということ? そんなことには、ならない! Rubyは、すばらしい言語 整数に変換できなければ、浮動小数点に変換するとか、明らかにおかしいでしょ? だから、質問者に言われた通りに書いたら、おかしいと言うこと! >>631 >時間は、0〜24 の整数のみ。 >分は、0〜60 の整数のみ 多くの言語が採用しているのは、 時間は、0〜23 の整数のみ。 分は、0〜59 の整数のみ 色んな言語の、Time クラスのメソッドを参照 >>623 「整数に変換できなければ、浮動小数点に変換する」 ↓ >>631 「整数に変換できなければ、浮動小数点に変換するとか、こんなおかしな設計はない!」 ↓ >>637 「質問者が整数に変換できなければ、浮動小数点に変換するって言った!浮動小数点でスレを検索してみろ!」 【検索結果】 623 名前:デフォルトの名無しさん[sage] 投稿日:2019/06/03(月) 08:15:05.64 ID:8eXXlkO0 [1/2] 631 名前:623[sage] 投稿日:2019/06/03(月) 11:22:16.99 ID:8eXXlkO0 [2/2] 637 名前:623[] 投稿日:2019/06/04(火) 05:26:37.80 ID://1XsOfQ >>637 俺はシェルスクリプトもRubyも上級者なんだよなぁ(苦笑) $ irb irb(main):001:0> require 'active_support/time' => true irb(main):002:0> 1.5.hours => 5400.0 seconds >>591 最初に引数を"h"→"h "、"m"→"m "に変換するといいんじゃないかな 小数点を含んだ時刻表記(単位は時・分)を秒数に正規化する,みたいな話かね 練習のために書いてて、うまい書き方は無いかという話だった気がするのだが… だよな、単に。sedならという応えも直後にあっての 変なのが変な話に変えてる 質問者「今から1時間後とか、あと1.5時間後とかにも対応してみました」 Ruby厨「整数に変換できなければ、浮動小数点に変換するとか、こんなおかしな設計はない!」 Ruby厨「時間は0〜24の整数のみ! 午前1時30分のことを1.5時とか言わない!」 バッシュでファイル名がアスキーコードが判定する方法教えて下さい一番簡単に アスキーコードはUTF8の一部でもあるのでnkfは確認出来ないとおもいました if iconv -t ASCII <<< "$filename" > /dev/null 2>&1; then 必要なら -f を。必要なら ASCII 以外の他のエンコーディングを >>646 この程度でbash専用にする必要ない。nkfもiconvも遅い。 case $filename in *[!a-z]*) # a-z以外の文字がある *) # a-zのみ esac あとはASCIIのみになるようにすればいい POSIX文字クラスを使うと楽 https://en.wikibooks.org/wiki/Regular_Expressions/POSIX_Basic_Regular_Expressions#Character_classes 制御コード入れたいのかにもよるのとASCIIコード以外にあてはまるかどうか調べてないが 例えば [![:cntrl:][:print:]] とかかな? 最悪一文字ずつ書けばいいだろう。 やはりRuby厨と変わらないw 正しく動くのを示せばいいだけでしょ、勝手にa-zだけじゃなく。それがちゃんとASCIIと判定できるなら 横槍はするが、自分に横槍すんなか。やはりRuby厨と変わらないw 意味わからん。ちゃんと正しく動くのを示せばいいだけじゃん なんでそんな妄想に走る?まあ、>>645 と言っておきながらの>>648 でそういうのがデフォなんだろうけど 俺はRuby厨でもなんでもないよ、ざんねん だからお前と問答する必要はない話だよねw 質問者にヒントを出した。あとは自分でやるか、"質問者"が泣きつくかどうかだろ なんでお前が泣きついてるんだ?えーんえーん(笑) ヒントを出した、泣きつくかどうか よくそんな言葉吐けるな。ちょっと前のいつものヤツか、その子供のような最後といい、よく恥ずかしげもなく書けるなw いつもの悔しい思いをしたやつってのは正解らしいwww bash や zsh の場合、locale 依存なんだなぁ $ bash -c 'LC_CTYPE=C; case 1 in *[![:cntrl:][:print:]]*) echo 'x';; *) echo 'y';; esac' x $ bash -c 'LC_CTYPE=ja_JP.UTF-8; case 1 in *[![:cntrl:][:print:]]*) echo 'x';; *) echo 'y';; esac' y bash で [:ascii:] を使う場合には locale は関係なし $ bash -c 'LC_CTYPE=C; [[ 1 = *[![:ascii:]]* ]] && echo x || echo y' x $ bash -c 'LC_CTYPE=ja_JP.UTF-8; [[ 1 = *[![:ascii:]]* ]] && echo x || echo y' x >>665 そうそう。だから面倒なので「ASCIIコード以外にあてはまるかどうか調べてない」し 「最悪一文字ずつ書けばいい」 あとbashやzshって限定しなくて良いよ。全部そうだから > bash で [:ascii:] を使う場合には [:ascii:]はPOSIXクラスじゃない なんで誰も求めていないPOSIXや速さにそんなにこだわるんだかな >>665 はちゃんと前段と分けて「bash で [:ascii:] を使う場合」とも言っている=「bashで」と言っているのに、なんでそうも自分は知ってるを出したいんだか ところが Ubuntu の dash(conform with the POSIX 1003.2 and 1003.2a specifications for the shell)は依存しないのよね…(上の例ではどちらも x を返す) 他人のレスを読めないのに妄想だけは いつものことか 「求めていない」と明言していない以上、 「求めていない」なんてお前が断定するなってことだよ。 >>668 なんだろ、C Standard Libraryにそういうのがなくて各々独自実装とかかな? POSIXで明確に文字(コード)として、これこれと規定してなくて独自判断実装とかか dashはプログラムでロケール(LC_CTYPE)の設定をしてない手抜きとかか。も考えられるね。どうであろうとデフォ= Cという >>651 > 正しく動くASCII判定のをどうぞ どうぞじゃなくて、それをやってみせる大チャンスだったのでは? そうすることに意義があると思うならね。 虚栄心の塊を助けるような真似はしたくはないな俺だったら 「助ける」って表現おかしくね? だって誰も「助けてくれ」なんて言ってないじゃん。 既に質問者の「助けて」には親切な奴が答えてくれている途中だった。 正しく動くプログラムに勝手にケチ付けた挙句、なんの案も出さずに「間違ってる」だけしか言ってないよね。 それな。 こっちは「こんな感じで作れますよー」って言ってるだけ あとは簡単なので質問者でもできるだろう (できないなら何かしらのレスをするだろう) そこにいちいち、それは完璧に動かないって言うだけ。言うだけ厨w >>645 >Ruby厨「時間は0〜24の整数のみ! 時間と時刻が混ざってるようだな こういう奴が仕様作成すると大変なことになる シェルスクリプトのスレは以下に統合しました。 今後シェルスクリプトの話題はこちらで くだらねえ質問はここに書き込め! Part 236 https://mao.5ch.net/test/read.cgi/linux/1556462911/ 某知恵袋で見かけた「ID非公開」さんの質問。 > Linuxのシェルスクリプトで質問です。 > リダイレクトの0は標準入力、1は標準出力、2は標準エラー出力。 > 0、1、2の他にも、3以上の番号もあるそうです。 > これら、3以上の番号を使った例を教えてください。 カテゴリマスター sle********さんの回答 > ファイルをオープンすれば3から順に使われるのだけど。 > 0,1,2の3つしか呼び出すプログラムには伝わらないのでできないのじゃないかな。 シェルスクリプトの話だということすら理解できてないなら回答するなよ。 シェルスクリプト リダイレクト exec でググれよとか思ったけど、「ID非公開」という時点で相手にする価値が無いしなあ… まあ確かにその説明は間違ってるけど 態々Yahoo知恵袋の回答を5chに持って来てまで叩くことあるかね……。 そう言えば以前 flock コマンドを使ってここに書かれているような排他ロックを掛けるのを書いたことがある。 http://fj.hatenablog.jp/entry/2016/03/12/223319 で、リダイレクトはこの例のように 200 とか使ったのだが、しかし、これが使われていたらまともに動かないのではないかと思う。 かといって現在使われていないファイルデスクリプタを探す方法があるのかというと、Linux なら /proc/$$/fd/ 以下を見れば 良いんだろうが多分OSごとにやり方が違っていると思う。ということで開きファイルでスクリプタを探す方法は bash にあるんだ ろうか? (bash でなくても良いが)。それとも探さずともシステムコールの open() 等のように空きを探し出して使ってくれる みたいな書き方はできるんだろうか? >>680 そこは「くだらねえ質問」だろ シェルスクリプトの事も書き込んでもよいけど、 シェルスクリプト専用のスレではない! Ruby のTempfile みたいな、一時ファイルでも作れば? >>684 ,685 空いているではなく、開いているまたは開いていないならわかりそうだが : >&200 しかし、なんで012以外をも直値にしたんだろうね プログラム板にキチガイ降臨中!botに一晩も反応する異常さ 一般人(学校恩師)に殺害予告をしているのでスレ建て通報してください。 https://mevius.5ch.net/test/read.cgi/tech/1559872586/ 142 名前:a4 ◆700L1Efzuv 投稿日:2019/06/18(火) 05:29:55 ID://qVkzO >>141 名古屋の人な 俺ね、君の問題を大橋先生と混ぜないことにする。つまりね、 片桐孝洋のことをボコろうと思う。普通に顎の骨を折る。これくらいで警察来るか? 一般市民とかさ、普通にさ、俺らの秘密なんだけどさ、日本人なんて復活ねーから。 shebangの書き方について教えてください。 #!/bin/sh # Next line is comment in Tcl, but not in sh... \ exec tclsh "$0" ${1+"$@"} ( 出典: https://rosettacode.org/wiki/Multiline_shebang ) コメント解釈の違いを利用して複数行に云々は分かります。 ただ気になった箇所が... ${1+"$@"} これは一体どういう意味合いが込められてるのでしょうか? Tcl 以外にも Perl とかでも同様の箇所があります。 引数 $1 が unsetなら null そうでなければ "$1" "$2" "$3" . . . って事ですよね。 それって、ただ "$@" と書くのと違いが分かりません。 ちなみに公式推奨は man tclsh8.5 までは "$@" man tclsh8.6 からは ${1+"$@"} になっています。ただし説明文はそのままでした。 良い解説があったので解決しました。 https://www.in-ulm.de/ ~mascheck/various/bourne_args/ スクリプトに引数を与えない場合、 一部の古いシステムでは "$@" の解釈が nothing (何もない) ではなく "" (空文字)になってしまうからだそうです。 参考までに言っておくと、>>691 のリンク先にも書いてあるが、 古いzshは ${1+"$@"} は期待したとおりに動かない 完璧な解決方法は、例 eval exec tclsh "\"$0\"" ${1+'"$@"'} ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる