シェルスクリプト総合 その22
■ このスレッドは過去ログ倉庫に格納されています
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/
0095名無しさん@お腹いっぱい。
2013/12/27(金) 13:48:23.630096名無しさん@お腹いっぱい。
2013/12/27(金) 14:02:56.75http://developer.android.com/sdk/index.html
0097名無しさん@お腹いっぱい。
2013/12/27(金) 15:10:37.860098名無しさん@お腹いっぱい。
2013/12/27(金) 15:11:17.22付録狙いで買ってくる
0099名無しさん@お腹いっぱい。
2013/12/27(金) 15:17:46.670100名無しさん@お腹いっぱい。
2013/12/27(金) 15:38:28.36ありがとうございます。いま環境がないので姉が帰ってきたら試してみます。
0101名無しさん@お腹いっぱい。
2013/12/27(金) 17:31:10.290102名無しさん@お腹いっぱい。
2013/12/28(土) 13:09:48.31こいつはsshクライアントなんだが、デフォルトだとプロトコルsshって
表示されてるとこでプロトコルlocalを選ぶと、Androidの
一般ユーザー権限でシェルが使えるので。
0103名無しさん@お腹いっぱい。
2013/12/28(土) 13:10:20.830104名無しさん@お腹いっぱい。
2013/12/28(土) 13:22:08.91iOSならネタになるかな?
iOSの公式ストアにあるアプリで、ローカルのシェルが使える奴ってある?
0105名無しさん@お腹いっぱい。
2013/12/28(土) 13:28:06.540106名無しさん@お腹いっぱい。
2013/12/28(土) 13:50:33.34だいぶ厳しい。(grepは入ってる)
でもシェルはkshで行編集やファイル名補完は効くぞ。
なぜかmoreがあるなあと思ったら、これksh組み込みの奴だったのね。
0107名無しさん@お腹いっぱい。
2014/01/11(土) 12:07:28.33それをforループで処理させたい思っており、現在はこんな感じのスクリプト作ってます
OSはCentOS、シェルはbashです
#!/bin/sh
for STR in `4バイトごとに切り取る処理`
do
hogehoge $STR
done
この「4バイトごとに切り取る処理」ですが、現在はsplitで4バイト単位に切り取り、
分割後のファイルを順次読み込ませるということにしているのですが、
分割後のファイルが沢山作られるので遅くなり、またやりたい事の割にやってることが
複雑すぎるので、なんとか改善したいと思ってます
そういうことをしてくれる、いい方法はありますでしょうか
標準出力を、指定したバイト数単位にセパレータを挟んで出力してくれるコマンド、みたいな
cutでやってみようと思ったのですが、これだとオフセットを4バイトずつずらしながら
切り出していく処理となりそうで、これもまた複雑だなぁ、と…
0108名無しさん@お腹いっぱい。
2014/01/11(土) 12:14:05.590109名無しさん@お腹いっぱい。
2014/01/11(土) 12:38:48.750110名無しさん@お腹いっぱい。
2014/01/11(土) 13:01:14.29>>108
なるほどreadでやるのですね
バイト数も任意で変更できそうで、柔軟性もありますね
ありがとうございました
0111名無しさん@お腹いっぱい。
2014/01/11(土) 13:41:30.36つfold
じゃだめなんだっけ?
forをwhileに書き換えるのはおすすめしない。
0112名無しさん@お腹いっぱい。
2014/01/11(土) 14:35:27.41read: Illegal option -N
0113名無しさん@お腹いっぱい。
2014/01/11(土) 15:13:02.47でなんとかならんかい?
0114名無しさん@お腹いっぱい。
2014/01/11(土) 15:16:16.51fold だとセパレータの指定はできないんじゃない?
$ sep="@"; echo 'hogefugapiyo' | while read -N 4 str; do echo -en "${str}${sep}";done
とかしたいのかと思ったけど…
# 最後にセパレータがくっついちゃうけどね
0115名無しさん@お腹いっぱい。
2014/01/11(土) 19:21:56.73社史編纂室に異動させるわ
0116名無しさん@お腹いっぱい。
2014/01/11(土) 19:26:19.16なんで?
保険でつけるでしょ?
0117名無しさん@お腹いっぱい。
2014/01/11(土) 20:27:26.031 2 3
echo 1 2 3 | read k1 k2 k3 | echo $k1 $k2 $k3 | read kk1 kk2 kk3 | echo $kk1 $kk2 $kk3
パイプって何本までできる?
0118名無しさん@お腹いっぱい。
2014/01/11(土) 20:46:56.09sed に -r つけたり grep に -P オプション付けてたりしたら
どこへ異動させられるやらw
0119名無しさん@お腹いっぱい。
2014/01/11(土) 20:53:12.98シェルがあえて限界を設定していないなら
1コマンドとして処理できる文字数以内で
単一プロセスが開けるパイプの限界数まで
じゃね?
0120名無しさん@お腹いっぱい。
2014/01/13(月) 06:37:06.28これって動く?サブシェルになりそうな気がするんだけど
0121名無しさん@お腹いっぱい。
2014/01/13(月) 07:44:33.04社史編纂室に異動させるわ
0122名無しさん@お腹いっぱい。
2014/01/13(月) 11:25:05.94odじゃ無いけどhexdumpの-fフォーマット辺りで何とかならんかのー
0123名無しさん@お腹いっぱい。
2014/01/13(月) 22:06:10.23動かなかった…
0124名無しさん@お腹いっぱい。
2014/01/18(土) 00:30:36.30ln -s linked linked_linked
みたいにリンクのリンク状態になっている場合、
シェルスクリプト内で、最後の linked_linked から大元のファイル
(この場合は original)を探り出す簡便な方法ってありますか?
0125名無しさん@お腹いっぱい。
2014/01/18(土) 00:36:07.020127名無しさん@お腹いっぱい。
2014/01/18(土) 14:08:09.48とコマンド文字列を引用符で囲うところで引用符を忘れて
bash -c test.sh 1 2. 3
としてしまった場合、 1 2 3 はどこに行ってしまうのでしょうか。
気になって仕方がないので教えてくださいー
0128名無しさん@お腹いっぱい。
2014/01/18(土) 14:10:54.08bash -c 'echo $0 $@' 1 2 3
ってやってみるとわかる
0129名無しさん@お腹いっぱい。
2014/01/18(土) 14:38:07.29通常端末と違って echo -e '\a' では駄目です。Androidです。
0130名無しさん@お腹いっぱい。
2014/01/18(土) 14:49:19.13おおお凄い引数として扱える、、、、ってでもこれはナンダ?
-c で生成したプロセスのbashに対して引数を与えられる、ってことでいいのかな?
まだよく理解できていませんが、色々と試してみようと思います。
128さん、ありがとうございました!
0131名無しさん@お腹いっぱい。
2014/01/19(日) 02:14:50.20IFS='=' read A B < a.txt
なら思ったとおりに AにCHINKO、BにBIG が入るんだけど
cat a.txt | IFS='=' read A B
だと入ってくれません
これって何が原因に考えられますか?
0132名無しさん@お腹いっぱい。
2014/01/19(日) 02:17:08.79$ IFS='=' read A B < a.txt; echo $A; echo $B
CHINKO
BIG
$ cat a.txt | IFS='=' read A B; echo $A; echo $B
CHINKO
BIG
$
0133名無しさん@お腹いっぱい。
2014/01/19(日) 02:21:50.04Debianだとうまくいかないんだ、shがdashだから。
>>132
ありがとうございました
0134名無しさん@お腹いっぱい。
2014/01/19(日) 02:40:36.320135名無しさん@お腹いっぱい。
2014/01/19(日) 03:14:26.330136名無しさん@お腹いっぱい。
2014/01/19(日) 03:42:02.64\aとかのビープを鳴らすってことならターミナルエミュレータが\aでビープなりバイブなりを再現すればいい
ので、ターミナルエミュレータの開発元に物申せばいいと思うよ。
普通に鳴らすコマンドが有るかは・・・知らん。
0137名無しさん@お腹いっぱい。
2014/01/19(日) 08:20:07.330138名無しさん@お腹いっぱい。
2014/01/19(日) 08:34:17.39いま、ConnectBot 上で echo Control-V Control-G したら、ちゃんと
ビープしたな。
0139名無しさん@お腹いっぱい。
2014/01/19(日) 08:45:56.29やりたいことをもうちょい具体的に。
0140名無しさん@お腹いっぱい。
2014/01/19(日) 09:32:15.000141名無しさん@お腹いっぱい。
2014/01/19(日) 09:46:37.45文字列なら入力はcatとかで変数にいれたらいい
var=`cat hoge.txt`
出力は標準出力からリダイレクト
hoge.sh > hoge.txt
バイナリならxxdとか使って16進数に変えてから使えばいい
0142141
2014/01/19(日) 09:51:46.110143名無しさん@お腹いっぱい。
2014/01/19(日) 13:21:53.00何を言いたいのかよくわからんが、
もしシェルをJCLのようなイメージでとらえているのであれば、
プログラムを作成する上で、シェルは必要ないです。
プログラムの中で指定すればいい。
0144名無しさん@お腹いっぱい。
2014/01/19(日) 14:03:22.370145名無しさん@お腹いっぱい。
2014/01/20(月) 10:51:58.59最新のDebianだと入らない
0146名無しさん@お腹いっぱい。
2014/01/24(金) 08:44:32.880147名無しさん@お腹いっぱい。
2014/01/24(金) 09:42:05.75社史編纂室に異動させるわ
0148名無しさん@お腹いっぱい。
2014/01/24(金) 10:51:15.620149名無しさん@お腹いっぱい。
2014/01/25(土) 00:19:11.43いまのところwhileにリダイレクトで食わせてreadで1行ずつperlで変換させてます。
もとはBINDのnamed.statsで、UNIXTIMEだけ抽出したものなんですけど、
えっらい時間をとられるもので…
ちなみにHP-UXだからか、dateにstrf表示させられなかったです。
0150名無しさん@お腹いっぱい。
2014/01/25(土) 01:29:52.23うーん、perl で直接ループ回しちゃえばいいんじゃないかな
$ perl -pe 's/\d+/localtime $&/e' < named.stats
named.stats のフォーマットが分からないから "\d+" が別の文字列に
マッチしちゃうかもしれないけど。
0151名無しさん@お腹いっぱい。
2014/01/25(土) 08:21:46.092ちゃんねるで聞こうとなる思考がどうかしてる
0152名無しさん@お腹いっぱい。
2014/01/25(土) 08:33:51.18perl(笑)に逃げちゃう思考がどうかしてる
0153名無しさん@お腹いっぱい。
2014/01/25(土) 11:06:49.43辞令
史編纂室勤務ヲ命ズ
0154名無しさん@お腹いっぱい。
2014/01/25(土) 11:19:26.340155名無しさん@お腹いっぱい。
2014/01/25(土) 12:35:08.03ありがとうございます。
別にスクリプト書いてそっちで回すか、Excelで計算するか…しかなさそうですね。
やってることは、こんな感じです。
grep "+++ Statistics Dump +++" named.stats | awk 'BEGIN{FS="("}{print $2}' | sed 's/)//' > days.txt
(他にもグラフ化したい値を抽出してテキスト化(略))
paste -d, days.txt hoge.txt fuga.txt > data.csv
>>154
すごく…… 低いです……
ン万行あってもgrepであっさりと情報をぶっこ抜けるので、ここだけ、
days.txtのUNIXTIMEを変換する、ここだけ遅いんですよ…
perlで全部解析するスクリプト組むとか面倒で
0156名無しさん@お腹いっぱい。
2014/01/25(土) 13:03:03.82いまの1行変換処理をループで囲うだけでしょ
while(<>){ 処理; }
0157名無しさん@お腹いっぱい。
2014/01/25(土) 13:07:32.99他が問題ない速度なら変換する部分だけをperlに置き換えればいいでしょ
0158名無しさん@お腹いっぱい。
2014/01/25(土) 13:08:25.67>grep "+++ Statistics Dump +++" named.stats | awk 'BEGIN{FS="("}{print $2}' | sed 's/)//' > days.txt
せっかく awk 使っているんだからこれで↓
awk -F'[()]' '/^\+\+\+ Statistics Dump \+\+\+/{print $2}' named.stats > days.txt
0159名無しさん@お腹いっぱい。
2014/01/25(土) 13:20:44.21perl でやるならこれで↓
perl -ne 'if(/^\+\+\+ Statistics Dump \+\+\+ \((\d+)\)$/){print localtime($1) . "\n";}' named.stats > days.txt
0160名無しさん@お腹いっぱい。
2014/01/25(土) 13:26:11.86awk には strftime() が使えるからこれで↓
awk -F'[()]' '/^\+\+\+ Statistics Dump \+\+\+/{print strftime("%Y/%m/%d %H:%M:%S",$2)}' named.stats
# もしかすると strftime() は GNU awk だけでしか使えないかも…
0161名無しさん@お腹いっぱい。
2014/01/25(土) 13:26:14.880162名無しさん@お腹いっぱい。
2014/01/25(土) 13:29:26.28awk: 実装が沢山あり、動作が異なる場合がある
r***: 論外
0163名無しさん@お腹いっぱい。
2014/01/25(土) 13:44:18.270164名無しさん@お腹いっぱい。
2014/01/25(土) 14:23:44.210165名無しさん@お腹いっぱい。
2014/01/25(土) 14:49:39.470166名無しさん@お腹いっぱい。
2014/01/26(日) 03:18:53.50そんなに早くレスを頂けるとは思っておらず、お礼が遅くなりました。
ありがとうございます。
そうか。awkやperlでgrepと同じことが出来るんですね…勉強になりました。
0167名無しさん@お腹いっぱい。
2014/01/28(火) 22:58:27.170168名無しさん@お腹いっぱい。
2014/01/28(火) 23:07:36.20待て待て、gnu dateなら複数行入力の一括変換とか出来るぞたしか
0169名無しさん@お腹いっぱい。
2014/01/28(火) 23:47:55.54昔、似たようなことをやりたくて探したことがあるけど…
あきらめて${#aaa}とかで文字数をカウントして、欲しい桁数からその数値を引き、
付け足すべき半角スペースをループで作って継ぎ足しただよ。
例外処理とかめんどくさかったので、いなかもんのおらも知りてぇだ。
0170名無しさん@お腹いっぱい。
2014/01/28(火) 23:51:39.80レスありがとう。
やはり、ループで足すしかないですかねぇ。
0171名無しさん@お腹いっぱい。
2014/01/29(水) 00:00:56.29aaa="hoge"
bbb="$(printf "%10s" "$aaa")"
echo "$bbb"
0172名無しさん@お腹いっぱい。
2014/01/29(水) 00:05:22.170173名無しさん@お腹いっぱい。
2014/01/29(水) 00:18:47.53どうやんの?
0174名無しさん@お腹いっぱい。
2014/01/29(水) 00:30:18.06printf(1)とか、シェルのクオーティングの振るまいとか、
基本なので理解しとくべき。
0175名無しさん@お腹いっぱい。
2014/01/29(水) 02:19:51.450176名無しさん@お腹いっぱい。
2014/01/29(水) 23:57:44.84すまん、たまたまかなり新しいバージョンのdateだった8.15
-fでファイルを読み込める。
バージョンいくつから出来るのかは知らん
0177名無しさん@お腹いっぱい。
2014/01/30(木) 01:01:14.41昔からあるみたいよ
http://git.savannah.gnu.org/cgit/coreutils.git/commit/src/date.c?id=3c28751b48177e42399ff763c48b54130688d7b6
0178名無しさん@お腹いっぱい。
2014/01/30(木) 15:36:42.60FreeBSDのdate確認したらファイル読み込んで1行ごとにって機能はなさそう
0179名無しさん@お腹いっぱい。
2014/01/30(木) 19:21:21.340180名無しさん@お腹いっぱい。
2014/01/30(木) 20:24:02.530181名無しさん@お腹いっぱい。
2014/01/30(木) 22:10:02.56の%1をsedで置換したいのですが、(でエラーとなってしまいます。
特殊記号の()を読み飛ばして置換するにはどうすればよいですか?
0182名無しさん@お腹いっぱい。
2014/01/30(木) 22:15:21.86" " ではなく ' ' でくくるといい
0183名無しさん@お腹いっぱい。
2014/01/31(金) 10:14:18.23入れられるのならもう入れてるだろう。
0184名無しさん@お腹いっぱい。
2014/01/31(金) 16:11:13.160185名無しさん@お腹いっぱい。
2014/02/03(月) 21:48:36.77以下のようにやると$resultの結果が取れないのですが、どのようにしたらよいでしょうか?
sendMail() {
from=$1
to=$2
inputEncoding="utf-8"
outputEncoding="iso-2022-jp"
subjectHead="=?${outputEncoding}?B?"
subjectBody="`echo "$3" | iconv -f $inputEncoding -t $outputEncoding | base64 | tr -d '\n'`"
subjectTail="?="
subject="$subjectHead$subjectBody$subjectTail"
contents="`echo -e $4 | iconv -f $inputEncoding -t $outputEncoding`"
echo "$contents" | mail -s "$subject" "$to" -- -f "$from"
return $?
}
PSQL=`echo -e "\
〜〜〜SQL文〜〜〜
`
from="from@example.com"
to="to@example.com"
subject="件名を入力"
contents="SQLの結果"
result = echo "$PSQL" | psql -U hogehoge
contents=”結果です"
sendMail "$from" "$to" "$subject" "$contents$result"
0186名無しさん@お腹いっぱい。
2014/02/03(月) 23:03:00.25> result = echo "$PSQL" | psql -U hogehoge
result =$( echo "$PSQL" | psql -U hogehoge)
0187185
2014/02/04(火) 13:38:46.35ありがとうございます
しかし、それだと改行がされないんですよね
A 152
B 585
C 209
と出したいところが
A 152B 585C 209
のようになってしまいます
0188名無しさん@お腹いっぱい。
2014/02/04(火) 15:50:22.05こんな感じ?もっといい方法ないのかな
echo "$PSQL" | psql -U hogehoge | while read line;do
result="$result\n$line"
done
0189名無しさん@お腹いっぱい。
2014/02/04(火) 16:03:23.990190名無しさん@お腹いっぱい。
2014/02/04(火) 16:49:38.80規制くらってたわ。
改行を保持したいのなら、引数でわたすのではなくsendMailの標準入力に渡したほうが楽だろ。
echo "$PSQL" | psql -U hogehoge | "$from" "$to" "$subject" "$contents"
にして、sendMailのmailコマンドを
{echo "$contents" ; cat - } | mail -s "$subject" "$to" -- -f "$from"
のようにして呼べばいい
0191185
2014/02/04(火) 21:26:43.930192名無しさん@お腹いっぱい。
2014/02/08(土) 01:47:24.71世の中的には最近やたらとpython流行ってるじゃないですか
0193名無しさん@お腹いっぱい。
2014/02/08(土) 02:01:25.65ってよくやるけど、pythonは多くの構文が改行を要求するので、ふだんと
違う改行なしの書き方使うことに
なって違和感があるとか?
まあクオートの中に改行入れられるから、そうするって手もあるんだけど、
シェルによっては編集が不便になるし。
0194名無しさん@お腹いっぱい。
2014/02/08(土) 02:25:02.2155500から55555までと規制したい場合はどのようにすればいいのでしょうか?
■ このスレッドは過去ログ倉庫に格納されています