トップページunix
1001コメント297KB

シェルスクリプト総合 その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/
0949名無しさん@お腹いっぱい。2014/06/26(木) 02:48:31.76
awkすごいな あこがれちゃうな
0950名無しさん@お腹いっぱい。2014/06/26(木) 20:57:17.17
それほどでもない
0951名無しさん@お腹いっぱい。2014/06/26(木) 22:40:09.50
お前などperlに変えてやる a2p
0952名無しさん@お腹いっぱい。2014/06/26(木) 22:42:34.98
整数型を持たず浮動小数点で数扱ってるせいで
大きな数はまともに足し算すらできないawkが何だって?
0953名無しさん@お腹いっぱい。2014/06/26(木) 22:43:26.49
お前よりは有能だよ
09549092014/06/26(木) 23:46:34.93
>>883のお題がたまたまawkにぴったりだったということで。
>>884>>909をa2pに掛けてみたけど、やっぱり読みにくい。
rubyやpythonだと見た目よくなるの?
0955名無しさん@お腹いっぱい。2014/06/26(木) 23:59:19.69
1,a,あああ,2,b,いいい,3,c,ううう
11,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
cvsならVBA
クォート処理から解放される
0957名無しさん@お腹いっぱい。2014/06/27(金) 00:42:46.87
そういやこのスレのやり方よく知らないんだけど、次スレはいつ立てるん?
じきに埋まりそうだが
0958名無しさん@お腹いっぱい。2014/06/27(金) 00:46:17.58
sed 's/,/\
/6; s/,/\
/3'
ちょっと手元に検証環境がないから間違ってたらだれか修正してくれ
0959名無しさん@お腹いっぱい。2014/06/27(金) 01:25:56.61
>>958
955です

期待通り動作しました!!
ありがとうございます

sedの仕様等しらべて、動作原理を把握しようと思います…
0960名無しさん@お腹いっぱい。2014/06/27(金) 01:33:49.62
s/,/\
/n  ←n番目の","を改行に置換する
まず6番目置換して、次に3番目を置換。
順番逆だとうまく動かないから気を付けてな
0961名無しさん@お腹いっぱい。2014/06/27(金) 03:24:34.12
cat filename | sed 's/,/\ /3' | sed 's/,/\ /3' これを繰り返すのはだめなのかな。3と6で数字を2つも使うのがなんとも言えなくて スクリプト詳しくないから、何か問題があったら教えて欲しいです
0962名無しさん@お腹いっぱい。2014/06/27(金) 08:13:10.13
これでどうかな。繰り返してくれるよ
sed -e 's/,/\n/3; P; D'
0963名無しさん@お腹いっぱい。2014/06/27(金) 08:32:22.50
sedって大容量ファイルに弱いイメージあるから、パイプでsedを何回もつなげるのって
動作遅くなる印象がある
検証してないから実は早いかもしれんけど、綺麗さ考えてもなるべくsedは1回で終わらせたいな
0964名無しさん@お腹いっぱい。2014/06/27(金) 08:34:49.66
>>948
sedでlispを実装した剛のものがいる。
https://github.com/shinh/sedlisp
0965名無しさん@お腹いっぱい。2014/06/27(金) 08:40:29.48
>>962
おお、こんなの知らなんだ。これはイディオムになってるのか?
0966名無しさん@お腹いっぱい。2014/06/27(金) 08:44:13.06
>>963
昔のCPUではsedを複数パイプでつなぐと遅かったが、
今のマルチコア(スレッド)のCPUだとsed複数をパイプでつないだ方が(それぞれ別CPUコアで実行されるので)速くなる。
わざわざsedひとつにまとめるとかえって遅くなるので注意。
0967名無しさん@お腹いっぱい。2014/06/27(金) 12:10:12.50
>>964 す、すごいな。全体で591行は、思いのほか短いな
頭おかしいとか褒められてるしw

で、書き上げた後の感想がw
> 正直疲れたんで s/// 以外の sed script 書くのやめようかと思いますね

やっぱり、goto 文相当しかないし、きついよね。
深入りしない方が吉って事かな?とかいいつつ、sedlisp.sed 保存


>>965 ちょw イディオムってw てれるなー。ただ考えながらコマンド並べただけ
たぶん引っかかるのは、d と D や s/.*\n// の違いとかでしょ?

>>957 いつもぎりぎり。ってか埋まってから次スレとかもある
0968名無しさん@お腹いっぱい。2014/06/27(金) 12:46:39.33
sedも使い慣れるとほんとなんでもできるよな
lispはさすがに変態だとは思うが

さっと検索したらsedスレもあるな
スレタイシンプルすぎて笑ったw
0969名無しさん@お腹いっぱい。2014/06/27(金) 12:55:52.08
967 です
info 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
lispは神言語だから、様々な環境上で再現されている
ニコニコ動画の投稿者コメント(ニワン語)とか、
エロゲスクリプト環境のNScriptとかでlisp実装した変態もいる

lispを変な環境で実装する、というのはlisperにとってある種の習性なのかもしれない
0971名無しさん@お腹いっぱい。2014/06/27(金) 14:44:29.63
>>955
grep -o '[^,]\+,[^,]\+,[^,]\+'
0972名無しさん@お腹いっぱい。2014/06/28(土) 01:22:09.24
>>971
目から鱗だわ
grepやりおる
0973名無しさん@お腹いっぱい。2014/06/28(土) 08:31:21.71
それならGNU awkでも
awk '{print RT}' RS="([^,]+,){2}[^,]+"
と思ったが、ヌルのフィールドがあるとうまくいかん
0974名無しさん@お腹いっぱい。2014/06/28(土) 22:33:32.71
>>971
すげー
だけどなぜ3つずつで改行されるのかわかりません(><)
アホなおれに原理を教えて誰かエロイ人
0975名無しさん@お腹いっぱい。2014/06/28(土) 23:06:59.94
>>971
[^,] が ',' 以外の任意の文字一つ
その後に "\+" で1つ以上ありったけ
その右にある','が1つ目の','
以下同文

1,a,あああ,2,b,いいい,3,c,ううう
には、まず
1,a,あああ がマッチする
-o オプションの説明通りにそのマッチしたのを出力した後、次に
2,b,いいい がマッチする
以下同文
0976名無しさん@お腹いっぱい。2014/06/28(土) 23:49:55.98
grep の -o オプションは、マッチした行じゃなくマッチした箇所を全部表示する
123abc456
という行に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.03
すまん、切り捨てるのは第二位以下だな
0979名無しさん@お腹いっぱい。2014/06/30(月) 16:58:10.85
>>977
n="$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
B=バイトのつもりだろうけど
板的にはBKMのBはBlock
0981名無しさん@お腹いっぱい。2014/06/30(月) 17:19:13.47
Oh...
今回はバイトと思ってくれorz

>>979
早速ありがとう。分かりやすくて無駄がないな
setとshift活用する手段は思いつかなかった…配列使うことしか頭になかったわ
0982名無しさん@お腹いっぱい。2014/06/30(月) 17:23:15.08
>>980
そんな決まりないよ。
0983名無しさん@お腹いっぱい。2014/06/30(月) 21:38:33.06
>>979
罰種胃損はイカンなぁ。純正シェルで書こうな。

#!/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.07
dd if=/dev/zero of=/tmp/hoge.$$ bs=1 count=$1 2>/dev/null
ls -lh /tmp/hoge.$$ | awk '$0=$5'
rm -f /tmp/hoge.$$
0985名無しさん@お腹いっぱい。2014/07/01(火) 08:37:43.26
>>984
ジョークで書いてるんだろうけど滅茶苦茶無駄な上に、1Kバイト未満の時 B の単位が付かないからNG
0986名無しさん@お腹いっぱい。2014/07/01(火) 10:58:43.15
>>983
純正シェルで利用できるシェル変数は$aから$m, 制御構文は
if/switch/while/goto/exitだけ, コマンド置換(`command`)は無い。

失格
0987名無しさん@お腹いっぱい。2014/07/01(火) 11:05:05.54
純正シェル道は奥が深いな。
0988名無しさん@お腹いっぱい。2014/07/01(火) 12:41:53.89
>>986 純正師江留道秘伝書第七巻を見ると、コマンド置換はあるようです
http://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.54
純正の意味はわからんけど、ボーンシェルならいいのでは
0990名無しさん@お腹いっぱい。2014/07/01(火) 13:07:30.36
>>988,989
bourneシェルの中でもV1-V6はコマンドラインインタプリタとしての
機能しかもっていないので、本スレでは対象外

プログラミング可能な制御構造を導入したPWBシェルでも動作可能なことが純正シェル道
http://www.in-ulm.de/~mascheck/bourne/PWB/
0991名無しさん@お腹いっぱい。2014/07/01(火) 13:31:46.64
純正とか割とどーでもいい
0992名無しさん@お腹いっぱい。2014/07/01(火) 13:51:27.90
よく分からんな
#!/bin/sh
で動く範囲ならOK?
0993名無しさん@お腹いっぱい。2014/07/01(火) 14:01:06.07
>>992
それじゃ/bin/shが実際何なのかわからん。
0994名無しさん@お腹いっぱい。2014/07/01(火) 14:24:32.56
>>991
まあ、個人的には誰しも、どーでもいいと思うだろう
だけど、色々な環境が有って、>>1でお約束を決めるに至った事を考えると、そうも思えない

>>992
ここは、総合。明示すればどんなシェルもOK
$ ls -l /bin/sh
/bin/sh -> dash
とかなってれば/bin/dashとか書けばいいし、少し調べてPOSIXシェルでとかでもいい
0995名無しさん@お腹いっぱい。2014/07/01(火) 14:26:17.93
おれもどうでもいいんだけど、一部求道者がいるのよね。
0996名無しさん@お腹いっぱい。2014/07/01(火) 14:28:04.05
>>1を決めた経緯なんてそんなたいしたもんあったっけ。
誰かが勝手に付け加えてっただけだろう。

>>994
シンボリックリンクかどうか見ただけじゃ不十分。
シンボリックリンクになってなくてもOS違えば挙動が変わる。
0997名無しさん@お腹いっぱい。2014/07/01(火) 14:35:51.47
専用スレがあるシェルはそっちに行ってもらって
あくまでもelseで落ちてきたシェルだけがここというのは?
0998名無しさん@お腹いっぱい。2014/07/01(火) 14:40:48.56
却下します。
0999名無しさん@お腹いっぱい。2014/07/01(火) 14:57:35.22
>>996 確かに変わるな
それで、不十分だから >>996 は明示の仕方について異論が有るのか?
>>1ではシェルを明示すればいい様だが
1000名無しさん@お腹いっぱい。2014/07/01(火) 15:08:14.47
>>999
どのシェルかわかるように明示してくれればそれでいいよ。
10011001Over 1000Thread
このスレッドは1000を超えました。
もう書けないので、新しいスレッドを立ててくださいです。。。
レス数が1000を超えています。これ以上書き込みはできません。