シェルスクリプト総合 その22
レス数が1000を超えています。これ以上書き込みはできません。
0001名無しさん@お腹いっぱい。
2013/11/01(金) 07:58:50.52□お約束
・特記なき場合は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.opensolaris.org/source/xref/onnv/onnv-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に逃げずにシェルスクリプトで処理するのが頭のいいやり方。
前スレ
シェルスクリプト総合 その21
http://toro.2ch.net/test/read.cgi/unix/1352973453/
0942名無しさん@お腹いっぱい。
2014/06/25(水) 23:51:38.160943名無しさん@お腹いっぱい。
2014/06/26(木) 00:07:16.26おおわざわざ解説ありがとう
やっぱシンプルかつ欲しい情報が的確に手に入る感じで好きだなこれ
0944名無しさん@お腹いっぱい。
2014/06/26(木) 00:12:19.21その点が明示されてないから好きにやれよとね
0945名無しさん@お腹いっぱい。
2014/06/26(木) 00:14:13.890946名無しさん@お腹いっぱい。
2014/06/26(木) 01:03:51.25とは言え、頭に D(uplicate)、S(kip)を付けただけだけど
$ cat a.txt | pee \
"uniq -d | sed -r 's/.+/D &/'" \
'uniq | awk '\''NR!=$1{list="S";for(i=NR;i<$1;i++){list = list " " i};print list;NR=$1++}'\'''
0947名無しさん@お腹いっぱい。
2014/06/26(木) 02:16:29.93>>854といい>>909といい、フィールド抽出だけにしか使ってなかったawkがこうまで活躍するとは思わなんだ
0948名無しさん@お腹いっぱい。
2014/06/26(木) 02:25:28.730949名無しさん@お腹いっぱい。
2014/06/26(木) 02:48:31.760950名無しさん@お腹いっぱい。
2014/06/26(木) 20:57:17.170951名無しさん@お腹いっぱい。
2014/06/26(木) 22:40:09.500952名無しさん@お腹いっぱい。
2014/06/26(木) 22:42:34.98大きな数はまともに足し算すらできないawkが何だって?
0953名無しさん@お腹いっぱい。
2014/06/26(木) 22:43:26.490954909
2014/06/26(木) 23:46:34.93>>884や>>909をa2pに掛けてみたけど、やっぱり読みにくい。
rubyやpythonだと見た目よくなるの?
0955名無しさん@お腹いっぱい。
2014/06/26(木) 23:59:19.6911,A,あ,12,B,い,13,C,う
↑みたいなCSV形式のテキストがあるのですが、これを
1,a,あああ
2,b,いいい
3,c,ううう
11,A,あ
12,B,い
13,C,う
と、カンマ区切りの3列毎に改行させたく思ってます
今はawkを使い$1〜$9として取り出して、printfで$1","$2","$3;みたいに処理させてるのですが
かなり冗長な感じで、個人的に気に入ってません
何かいい方法ありますでしょうか
0956名無しさん@お腹いっぱい。
2014/06/27(金) 00:04:54.49クォート処理から解放される
0957名無しさん@お腹いっぱい。
2014/06/27(金) 00:42:46.87じきに埋まりそうだが
0958名無しさん@お腹いっぱい。
2014/06/27(金) 00:46:17.58/6; s/,/\
/3'
ちょっと手元に検証環境がないから間違ってたらだれか修正してくれ
0959名無しさん@お腹いっぱい。
2014/06/27(金) 01:25:56.61955です
期待通り動作しました!!
ありがとうございます
sedの仕様等しらべて、動作原理を把握しようと思います…
0960名無しさん@お腹いっぱい。
2014/06/27(金) 01:33:49.62/n ←n番目の","を改行に置換する
まず6番目置換して、次に3番目を置換。
順番逆だとうまく動かないから気を付けてな
0961名無しさん@お腹いっぱい。
2014/06/27(金) 03:24:34.120962名無しさん@お腹いっぱい。
2014/06/27(金) 08:13:10.13sed -e 's/,/\n/3; P; D'
0963名無しさん@お腹いっぱい。
2014/06/27(金) 08:32:22.50動作遅くなる印象がある
検証してないから実は早いかもしれんけど、綺麗さ考えてもなるべくsedは1回で終わらせたいな
0964名無しさん@お腹いっぱい。
2014/06/27(金) 08:34:49.66sedでlispを実装した剛のものがいる。
https://github.com/shinh/sedlisp
0965名無しさん@お腹いっぱい。
2014/06/27(金) 08:40:29.48おお、こんなの知らなんだ。これはイディオムになってるのか?
0966名無しさん@お腹いっぱい。
2014/06/27(金) 08:44:13.06昔のCPUではsedを複数パイプでつなぐと遅かったが、
今のマルチコア(スレッド)のCPUだとsed複数をパイプでつないだ方が(それぞれ別CPUコアで実行されるので)速くなる。
わざわざsedひとつにまとめるとかえって遅くなるので注意。
0967名無しさん@お腹いっぱい。
2014/06/27(金) 12:10:12.50頭おかしいとか褒められてるしw
で、書き上げた後の感想がw
> 正直疲れたんで s/// 以外の sed script 書くのやめようかと思いますね
やっぱり、goto 文相当しかないし、きついよね。
深入りしない方が吉って事かな?とかいいつつ、sedlisp.sed 保存
>>965 ちょw イディオムってw てれるなー。ただ考えながらコマンド並べただけ
たぶん引っかかるのは、d と D や s/.*\n// の違いとかでしょ?
>>957 いつもぎりぎり。ってか埋まってから次スレとかもある
0968名無しさん@お腹いっぱい。
2014/06/27(金) 12:46:39.33lispはさすがに変態だとは思うが
さっと検索したらsedスレもあるな
スレタイシンプルすぎて笑ったw
0969名無しさん@お腹いっぱい。
2014/06/27(金) 12:55:52.08info sed の Examples/uniq とかみたら
> As you can see, we mantain a 2-line window using `P' and `D'. This
> technique is often used in advanced `sed' scripts
とかあるから、イディオムかって言えば、そうかもね
0970名無しさん@お腹いっぱい。
2014/06/27(金) 13:50:32.44ニコニコ動画の投稿者コメント(ニワン語)とか、
エロゲスクリプト環境のNScriptとかでlisp実装した変態もいる
lispを変な環境で実装する、というのはlisperにとってある種の習性なのかもしれない
0971名無しさん@お腹いっぱい。
2014/06/27(金) 14:44:29.63grep -o '[^,]\+,[^,]\+,[^,]\+'
0972名無しさん@お腹いっぱい。
2014/06/28(土) 01:22:09.24目から鱗だわ
grepやりおる
0973名無しさん@お腹いっぱい。
2014/06/28(土) 08:31:21.71awk '{print RT}' RS="([^,]+,){2}[^,]+"
と思ったが、ヌルのフィールドがあるとうまくいかん
0974名無しさん@お腹いっぱい。
2014/06/28(土) 22:33:32.71すげー
だけどなぜ3つずつで改行されるのかわかりません(><)
アホなおれに原理を教えて誰かエロイ人
0975名無しさん@お腹いっぱい。
2014/06/28(土) 23:06:59.94[^,] が ',' 以外の任意の文字一つ
その後に "\+" で1つ以上ありったけ
その右にある','が1つ目の','
以下同文
1,a,あああ,2,b,いいい,3,c,ううう
には、まず
1,a,あああ がマッチする
-o オプションの説明通りにそのマッチしたのを出力した後、次に
2,b,いいい がマッチする
以下同文
0976名無しさん@お腹いっぱい。
2014/06/28(土) 23:49:55.98123abc456
という行にgrep -o [0-9] とかやると、
1
2
3
4
5
6
とかなる
0977名無しさん@お腹いっぱい。
2014/06/30(月) 16:33:37.27自然数の数値を与えると、2^10で割ってB,K,M...の単位を付与する仕組みを考える。
例)
入力:1000 出力:1000B
入力:1000000 出力:976.5K
入力:1000000000 出力:953.6M
・出力の小数点第一位以降は切り捨て
・対応単位はB, K, M, G, T
・入力方法は不問。$1に入ってるよとかでもいい
0978名無しさん@お腹いっぱい。
2014/06/30(月) 16:55:13.030979名無しさん@お腹いっぱい。
2014/06/30(月) 16:58:10.85n="$1"0
set B K M G T
while (($n / 1024 >= 10)); do shift; ((n /= 1024)); done
case $((n % 10)) in
0) echo $((n / 10))$1;;
*) echo $((n / 10)).$((n % 10))$1;;
esac
0980名無しさん@お腹いっぱい。
2014/06/30(月) 16:58:57.49板的にはBKMのBはBlock
0981名無しさん@お腹いっぱい。
2014/06/30(月) 17:19:13.47今回はバイトと思ってくれorz
>>979
早速ありがとう。分かりやすくて無駄がないな
setとshift活用する手段は思いつかなかった…配列使うことしか頭になかったわ
0982名無しさん@お腹いっぱい。
2014/06/30(月) 17:23:15.08そんな決まりないよ。
0983名無しさん@お腹いっぱい。
2014/06/30(月) 21:38:33.06罰種胃損はイカンなぁ。純正シェルで書こうな。
#!/bin/sh
n="$1"0
set B K M G T
while [ "$n" -ge 10240 ]; do shift; n=`expr "$n" / 1024`; done
f=`expr "$n" % 10`
n=`expr "$n" / 10`
case $f in 0) echo $n$1;; *) echo $n.$f$1;; esac
0984名無しさん@お腹いっぱい。
2014/07/01(火) 00:56:36.07ls -lh /tmp/hoge.$$ | awk '$0=$5'
rm -f /tmp/hoge.$$
0985名無しさん@お腹いっぱい。
2014/07/01(火) 08:37:43.26ジョークで書いてるんだろうけど滅茶苦茶無駄な上に、1Kバイト未満の時 B の単位が付かないからNG
0986名無しさん@お腹いっぱい。
2014/07/01(火) 10:58:43.15純正シェルで利用できるシェル変数は$aから$m, 制御構文は
if/switch/while/goto/exitだけ, コマンド置換(`command`)は無い。
失格
0987名無しさん@お腹いっぱい。
2014/07/01(火) 11:05:05.540988名無しさん@お腹いっぱい。
2014/07/01(火) 12:41:53.89http://www.in-ulm.de/~mascheck/bourne/v7/
http://heirloom.sourceforge.net/sh/sh.1.html#4
>>977 GNU coreutils で小数点とかの指定がダメなのですが、
numfmt --to=iec --suffix B "$1"
伝統的に SI units を流用して2進接頭辞を表していたけど、いつのまにか
IEC units を使ってないのは、日本だけって事に成りません様に
メビバイト MiB とか、まだまだ若いし、頭が固くないし、完全拒否とかはない。余裕。汗
0989名無しさん@お腹いっぱい。
2014/07/01(火) 12:45:47.540990名無しさん@お腹いっぱい。
2014/07/01(火) 13:07:30.36bourneシェルの中でもV1-V6はコマンドラインインタプリタとしての
機能しかもっていないので、本スレでは対象外
プログラミング可能な制御構造を導入したPWBシェルでも動作可能なことが純正シェル道
http://www.in-ulm.de/~mascheck/bourne/PWB/
0991名無しさん@お腹いっぱい。
2014/07/01(火) 13:31:46.640992名無しさん@お腹いっぱい。
2014/07/01(火) 13:51:27.90#!/bin/sh
で動く範囲ならOK?
0993名無しさん@お腹いっぱい。
2014/07/01(火) 14:01:06.07それじゃ/bin/shが実際何なのかわからん。
0994名無しさん@お腹いっぱい。
2014/07/01(火) 14:24:32.56まあ、個人的には誰しも、どーでもいいと思うだろう
だけど、色々な環境が有って、>>1でお約束を決めるに至った事を考えると、そうも思えない
>>992
ここは、総合。明示すればどんなシェルもOK
$ ls -l /bin/sh
/bin/sh -> dash
とかなってれば/bin/dashとか書けばいいし、少し調べてPOSIXシェルでとかでもいい
0995名無しさん@お腹いっぱい。
2014/07/01(火) 14:26:17.930996名無しさん@お腹いっぱい。
2014/07/01(火) 14:28:04.05誰かが勝手に付け加えてっただけだろう。
>>994
シンボリックリンクかどうか見ただけじゃ不十分。
シンボリックリンクになってなくてもOS違えば挙動が変わる。
0997名無しさん@お腹いっぱい。
2014/07/01(火) 14:35:51.47あくまでもelseで落ちてきたシェルだけがここというのは?
0998名無しさん@お腹いっぱい。
2014/07/01(火) 14:40:48.560999名無しさん@お腹いっぱい。
2014/07/01(火) 14:57:35.22それで、不十分だから >>996 は明示の仕方について異論が有るのか?
>>1ではシェルを明示すればいい様だが
1000名無しさん@お腹いっぱい。
2014/07/01(火) 15:08:14.47どのシェルかわかるように明示してくれればそれでいいよ。
10011001
Over 1000Threadもう書けないので、新しいスレッドを立ててくださいです。。。
レス数が1000を超えています。これ以上書き込みはできません。