シェルスクリプト総合 その26 [無断転載禁止]©2ch.net
■ このスレッドは過去ログ倉庫に格納されています
シェルスクリプトの総合スレです。 □お約束 ・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。 Linuxユーザは/bin/shの正体がbashまたはdashなので特に注意。 FreeBSDユーザは/bin/shの正体がashなので注意。 v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。 http://src.illumos.org/source/xref/illumos-gate/usr/src/cmd/sh/ http://heirloom.sourceforge.net/sh.html ・csh/tcshのシェルスクリプトは推奨されません。 (理由は「csh-whynot」でググれ) ・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。 manや参考リンクを見ましょう。 aproposないしはman -kでそれらしい単語による簡単な検索もできます。 ・シェルで使えるワイルドカード等は正規表現ではありません。 正規表現の話題はスレ違い(正規表現スレへ) ・シェルスクリプトのことをシェルってゆーな □初心者へのアドバイス: ・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも awkまたはperlの方が適した処理にはそちらを使いましょう。 ・知らないコマンドが出てきたらmanを引きましょう。 ・思い通りに動かないときは、まずは sh -x でトレースしましょう。 □回答者への注意事項: ・シェルスクリプトでの処理方法を質問しているのに、よくわからずに 「そういうのはperl使いましょう」と回答するのはやめましょう。 安易にperlに逃げずにシェルスクリプトで処理するのが頭のいいやり方。 前スレ シェルスクリプト総合 その25 http://echo.2ch.net/test/read.cgi/unix/1439563321/ >>485 ありがとうございます。 > 例によってSolarisにはないが、POSIXに準拠してないということで切れる。 恥かしながらSolaisってPOSIX準拠を謳っていないことを今知りました…… よくシステムコールAPIの説明で「SolaisまたはPOSIX」とありますが, その真意をようやく掴めました。 --- awkのRSにナル文字を指定できればxargsの代替として使えるかもしれないと思ったんですが, $ printf '%s\0%s\0%s' 'First' 'Second' 'Third' | awk -v RS="$(printf '\0')" '{ print $0 }' みたいなことをやっても撥ねられる (シェルがナル文字についての警告を出して,「FirstSecondThird」とだけ表示される) のでやっぱりナル区切りを扱うのはやめておこうと思いました。 大人しく空白区切り・改行レコードで行きます。 なんかこうすると上手く行った (ように見えます)。 $ printf '%s\0%s\0%s' 'First' 'Second' 'Third' | \ awk ' \ BEGIN { RS="\0" ORS="\n" } { print } \ ' なんでこれが良くて >>486 がだめなのか分からないのが怖いので結局ナル文字区切りはやめることにしました。 連投&スレ汚し失礼しました。 sedでiフラグをdフラグと一緒に使うことはできないのでしょうか。 >>489 誘導ありがとうございます。一応の解決を見ました。 hoge.sh <(cat hoge.txt fuga.txt piyo.txt) ### hoge.sh #!/bin/bash wc -l $1 # 正しい行数 wc -l $1 # なぜか0 おせーてエロいひと >>491 つ cat hoge.txt fuga.txt piyo.txt | (wc -l; wc -l) こういうhoge.shがあったとして ``` #!/bin/bash set -x for x in aa bb cc; do echo $x done ``` 実行するとこうなる ``` $ bash hoge.sh + for x in aa bb cc + echo aa aa + for x in aa bb cc + echo bb bb + for x in aa bb cc + echo cc cc ``` けどこうしたい(forやifが出力されないようにしたい) ``` $ bash hoge.sh + echo aa aa + echo bb bb + echo cc cc ``` どうしたらいい? つづき。ためしにこうしてみた ``` #!/bin/bash for x in aa bb cc; do set -x echo $x set +x done ``` 実行したら set +x も表示された(これはいらない) ``` $ bash hoge.sh + echo aa aa + set +x + echo bb bb + set +x + echo cc cc + set +x ``` echo $x の前に echo + echo $x と記述する $ cat hoge.sh #!/bin/bash for x in aa bb cc; do (set -x echo $x) done $ bash hoge.sh + echo aa aa + echo bb bb + echo cc cc なんつって >>499 > (set -x > echo $x) この方法でできました。ありがとうございます。 もっと簡潔に書けるといいのだけど。 すんませんけど 今割り当て端末数からこんな感じでサブネットマスクを出すのを作ったんですけど i=256;j=0 ; while [ ! $i -eq 1 ] ; do i=$(( $i /2 ));echo $i; j=$(($j + 1)) ; done ;echo ans:$((32 - $j)) もっとてっとり早く出すコマンドはありませんか? できれば256を入れたら8とかさっさと返してくれるような奴を あとよくわからんけど 計算で256と2を入力したら後ろの8とかを出すコマンドはないですか? 覚えるとか調べるは嫌いなんで、なるべく手間のかからないものを教えてください >覚えるとか調べるは嫌いなんで、 生きてる意味あんのか、これで? >>502 手間がかかるから面倒だよ 20万以上やるし ああ これででるのね うしろに変なゴミが付いてるがどうでもいいか :echo " l(65556)/l(2)" | bc -l 16.00044020841915062248 :echo " l(1024)/l(2)" | bc -l 10.00000000000000000010 >>503 また努力するするのが誇らしいとか思ってる馬鹿?ww 俺が考えるならこの機械とか利用価値はないよ ゲーム開発のUNITYのスレに行けば似たような奴が沢山いるよ まぁしばらくはマシーンを買う金がないからlinuxとイヤイヤ付き合うしかないが ほんと手間がかかるな >また努力するするのが誇らしいとか思ってる馬鹿?ww こんなこと考えたこともないけど 思い込みが激しいっていうか頭腐ってるだろ ああ死んでるんだったっけ >>506 そういう手間が掛かるのはちょっと… 利用価値がないし >>509 俺自体が無職だよ さて間抜けからビットコインを盗まんと >>512 予告と教唆じゃなくて実行中だよ とろくさいやつだなw http://or2.mobi/index.php?mode=image& ;file=193749.jpg http://or2.mobi/index.php?mode=image& ;file=193750.jpg 3週間たってだいぶリナックスにも慣れてきた ある程度稼がせてもらったらウインドウズに戻るよ ライブは少し使いにくい なんかシェルスクリプト総合とか書いてあったから来てみたけど しょぼそうな連中しか居ないけど… ここのひとってシステム管理とかで食ってる連中が多いの? なんか急に変なの出てきたな どっかにスレのアドレスでも貼られたのか 変と思いながら見続けて今さあながら「変だ!変だ!」と言う人って・・・ まあ相手にされるかは別にして居たいなら居ていいと思うよ >>514 面白いネタがあれば食いつくんじゃない? つまらんネタしか無いから過疎ってる。 ほんとに揃いも揃っておまえらは無能な連中だよ こんな能無し共が良いかねを取って裕福な生活をしてるのに 何で俺がしこしこビットコインを盗まんとならんのか…… よしよしw 今日はあがりはデカそうだな 1111 2222 3333 という内容のファイルに対して, • 3333 が見付かれば 3333 を, • 見付からなければ 2222 を • ⋮ という操作を施したいです。そして,これをパイプに繋ぎたいです。 私が考えたのは↓のスクリプトですが, for q in 3333 2222 1111; do cat <<-'EOF' | 1111 2222 3333 EOF grep $q && break done 難点があります。 1. パイプでファイルを渡せない。 2. 順番に依存している (実際のファイルでは 3333 が最後にくるとは限らない) どうか助言願います あ,すいません。期待する動作は, かりに理想のスクリプトを idea.sh として, $ cat ./org.txt 2222 3333 1111 $ cat ./org.txt | idea.sh 3333 $ cat ./org.txt | sed -e '/3333/d' | idea.sh 2222 $ cat ./org.txt | sed -e '/3333/d' -e '/2222/d' | idea.sh 1111 という感じです。 標準入力を受け取れるように作ればいいんじゃないの? idea.sh sed -e "/$1/d" < /dev/stdin $ cat ./org.txt | ./idea.sh ‘3333’ | ./idea.sh ‘2222’ | ./idea.sh ‘1111’ awk使うのが妥当。 awkが嫌なら、標準入力をファイルにコピーしてから複数回に分けて処理するしかないな。 やりたい事はシンプルなのに標準入力使おうとしてるせいで妙に面倒になってるな awkかgrepでよさそうだが $PATHの中身って最初は空じゃないの? $PATHをechoしてみたら,その中に ~/.bashrcや~/.bash_profileでexportされてるパス以外のモノが含まれてた でも$PATHに初期値を設定できるならわざわざ~/.bashrcや~/.bash_profileでexportする必要なくない? どうなってるのか教えてくれ OSによるけどinit.dの中とかlogin.confとかでデフォルトを設定する。 ここ書き換えると全ユーザに影響が出るので、個別設定は.bash_profileとかに書く。 exportするのは万一PATHなしで起動されてしまったとき用。 >>501 > すんませんけど 今割り当て端末数からこんな感じでサブネットマスクを出すのを作ったんですけど ipcalcコマンドで行けるんじゃね? 知ってるだけで使ったことないけど 他にもiptabとかipcountとかあるらしいな >>522 最初に自身で書いてたようなんで十分じゃないの? パイプで渡せないというのが何を嫌がってんのかによるけど テキストなら貯めてechoしたっていいんじゃ DATA="$(cat -)" && cat $KEYWORDFILE | while read KEYWORD ; do ( echo "$DATA" | grep "$KEYWORD" ) && break ; done データでかいから捜査対象の方を1パスで捜査したいってことなら シェルスクリプトでがんばるより別のことでがんばろう >>530 ありがとやっと有益なレスが出たよ 他のやつは揃いも揃って無能な役立たずばっかりだから ショッアーーーーーーーーー!!! さってビットコインを盗むか アホにレスした俺もアホだった。 やっぱアホはスルーに限る。 >>530 俺も普通は ipcalc 使ってるけど最近は sipcalc というのもあるらしい。 紹介してくれてる iptab とか ipcount 含めて今度試してみようと思う シェルスクリプトの函数で扱える文字数に上限はないのでしょうか。 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_05 ↑ここが多分公式の文書だと思うのですが,使用可能な文字の種類に言及こそすれ,文字数については触れていないように思いますが…… ファイル名などの上限と同じく255文字でしょうか? >>536 255文字かどうかは、質問するまでもなくすぐにわかると思いますよ。 $ :> "$(yes a | head -n 255 | tr -d '\n')" $ :> "$(yes a | head -n 256 | tr -d '\n')" sh: 1: cannot create aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa: File name too long ファイル名の文字数上限はファイルシステムに依存する シェルスクリプトで有るコマンドを実行した時、 標準出力の内容を緑に、標準エラー出力の内容を 赤にしたいんだけどどうすればいい? 本当に聞きたいことはエスケープシーケンスではなく、 標準出力と標準エラーをそれぞれ別々に加工する方法ね それがないんだよね。標準エラー出力を標準出力に 変えてしまうのは有るけど、それじゃ別々にやるのは不可能だし 条件が厳しいからどうしてもシェルスクリプトでやりたいなら 先ずシェルを作るところから始めないといけない 出力を切り離してパイプで別々のコマンドでフィルタする程度じゃ全然駄目だから こういうのを簡単にできると言い切る人はきっとものすごく優秀な頭脳の持ち主だと思う これは書いていなかった俺が悪いんだが、 bashやzshを使わずにposixの範囲でやりたいんだよね。 少なくともdashやashで動くものがほしい でその方法が実際にあることは知ってるんだけど、 もっとシンプルな方法はないのだろうかと言うのと 俺がその方法をここに書いちゃうと 身バレしちゃうので書かなかった >>548 > 出力を切り離してパイプで別々のコマンドでフィルタする だけやぞ POSIXに準拠したい気持は分かるけど,一次ファイルを作らないっていう謎の拘りが理解できない。 両立させるのは厳しいと思う。もうさ, tempf="$(printf '%s%s%s%s' '/tmp/' "$(date +"%y%m%d%H%M%S")" '.' "$$")"; somecmd 2> "${tempf}" | \ printf '\e[1;32m%s\e[0m\n\e[1;31m%s\e[0m\n' "$(cat)" "$(cat "${tempf}")"; rm -rf "${tempf}" でいいでしょ。もちろんPOSIX準拠。 あと偉そうなこと言うが,「身バレが怖いから持ってる (有益かもしれない) 情報を明かしません」って, こっちからするとかなり不快だから,黙って何も知らないふりをしておいたほうがまだマシだよ。 落ち着け 最初の質問の時点で性格の幼稚さは見え透いてるだろ >>551 > 一次ファイルを作らないっていう謎の拘りが理解できない。 書いてなかったのが悪いんだろうけど、一時ファイルを使うと ストリーミングで処理できなくなるんだよ つまり前のプログラムの出力が完了しないと次のプログラムが動かない POSIX準拠はbusyboxで動かす必要があるからこれも必須 この二点は今回の質問には直接関係ないから理由じゃなくて制約として書いた そしてこっちの方で回答きたよ くだらねえ質問はここに書き込め!Part 230 https://mao.5ch.net/test/read.cgi/linux/1515383155/315 同じ文章なのになんでこう反応が違うんだろうね 同じ文章なんだからレスする側の問題があるだろうね 質問する側と回答する側、立場は対等だって言ったら怒りそう >>551 あとmktemp使ったほうが良いよ。 なんでぜったいにかぶらない方法があるのに 自分でなるべくかぶらないように努力するんだろう 結構多いよね。mktemp使ったほうがコード短くなるのに 自分自身は何もしてないのになぜこうも態度をでかくできるのか 別にでかくないでしょw ほかの人と一緒。 質問したからといってへりくだる必要はないと思ってるだけ 無知でもないしね マルチカスか 教えたがりを徹底的にこき使っとけ ここには二度とくるなよ 聞く側はこういう態度を取らないといけないって 体育会系とか年功序列とか年上は敬え的な考え方だよ 今時はやらない >>555 のそれ「解答」じゃないじゃん。 無理って言われてるんだぞ? 理解できてる? どういう態度取るべきとは思わないけど、 相手を不快にさせたら得られるはずの回答も得られなくなる可能性が上がるよ。 それでよければご自由に。 出力が色制御してきたら取り除いたりとか、マルチプロセスとかで変なところでブッタ斬り/ミックスされないように同期取ったりとか考えてたけど俺には無理だからもういいや >>563 やりたいこと > 標準出力の内容を緑に、標準エラー出力の内容を > 赤にしたいんだけどどうすればいい? 標準出力の内容を緑にする・・・簡単 標準エラー出力の内容を赤にする・・・? >>555 で明らかになったこと ・・・ 標準出力と標準エラー出力を入れ替える方法 ここから標準エラー出力の内容を赤にするには 標準出力と標準エラー出力を入れ替えれて 処理すればいいって気づくよね? >>567 ん? それだと今度は標準出力が (標準エラー出力に複製されたので) パイプを通らなくなるから、 標準出力の内容 (今は標準エラー出力に出力されている) を緑にできないんじゃ? もしかして同時じゃなくていいってこと? もうほっとけ 標準出力、標準エラー出力に関する便利な小ネタでも教えてやろうかと思ったけどやめとくわ >>568 片方ずつしか処理できないなら、 2回やれば両方できるだろ? っていうかそれぐらいわかるだろw >>569 > 標準出力、標準エラー出力に関する便利な小ネタでも教えてやろうかと思ったけどやめとくわ おせーておせーて |& ←このパイプは標準出力標準エラー出力ともに通すよ。 ただ質問者さんが望んでいるのは「標準出力か標準出力かが区別できる状態でのパイプ通過」だろうから、 それはちょっと無理なんじゃないかな。 あと態度がデカすぎる。一度死んだほうがいいと思う。 >>570 まさかコマンド二回回すの? 標準出力と標準エラー出力分ける為だけに? それ一時ファイル作るより余程冗長だぞw もう一度シェルっていうかコンピュータの仕組みを勉強しなおしてきな だから一時ファイルを作るとストリーミングに できなくなるからだめなんだって さっきも書いたろ >>572 やっぱり>>555 が今のところ一番シンプルな解みたいだね。 てか、標準出力と標準エラー出力を別々にファイルに吐き出せるんだから、 別々のプログラムにパイプでつなげられる機能があっても良いと思うんだけどね 君たぶんだけど意思疎通に係わる障害持ってるから病院で診てもらったほうがいいよ。 知り合いにそういう調子の会話する人がいて、ある日会社で大きな事件を起こして辞めさせられたあと 病院で検査したらそういう系統の精神病だったからさ。 煽りとかじゃなくて、君はどうも社会で孤立してそうだから、助けになりたい。 いや、おちょくってるだけだろ まともに相手するだけ無駄やぞ ここに限らず、質問系のスレにたまに沸くアレでしょ 5chが過疎って最近あんま見てなかったから なんか懐かしい感じするわw あっちで粘着してるみたいだな 久々にアレな奴を見たわ 入力リダイレクトで複数ファイルを一度で流し込むのはどうしたら良いのですか? よろしくお願いします。 mac で bashです。 mdfindからパイプつないだ先でcpしたら 検索が間に合わなかったのかコピーし損ねがでてきます。 再度コピーしそこねたファイル名リストを同じようにこれに掛けると、 幾つか成功していくつかはコピーし損ねます。 function readMdfind() { while read LINE; do mdfind "kMDItemFSName == "${LINE}" || kMDItemDisplayName == "${LINE%.*}"" | awk 'NR==1' | xargs -J % cp -p "%" "$1" 2>/dev/null done <${2} 引数の1はファイル名のリストが入ったテキストで、2はコピー先のフォルダになります。 ファイル名は殆どが一意にしてあるので、とりあえずヒットしたら良い感じです。 一度で取りこぼしのない良い方法はありませんでしょうか。 引数の件1と2逆でした 惑わせてしまい申し訳ありません。 正しくは1がコピー先フォルダで2がファイル名のリストです。 >>582 回答ありがとうございます。 ということはそのまま cat hoge huga | command で、いいってことですか。なるほど。 レスつくまで色々ググって調べてみたのですが command <( cat hoge huga ) でも全く同じ動作ですか? >>585 二番目の方法,たぶんコマンドラインで試して成功したから書き込んでるんだろうけど, それはプロセス置換と言って Bash筆頭に幾つかのシェルの独自拡張だからシェルスクリプトにするときは シェバンを #! /usr/bin/env bash か #! /bin/bash とかにする必要がある。 cat hoge huga | somecommand で代替できることに可搬性を犠牲にするのは避けたいだろうから (つまり #! /bin/sh というシェバンを捨てるのは勿体無いということ) <(cat hoge huga) は避けれる時は (特にシェルスクリプトで使う時) 避けといたほうがいいんじゃないかな。 ■ このスレッドは過去ログ倉庫に格納されています
read.cgi ver 07.5.5 2024/06/08 Walang Kapalit ★ | Donguri System Team 5ちゃんねる