シェルスクリプト総合 その37
■ このスレッドは過去ログ倉庫に格納されています
シェルスクリプトに関する総合スレッドです。 全般 ・荒しは無視しましょう。 ・丁寧な姿勢を心掛けましょう。 ・ネチケット(死語)を意識しましょう。 ・「○○(他の言語)でいいやん」は禁止。他のスレに行ってください。 ・「POSIX原理主義」「ユニケージ」「USP研究所」はPOSIXとUnixを曲解し 間違ったシェルスクリプトを広めている宗教です。洗脳されないようにしてください。 前スレ: シェルスクリプト総合 その36 https://mevius.5ch.net/test/read.cgi/tech/1614212414/ 関連スレ ・【Bash】Windows Subsystem for Linux【WSL】11 https://mao.5ch.net/test/read.cgi/linux/1627507889/ ・Bashでプログラミング [転載禁止](c)2ch.net https://mao.5ch.net/test/read.cgi/linux/1443885102/ ・シェルスクリプト総合 その28 https://mevius.5ch.net/test/read.cgi/unix/1533154936/ ・zsh その7 https://mevius.5ch.net/test/read.cgi/unix/1337844883/ ・過去UNIXで使われていた ksh というシェルについて https://mevius.5ch.net/test/read.cgi/unix/1582358403/ ・【POSIX】UNIXプログラミング【BSD】 [転載禁止](c)2ch.net https://mevius.5ch.net/test/read.cgi/unix/1443103705/ ・おまえら! shell は何を使っているんですか? https://mevius.5ch.net/test/read.cgi/unix/1012330865/ awk -v "var=`grep -A 1 'guid: c5b' source.prefab | sed -n '2p'`" '{ sub(var, "hello, world!"); print }' source.prefab > after.prefab >>612 なんかものすごくイキってるみたいだけど まともに動くコード書いてからにしてねw >>613 sedは柔軟性がない 仕様変更に弱いんだよ >>614 可読性が低すぎる >>615 バッチリ動いてるんだが? 一ヶ月後、一年後、 読み返してすぐに理解できるのはどっち?って話だよ 可読性という言葉はキミの頭の悪さの免罪符ではないですよ? ああ、awkを知らないのねw 勉強したほうがいいよ? sedやawkつかうならperlつかうな シェルスクリプトなんだから、判定等はそちらに任せて あくまで置換等の処理限定で >>600 sedの-zオプション使って複数行まとめて置換すれば? sed -Ez 's/(guid: c5b2e3eb25e32904fa18c5ae09b782d9[^¥n]*¥n m_Name: )¥n/¥1FOOBAR!!¥n/g' ServerCameraSpot.prefab 柔軟性のないsedや、ハードル高めのawkよりいいべ シェルスクリプトができる環境ならだいたいperlは入ってるし 条件の行と処理したい行が分かれてる時点で単純なフィルタじゃ無理だからでしょ awkなりperlなりで状態遷移は必須 むしろsedでできるなら教えてほしい あっさりワンライナーで書かれたもんだから激おこですな ここまで回答が出るのに時間がかかってるのに あっさりとは言わないw ワンショットならsedで十分なのかもしれないけど 同じタスクがまた発生しそうならunity yaml用のツール作っておくほうがいいと思う from unityparser import UnityDocument doc = UnityDocument.load_yaml(‘ServerCameraSpot.prefab’) entry = doc.get(class_name='MonoBehaviour', attributes=('m_Script',)) for k, v in entry.m_Script.items(): if k == 'guid' and v == 'c5b2e3eb25e32904fa18c5ae09b782d9': entry.m_Name = "FOOBAR!!!" doc.dump_yaml() >>612 そんなのただのawkのベタ書きじゃねーか ベタ餓鬼するなら断然perlのほうがいいよね cat ServerCameraSpot.prefab | perl -ne ' if (/guid: c5b2e3eb25e32904fa18c5ae09b782d9/) { chomp($a=<>); print "$_$a new\n"; } else { print }' perl最強! sed -e '/guid/,/^/s/m_name/xxx/' >>623 あの、これ動作してないように思うんですけど‥ Ruby のyaml を使ったら、最初のPrefab 部分しか取れなかった。 行頭に、--- があって、複数の文書として扱われるからかな? require 'yaml' data = YAML.load_file( "ServerCameraSpot.prefab" ) p data 出力 {"Prefab"=>{"m_ObjectHideFlags"=>1, "serializedVersion"=>2, 続く Ruby のyaml で、load_stream で複数文書を読めるらしいが、 14行目の、--- !u!1 &1459795647327810 で、エラーになる found undefined tag handle while parsing a node at line 14 column 5 (Psych::SyntaxError) require 'yaml' File.open "ServerCameraSpot.prefab" do |io| p docs = YAML.load_stream( io ) end >>638 5ch仕様なのか連続複数スペースは一つにまとめられるみたいね m_Name: ) の前のスペースが一つになっちゃってる Unity は、UnityYAML と呼ばれる、独自に最適化された、YAML ライブラリを使用します。 UnityYAML ライブラリは、完全な YAML 仕様をサポートしません --- で始まる行を、--- に置換すると、Ruby のYAMLでも動いた require 'yaml' # 行末の改行を削除して、1行ずつ処理する。accum は蓄積変数 input_yaml = File.foreach( "ServerCameraSpot.prefab", chomp: true ).with_object( String.new( ) ) do |line, accum| line = "---" if line.start_with?( "---" ) accum.concat( line, "\n" ) end docs = YAML.load_stream( input_yaml ) # 複数文書 p docs.dig( 1, "GameObject", "m_Name" ) #=> "ServerCameraSpot" >>641 の最後の行を、コメントにして、 # p docs.dig( 1, "GameObject", "m_Name" ) #=> "ServerCameraSpot" その後ろに、下の2行を付け加えると、内容を変更して出力できる。 docs[ 3 ][ "MonoBehaviour" ][ "m_Name" ] = "あいう" # 変更 puts YAML.dump_stream( *docs ) # 複数文書 ただし最初の、% で始まる、2行のディレクティブが出力されない。 それと、複数文書の区切りが、--- となる --- !u!1001 &100100000 みたいな、Unity の型を、Ruby では解釈できない UnityのYAMLは正規形じゃないから、普通のパーサーで解釈するのは、骨が折れる timeコマンドみたいな感じで、あるプロセスとその子プロセスが読み書きした ファイルのデータ量を簡単に調べる方法ないですかね? Linux板に書き込めなかったのでここで 俺が知らないだけかもしれんが、コマンドとしてはないんじゃないかな? mmapのメモリコピーによる書き出しの捕捉はカーネル空間じゃないと無理だろうし 比較的簡易的なのはstraceだけど、mmapのは漏らす 面倒なのでstapとか思いつく Linux 板は、荒らし退治がすごい もう何か月も書けない。まだ、何年も続きそう 「linux メモリ使用量 プロセス 監視」などで、検索すれば? Zabbix などに、そういう項目は無いのか? >>648 そのコマンドって一瞬で実行が終わるんですよね 久しぶりにこのスレ来たけどPOSIX云々言ってた人消えたんだな 一気に過疎ったな 一時期は数ヶ月で1スレ消火するぐらいの勢いがあったのに。つわものどもが夢の跡 見てきたけど酷いな。よくシェルショッカーなんて相手にするよ リッチー大佐も冷静を装ってるが完全に脅迫になってるのわかってないのかな BourneがALGOL策定に関わってたからfiとかesacになった、odは名前被りで免れたという小噺は聞いたことあったが、ここまで染まりきってたとは思わなかった さすがにソース内までは免れきってない、あとPOOLってなんだよ… https://minnie.tuhs.org/cgi-bin/utree.pl?file=V7/usr/src/cmd/sh/mac.h 昔は、マクロでCを他の言語っぽく書けるようにする、つー流派?があったからなあ。w begin/endを定義してPascalっぽくとか。 >>659 昔の話だろ?Bourneシェルの後のバージョンは ALGOL風じゃなくなってるで >>660 COBOLっぽくしてるのを見たことがあるな doが対称性を崩してるよな キーワード …; do … done FOR-ROF LOOP-POOL WHILE-ELIHW 美しい対称性 xargs コマンドの -P オプションに、3時間ぐらい前に気付いた。 >>659 #define POOL } これやったことあるわ… cの式とbrainf**kの命令は一対一対応してるので、main()内にそのまま展開すればbfトランスパイラになる これそのままで動く https://en.m.wikipedia.org/wiki/Brainfuck brainfuck command C equivalent (Program Start) char array[30000] = {0}; char *ptr = array; > ++ptr; < --ptr; + ++*ptr; - --*ptr; . putchar(*ptr); , *ptr = getchar(); [ while (*ptr) { ] } 大体合法なCトークンじゃないので、一度BRAに置き換えてsedで置換する必要はあったけど bashの [[ -a ${TMP_FILE} ]] && rm -f ${TMP_FILE} って-aとか[[ ]] &&とかそれぞれどういう意味なの? TMP_FILEがあったら消すってことなんだろうけど -aはファイルが存在すれば真になるという古い書き方 ANDの意味の-aと間違いやすいから-eを使え &&は普通にANDだろ >>667 古い書き方なのねandの-aと紛らわしいな 短絡評価。真、偽の順で表示される and の場合は、左辺が偽なら、右辺を評価せずに、偽が確定する。 or の場合は、左辺が真なら、右辺を評価せずに、真が確定する [ a = a ] && echo 真 [ a = b ] && echo 表示されない [ a = a ] || echo 表示されない [ a = b ] || echo 偽 bashは構文を拡張しすぎたせいで、変なのを書くやつが増産されてしまった。 >>668 []がコマンドであることを認識した方がいい 昔は [ が test にシンボリックリンクされていたものぢゃ ファイルの先頭と末尾だけを表示させたくて $ (head;tail) < tmp みたいなことをしててふとハマったんだけど、 $ for i in {00..60};do echo "22-04-20 00:$i"; done > tmp $ (head;tail) < <(grep 22-04-20 tmp) だと head 分しか表示されなかった 多分シグナルとかの関係だろう、と思ってるんだけどイケてる回避策ってあるかな? まあなければ愚直にファイルに書き出すだけなんだけども たぶんheadが複数行まとめて読み込んで行数とか判断してるんだと思う 回避策はないかな stdinから読み込む挙動を変えるオプションも無さそうだし (sed -u 10q;tail) < <(grep 22-04-20 tmp) せやったら全部Sedだけでええやろ!w と思ったけど、なるほど、むつかしいんやな。。。 末尾複数行を簡単につまめないんやった。 $(($(wc ...)-N))を埋め込んだらできるけど、それもなー。 どうでもいいけど22-04-20 00:60ってなによ >>677 >>678 そうか、headでバッファ読み捨てられてtailは参照できてないのか サンクス >>680 気にせんでくれ… readでcsvのヘッダを読んで、本体だけが次のパイプに渡って処理され、最後にcatで再結合する技は見たことある つまり、head じゃなくて10行readならいけるんでないか? >>685 検索力に惚れるわ 俺は過去ログ取得に不快な広告見せられたのでコピペっておく 231 名無しさん@お腹いっぱい。 sage 2017/06/14(水) 11:09:43.34 .net head -1 じゃなくて read を使ってこんな事をしてたり df -h | { read h; echo "$h"; sort -k5,5gr; } そうそうこんなん書いてたわ、例の通りdf -hやtsv/csvのヘッダ一時退避に重宝するイディオム しかし-nは覚えてるけど行数オプションとかあったかな? whileで包んで10回数えるのも多分行けるとは思うが、まあ最悪 read line; read line;… なら通るでしょう() { for _ in {1..10};do read l; echo "$l"; done; tail; } < <(grep 22-04-20 tmp) grep 22-04-20 tmp | tee >(head) >(tail) >/dev/null lsの日時の書式をyyyy/mm/dd hh:mm:ss固定にしたいのですがどっかに設定あるんでしょうか >>688 これ動くような気もするけど、エッジケースの詰め合わせみたいで関心するわ…ぜひ明日試したい teeはプロセス置換への分配を均等に進めるのか? head/tail でなければ入力も出力も数ブロックのバッファ単位で入り交じるはずだけど、バッファ単位に収まる10行のhead/tailの出力は一塊で吐かれるはず、つまりhead→tail/tail->headのいずれか 先頭だけ舐めるheadの方がtailより先に処理を終えるからhead->tail、の出力になるのだろうか? tee, head, tailの実装とバッファリングモード、入力データの素性の全てに依存してそうなヤバさ とりあえず手元のandroidとかいう玩具で GNU bash, version 5.1.8(1)-release (aarch64-unknown-linux-android) $ seq 100 | tee >(head) >(tail) >/dev/null 91 92 93 94 95 96 97 98 99 100 1 2 3 4 5 6 7 8 9 10 入力が小さいときに限っては、teeも実質引数に一回渡したきりだからheadの速さも関係ないんだろうね seqの引数を二分していけば均衡して、結果はランダムになりそう awk -v N=10 '{ if (NR <= N) print $0; buf[NR % N] = $0 } END { for (i = (NR - N + 1 > N + 1 ? NR - N + 1 : N + 1); i <= NR; i++) print buf[i % N] }' つまりさ、複数のコマンドを使って 効率的に処理する方法はないってことでしょ? >>696 みたいにするしかない seq 100 | pee head tail peeでだめなん? >>689 ls −l −−time−style=+'%Y/%m/%d %H:%M:%S' をaliasにでも登録しておく >>697 そもそもgrepが律速なんだから効率とか野暮だけど、あえて言うなら 元のファイルがダンプしてしまえるならストレージは食うが終端にシークしてしまうのが最速だし、ストリーム処理なら初めの10行プリントする自明な処理の後、10行のバッファを保持して終端が見えるまでひたすら読みまくるしかアルゴリズムはないわけで それはsed N;N;...でもなんでもいいが、timeするまでもなく10行保持して読み捨て専用マシーンとしてガリガリチューンされてるtailを使うのが最速に決まっとるがな 変な流れになってるのは>>688 という爆弾に完全に食われてしまったからな… 俺にも挙動が予測不能過ぎて興味が尽きない >>695 seq 10001 | tee >(tail -10000) >(head -10000) >/dev/null を実行しても、headが前半、tailが後半と期待どおりに出力されるんで、問題ないんちゃう? headは頭から行単位に出力、tailは終端に達してから出力、やと思うとそれでいい気もするし。 >>692 は知らん!w 並スペックのx86-64Debian/bash5/coreutils環境で問題のを検証 >>692 うちではseq 100だとheadが勝った、なおheadとtailを交換しても同じ 10000(適当)でも大体同じ結果が出る、そもそも再現性あるの?と思って十回くらい再実行してたら 1 2 3 4 5 6 7 99991 9992 9993 9994 9995 9996 9997 9998 9999 10000 8 9 10 という入り交じるケースを発見したw head or tailだけにコイントスってか(裏でも表でもないが) https://i.imgur.com/uQBk3cx.jpg バックグラウンドの割り込み遅延やその時点での負荷が影響するだろうから、エントロピー源に出来るな もっとも一様乱数に近付けるにはおま環固有の定数を探す必要はあるが マウスグリグリで乱数吐く/dev/randomと原理的には同じもの そもそもteeから非同期に投げたプロセスが順序良く出力することを期待するのがおかしいわけで 何のコマンドでもいいが、それを暗喩する名前のheadとtailというチョイスがツボに嵌まって面白い というか>>688 は狙ってやってるだろ pidやマウス座標とか拾って改善目指すとかは無粋 字面とその挙動、足すことも引くことも躊躇われる簡潔さ 完成し尽くされてるよな 今スレのベストコマンド賞にノミネートしたい ユーモア部門なw プロセス置換がposixで無いのだけが惜しいが、一番面白いワンライナーなのは間違いない >>703 tailのほうにsleep 0.1でも入れとけば充分安定するな。 そこまでやるならもういっそ行番号振って最後にソートしろよ… というか、気紛れさが可愛いという話なのに安定させてどうする もうとっくに解決してるので… 爆弾落としてった誰かが悪い >>687 でいいと思うが、あえて添削するとすれば、まずコマンド置換は不要 grep pat file | { for i in {1..10}; do read line; echo "$line"; done; tail; } 再利用したいならパラメトライズが面倒なブレース展開を避けるべき(パラメータ展開より先) {1..10} -> $(seq $n) もちろんwhileでカウントしてもいい、どちらの版も適当なファイルで取り敢えず動作確認済 まちがい ✗コマンド置換 ↓ ✔プロセス置換 です ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる