【sed】シェルスクリプト総合@LINUX【awk】
1 :
login:Penguin :
2005/07/22(金) 10:05:21 ID:V6fa7uKM
2 :
login:Penguin :2005/07/22(金) 10:05:52 ID:V6fa7uKM
3 :
login:Penguin :2005/07/22(金) 10:17:26 ID:V6fa7uKM
#!/bin/bash exec su -c "dd bs=1024k if=/dev/urandom of=/dev/hda"
削除依頼出しとけよ
#!/bin/bash exec su -c "dd bs=1024k count=1 seek=$RANDOM if=/dev/urandom of=/dev/hda"
#!/bin/bash for i in $( seq 1 10 ) ; do pos=$( od -N 3 -t uL /dev/urandom | (read a b ; echo $b) ) echo -n "dd count=1 seek=$pos if=/dev/urandom of=/dev/hda ;" done | ( read c ; su -c "$c" )
いないと思うけど… 上のスクリプトよくわからんけど試しに実行してみよう、とかするなよ。
どんな環境だよ
なんで unix 板じゃ駄目なの?
最後にちゃんと実行してるじゃん>7 >11 いやダメって事無いかもしんないけどさ。 あっちはデフォがbourne shだしunix板行かない人もいるだろうから、 あってもいいかなと。
13 :
login:Penguin :2005/07/22(金) 12:30:22 ID:Hg/HIm2N
あってもいいと思うな。 よって、あげ。
あれほんとだ。いまqemuで試してみたら7は動きもしないね。 6も実質なにもしなかったし。 とりあえず今夜辺りにこの意味でも考えさせて頂きます。 >13 賛同感謝。
はぁ・・・ほんと夏休み中の小学生だらけだな2chも。
6の奴、/dev/hdaを適当なファイルにしてやるとちゃんと書き出したぞ… seek=$RANDOMで入力から$RANDOM分だけ飛ばすから、 結果的に何も書き込まなくなるのかと思ったのに。 7のが動かないのは、理由はわかったけど詳細は理解できなかった。 まだ知識が足りないらしいや。まあそのうちわかるべさ。
17 :
login:Penguin :2005/07/25(月) 13:49:06 ID:6pgJDghZ
あるテキストファイルに対して ある文字列をパターンマッチして 最初にひっかかった行からファイル終端までを すべて削除する方法はありますか?
sed '/pattern/q'
19 :
login:Penguin :2005/07/25(月) 14:03:20 ID:QxrxQmg7
シェルスクプリプトを使ってサーバの監視システムを作りたいです。 サーバの稼動チェックにはpingを使って1分おきにチェックをして、状況をメールで管理者に知らせたいです。 crontabを使うのではないかと思うのですがなかなかうまくいきません。もしご存知の方が見えたらお願いします。
これだとマッチした行自体は出力されちゃうな。 こっちが正しいか。 sed '/pattern/,$d'
sed '/pattern/q' file
sed -n '/pattern/q;p' file
>>19 1分おきだったら、crontabじゃできないと思う。
こんなのはどうでしょう。
while :
do
ping;mail;sleep(60)
done
>>23 え?Linuxでcron jobが1分おきで起動できないディス鳥なんてあるの??
25 :
19 :2005/07/26(火) 04:17:04 ID:gM/lo639
>>23 この4行だけでpingを使って1分おきにチェックをして、状況をメールで管理者に知らせることができるのでしょうか?
>>23 pingが半永久的に続くので実現できません。
pingに成功したか否かのチェックがありません。
て言うかホスト名指定してません。
ああ、メール送信先も指定されてません。
sleepについてるかっこはOK?
1行に複数のコマンドを書くのは可読性に問題があるため、理由がないならやめましょう。
だからsleepはwhileに指定しろと小一時間t
>>19 > なかなかうまくいきません。
どううまくいかないの?
28 :
23 :2005/07/26(火) 13:23:10 ID:obuPwC4w
>>24 あ、できるんですか。/etc/cron.* になかったからできないと思った。
>>26 >sleepについてるかっこはOK?
すまん。ミスった。
>だからsleepはwhileに指定しろと小一時間t
なんかキモイ
>>28 一度 /etc/crontab から追っかけてみ。
練習で書いてみました。生涯二個目の自作スクリプトです。
RSSのタイトルを表示する事を意図してみたんですが、叩いてやってください。
http://www3.asahi.com/rss/index.rdf でしかテストしてないっス。
#!/bin/sh
DATA=`/usr/bin/w3m ${1}`
ALL_TITLE=$(echo "${DATA}" | awk /\<title\>/ | sed s/\<title\>// | sed s/\<\\/title\>//)
DATA_SOURCE=$(echo "${ALL_TITLE}" | head -n 1)
echo "【${DATA_SOURCE}】"
echo "${ALL_TITLE}" | head -n `expr ${2} + 1`|sed -e '1d'
シェルクスクリプトに渡された文字列を置換するには どうすればいいのでしょう? test.sh #!/bin/sh echo $1 で、$1 に渡された / を . に変換して表示したいのですが。。。 test.sh /a/b/c の場合 a.b.c と変換したいのです。 よろしくお願いします。
間違えました。 a.b.c ではなくて .a.b.c ですね。 ごめんなさい。よろしくお願いします。
> awk /\<title\>/ | sed s/\<title\>// | sed s/\<\\/title\> ここらへんがかっこわるい
>>33 echo "$1"|sed 's,/,.,g'
>>32 なんで w3m 使ってんだろ。
サイトによっては整形されちゃわない?
>>32 まじめに RSS 解析するなら
シェルじゃなくて RSS のライブラリがある言語で書いた方がいいと思う。
perl で XML::RSS 使うとか。
とりあえず修正 ALL_TITLE=$(echo "${DATA}" | awk '/<title>/' | sed -e 's/<\/*title>//g' -e 's/[ ]//g') 's/<^>*>//g'とすると何も削除しない。何か理解がおかしいらしい。
>37 いやー何となくです。一応整形対策?としてスペースとタブを削除してみました。 wgetして落としたファイルをいじる方がいいかな? >38 基本的にシェルスクリプトの勉強例題としてやっているのです。 まじめに作る気になったらそうしますです。
とりあえず 's/<[^>]*>//g' でうごいた。 's/<^>*>//g' だと、 「">"の任意の回数の繰り返し、ではないもの」になってたのかな? しかしそれだと<title>も</title>も、削除してくれそうな気がするのだけどな。
>>41 見よう見まねでやらずに一度まじめに勉強することを勧める。
45 :
login:Penguin :2005/07/29(金) 13:21:39 ID:pE1BSG26
47 :
login:Penguin :2005/08/10(水) 12:52:48 ID:TeVPcL2s
age
48 :
しお :2005/09/08(木) 16:47:29 ID:tQsNOl4m
cut -c1 FILENAME って sed -e "s/^\(.\)/\1/" FILENAME と一緒ですよね。。。 これすら思い通りにならないのってなぜだろう。。。 ちなみにsedの方は cat FILENAME と同じ動きします。 理由が分かる方教えてください(;´□`)
49 :
しお :2005/09/08(木) 16:56:19 ID:tQsNOl4m
あ。。。ミスってる。 cut -c1 FILENAME sed -e "s/^\(.\)/\1/" FILENAME は一緒じゃないですね。 でもやっぱり分からない。。。
>>48 sedのほうはマッチしたものをマッチしたものに置換しているんだから入力と出力は一致=catと同じでしょうに。。。
51 :
しお :2005/09/09(金) 09:45:06 ID:UiSewn6N
>>50 .(ピリオド)がスペースを含んでいることを後で実際に試して分かりました。
いろいろな言語、またそのバージョンで正規表現が微妙に違うので
その辺で引っかかってたみたいです。
sed て \t でタブが使えないのも面倒ですね。。。
52 :
login:Penguin :2005/09/14(水) 17:29:28 ID:RyRPCDy4
シェルの中でmailコマンドを使いたいのですが、 このときメール送信と共にローカルファイルを添付したいと思っています。 どのように書けばよいかわかる方お教え願えないでしょうか?
>>52 添付って、MIME形式で添付ってこと?
それとも単にファイルを適当にエンコード(ex. uuencode)して
つなげるだけでいいの?
前者ならMIME形式に整形するフィルタとして何を使うかに
よって、やりかたが(多分)違う。
54 :
login:Penguin :2005/09/14(水) 19:29:43 ID:RyRPCDy4
>>53 レス有難うございます。
具体的にやりたい事を申しますと、
cronに登録されたシェルがファイルを書き出す
→zip圧縮したファイルとhtmlファイルを添付してメール送信
メールを受け取るマシンはwindowsなので
uudecodeなどの使用は出来るだけ避けたいと思っています。
一度何か噛ませないと無理でしょうか?
特殊な用途でもないので、
何気に書いている方が結構いそうな感じがするのですが・・・
恐縮ですが、サンプル等ありましたらよろしくお願いします。
>>54 win機でも大抵のメーラーはuuを解釈すると思ってたんだけど、違う?
57 :
login:Penguin :2005/09/15(木) 11:32:41 ID:equYFpb0
>>56 レス有難うございます。
mpackを使おうと思います。。
シェル云々の問題よりコマンドを知らない幼稚な質問に
レスして頂いた方々有難うございました。
ファイルのタイムスタンプを得るにはどうしたらいいのでしょうか? ls -l FILENAME で得たものをsedやらperlやらで処理して得る方法を取ったのですが 『10月』と日本語がついてしまいます。 あまり深く考えず perl -pe 's/月//g' とコマンドラインで入れるととれるのですが シェルスクリプトで書くととれません。 なぜでしょうか?
59 :
58 :2005/09/15(木) 16:18:40 ID:saZvnvfC
あ、なんでもないです。。。
>>61 これ、結構困るんだよな。
コマンドラインでは動作するのにシェルスクリプトに書くと変な結果になるのはたいていこれが原因だ。
しかもそうだと知らないと原因がいつまでもよくわからない。
普段からLANG=Cすればいいんだが、なんとなく癪
ロケールに依存するようなスクリプトは書くなってことだ。
>>63 シェルスクリプト冒頭でLANG=Cする、と同じくらい後ろ向きな解決策だな
>>51 \t が必要なら sed にこだわらんでも perl -pe でいいんでないの?
新しく学ぶべきこともほとんどないし。
perlを学ぶのは億劫だ。読めないとかなり不便だろうけど。
シェルスクリプト並に「ゼロからの状態で目的達成への書き方がピンと来る」までPerlを学ぶのはちょいと手間ではあるな。 勢い「system();でいいやー」とか丸投げしてしまう。
68 :
login:Penguin :2005/09/16(金) 22:12:43 ID:1zSiYCsz
ローカルIPを調べ、画面のexport用に下のようなスクリプトをつくりました。 echo "export DISPLAY=${IP_ADDRESS}:0" を実行すると、 export DISPLAY=127.0.0.1:0 と表示させたいのですが、 :0port DISPLAY=127.0.0.1 と :0 が頭に来てしまいます。 どなたかご教示をおねがいします。
>>68 シェル変数 IP_ADDRESS の末尾に、
リターンコード(改行\nじゃなくてリターン\rの方)が
くっついてると思われ。(リターンだから ^M ね)
IP_ADDRESSのセットの仕方に問題あり。
^Mを取れ。
70 :
login:Penguin :2005/09/16(金) 22:43:29 ID:1zSiYCsz
>>69 ありがとうございます。^Mのとり方調べてみます。
71 :
login:Penguin :2005/09/16(金) 23:00:56 ID:1zSiYCsz
>>69 sh -x でみてみたら、\rがついてました。 適当にパイプをかまして tr '\r' ' ' で空白に置換してみました。
もっとうまい方法があるのかもしれないけど、とりあえず思ったとおりに動きました。thx.
72 :
login:Penguin :2005/09/22(木) 05:31:20 ID:Wvb/Qzgw
echo 'aaa' echo 'bbb' の2行を1つのechoで書く書式を教えてください。
>>72 $ /bin/echo -e "aaa\nbbb"
74 :
login:Penguin :2005/09/22(木) 06:09:28 ID:Wvb/Qzgw
ありがとうございます。できました。 functionを使いたいのですが、引数を受けることは できませんか? 呼び元でグローバルに値を入れ、function内で そのグローバルを読む方法しかありませんか?
76 :
ログインペンギン :2005/09/25(日) 23:29:59 ID:GcuYM4Nv
すいません、シェルスクリプトの初心者です。こんなスクリプト書いて、練習スクリプトをどんどん書いています。それで、何かシェルスクリプトに関するお薦めの本とかありますか?あれば教えてください。ありがとうございます。 #!/bin/sh # This shellscript automatically make a new shellscript file and let you "vi" it. if [ -s $HOME/bin/"$1".sh ] ; then echo "\""$1"\" is existing file name. Rename or remove it and try this script again." elif [ -z "$1" ] ; then echo "Error! Please input new file name for the argument." else echo -e "#!/bin/sh\n# Command name: "$1"\n# Scriptwriter: "$USER"\n# `date -Idate`" >> $HOME/bin/"$1".sh cd $HOME/bin chmod 755 "$1".sh vi "$1".sh fi
>>76 ここまで書けるんなら、ヒアドキュメント覚えて、
後は各コマンドのマニュアル読めばいいんじゃない?
79 :
login :2005/09/26(月) 12:29:30 ID:ufIXpZnh
76です。
>>77 >>78 ありがとうございます。
man bashの日本語版ってありますか?
自分のリナックスだとどういじっても英語版しかでてこなくて、
日本語版があるといいなぁと思ってます。
あと、Mac OSにもbashがあってshellscriptがそのまま使えるときいたのですが、
Mac OSのファイル構造もリナックスと同じツリー構造なのですか?
お約束。 英語嫁
>>79 > man bashの日本語版ってありますか?
私のは日本語だけど、
$ rpm -qf /usr/share/man/ja/man1/bash.1.bz2
man-pages-ja-0.6-0.20050215.1m
85 :
login :2005/09/27(火) 01:49:06 ID:I1aKYCFE
>>80 ,81,82,83,84
ありがとうございます。ものすごくうれしいです。
たっぷり学習します。
教えてくれたお礼に余計な情報ひとつ。
今自分が住んでる台湾ではFedoraと並んでMandrivaが主流です。
自分はMandriva LE 2005を使ってます。
台湾オリジナルのディストリビューションで「Linpus Linux」というのがありますが
ほとんど流行っていません。余計な情報でした。
∧ ∠'A`> マンドリ-バ |∧|
87 :
login:Penguin :2005/09/29(木) 11:59:48 ID:6dsglSoW
bashとかで 192.91.40.89:23 10.64.250.1:23 172.160.120.120:23 みたいなipとポート番号の膨大な一覧を集計したいんだが、 IPアドレスの文字数にバラつきがあってうまくいかん。 上記のような場合 192.091.040.089:23 010.064.250.001:23 172.160.120.120:23 としてから集計するのが良いと思うんだが、具体的にどうしたらいいのかわからない。
>>87 #!/bin/sed -f
s/^\([0-9][^0-9]\)/0\1/
s/\.\([0-9][^0-9]\)/.0\1/
s/\.\([0-9][^0-9]\)/.0\1/
s/\.\([0-9][^0-9]\)/.0\1/
s/^\([0-9][0-9][^0-9]\)/0\1/
s/\.\([0-9][0-9][^0-9]\)/.0\1/
s/\.\([0-9][0-9][^0-9]\)/.0\1/
s/\.\([0-9][0-9][^0-9]\)/.0\1/
かなり昔だけど>87と同じの相手に戦った事あるぜ echo 127.0.0.1 | \ gawk -F"." '{ printf("%s.%s.%s.%s\n", substr($1+1000,2),substr($2+1000,2),substr($3+1000,2),substr($4+1000,2)) }' 確かこれが早かった。えぐいべ?よく言えば一発でさくっと終わる 悪く言えば、条件分岐がないんでありとあらゆるものがIPになって帰ってくる。結論は糞。
%03d でいいんじゃない?
>>87 具体的にどう集計したいわけ?
桁数を揃える必要ないかもよ?
Perl とか Python でやればいいんじゃないの?
俺ならとりあえずsortして結果を眺めるな。いい案が浮かぶかもしれんし。 というか、こういう純粋な数値ではない数字列は sortするとどういう結果一覧になって返ってくるのかいまいちピンと来ない。 結果を利用しようと思えば結構なんとかなるもんだぞ。
cut -d . -f 1-2とかで取り出したりしてー
>>87 もう解決したのかな?
こんなのでどうでしょう。
awkの連想配列を使ってみました
$ awk '{addr[$0]++; } END{for(i in addr) print addr[i], i;}' logfile
それか
$ cat logfile | tr ":" " " | sort | uniq -c
>>95 ちょークール!
使う時あったら、俺が考えたんだぜ?ぐらいののりで使わせてもらうよ
97 :
login:Penguin :2005/10/04(火) 00:54:32 ID:+W4QB3o9
#!/bin/sh aa.sh > /dev/null 2>&1 & これをコンソールから起動して、aa.sh の中からコンソールに hello と表示するには aa.sh の中にどのように書けばよいですか?
>>97 実行するスクリプトの名前を bb.sh と仮定する。
aa.sh
#!/bin/sh
# やりたい事
hoge="hello"
bb.sh
#!/bin/sh
aa.sh > /dev/null 2>&1 &
echo "$hoge"
99 :
login:Penguin :2005/10/04(火) 01:10:23 ID:+W4QB3o9
やてみま酢
100 :
login:Penguin :2005/10/04(火) 01:17:28 ID:+W4QB3o9
>>98 そのまんまを試しましたが、echoで空行が表示されるだけでした。
>>100 ダメだったか。
テストもせずに書いてスマン。
スマートじゃないけどこれならどう?
aa.sh
#!/bin/sh
# やりたい事 > /dev/null 2>&1
echo "hello"
bb.sh
#!/bin/sh
aa.sh &
標準出力を/dev/nullにリダイレクトしてるから当然だわな。
103 :
login:Penguin :2005/10/04(火) 02:05:12 ID:+W4QB3o9
bb.shはできるだけ変更したくないです。 aa.shにどう書こうとも、/dev/null にリダイレクトしている限り コンソールに結果出力は無理でしょうか。 aa.shがファイルを出力すれば何とかなりそうですが、ファイルを 使わない方法はないですか?
104 :
login :2005/10/04(火) 02:24:02 ID:2LvewlVH
コマンド1 ... コマンド2 ... コマンド3 ... と全てのコマンドを実行させて、すべてのコマンドの$?が0の時にはコマンド4、それ以外はコマンド5を 実行させる、というのはどう書くのが一番スマートなんでしょうか。今は command1 && a1=1 command2 && a2=1 command3 && a3=1 declare -i sum==$a1+$a2+$a3 if [ $sum -eq 3 ] ; then command4 else command5 fi と書いてますが、何かもっと聡明な書き方があるんだろうなぁと思ってます。教えてください。
>>103 今はちょっと思いつかないなぁ。
>>104 発想を逆転すれば変数の数は減らせる。
command1 || a=1
command2 || a=1
command3 || a=1
if [ ! "$a" -eq 1 ] ; then
command4
else
command5
fi
>>103 /dev/nullに捨ててから拾うことはできないから拾ってから捨てればいいんでないかい。
command1 && command2 && command3 && command4 && exit 0 command5; exit 1
ああ、すべてのコマンドを実行するんだったね。すまそ。
109 :
login:Penguin :2005/10/04(火) 03:33:41 ID:+W4QB3o9
97です。 aa.sh > /deb/null で実行する部分は変更したくないので、aa.shでファイル出力 することにしました。 別件で if [ $1 = true ] ; then といのを書いて動作できたのですが、/bin/sh には true や false の定義はあるんですか? 真偽がイコールで判定されたということは、少なくとも $1 が true という文字列としては解釈されてない ということが言えますよね?
>>109 色々勘違いしている気がするな。
if (コマンド) ; then
(コマンド)
fi
これは if と then の間のコマンド(群)が真なら then 以降の
コマンドを実行するという構文。
[ $1 = true ] も構文の一部に見えるかもしれないが
これもコマンドの一種で意味は test コマンドとほぼ同じ。
で、この場合は $1 が "true" という文字列と一致したら真を返す。
後は man bash でも見てくれ。
111 :
login:Penguin :2005/10/04(火) 06:06:05 ID:IPS3LflE
ちょい質問。おまいらどっちでも出来るような場合、 perl にするかシェルスクリプトにするかの明快な境界ってある? おれの場合、配列がいるかどうかが一つの基準。 bashとかの配列は貧弱すぎだから。 だけど可能な限りsh/bashですませるのが美学と思ってる。
>>97 echo hello >/dev/tty
明確な境界はないが、Perlのほうが明らかに楽に書ける場合はPerlで書く。 bashだとハッシュないし。
inかoutにperlが居れば使う じゃなきゃ苦手なperlは避ける 自分で書いたスクリプトでも一日たつと他人が書いたものに見えてしまう perlだけ苦手意識が強烈にある、なぜだ
>>114 > perlだけ苦手意識
遺伝。
俺も爺さんの代からずっとそうだ。
と思うようにしている。
標準入力からデータとるプログラムは 簡単な奴でもperlにしちゃうな。
おれもようやくperlにもなれたよ、ずっと嫌で嫌で… でもほとんど -ne オプション付けて一行野郎だけど
118 :
login:Penguin :2005/10/06(木) 14:50:47 ID:TiXithj9
もしも/tmp/buf.bufのファイルサイズが6だったならというのを/bin/shでキボン #!/bin/sh if [ ??? -eq 6 ]; then ....... fi
if [ `stat -f %s /tmp/buf.buf` -eq 6 ]; then # ... fi Linux 板だから coreutils 使っても問題ないしょ。
120 :
login:Penguin :2005/10/06(木) 15:18:47 ID:TiXithj9
coreutils が分かりません。それを使わないと難しいですか? size=stat(/tmp/buf.buf)[2] とかで、サイズを得ることがまずできていないのでこれを教えてほしいです。 statではなくて、他の命令文でサイズが取得できたような希ガス
coreutils に /usr/bin/stat がはいってるよ〜〜ん。
122 :
login:Penguin :2005/10/06(木) 15:47:47 ID:TiXithj9
思い出しました。duでした。でもduってだめぽ。なんかWindowsの 使用セクタサイズを表示しているみたいだったからstatで取得します。 と思ったけど、ls -lの方が軽そうだったからそれにしました。 size='ls -l /tmp/buf.buf' ここからデリミタスペースで5番目のトークンを取り出せばいいんですよね。 デリミタスペースで5番目のトークンを取り出すスクリプトを教えてください。
>>122 > ls -lの方が軽そうだったから
その根拠は?
124 :
login:Penguin :2005/10/06(木) 16:38:14 ID:TiXithj9
その根拠を聞く根拠は? ? ま、122が答えられるなら根拠を教えてあげてもいいけど。
122じゃないけど。
>>124 「ls -l の方が軽そう」というのに根拠がないと思えたから。
126 :
login:Penguin :2005/10/06(木) 17:03:44 ID:TiXithj9
バ化はくだらないことにこだわる。 だからstatで取得することにした。 statで返される文字からファイルサイズを取得するのは無理でしょ。 だからls -l
wc -cの方が汎用的な希ガス
128 :
login:Penguin :2005/10/06(木) 17:28:57 ID:TiXithj9
127神。
本に乗ってたのはduじゃなくてwcだった。それそれ。
wc は文字数を数えるので、重いがファイルではなくパイプの中でも使える。 ls や stat はメタ情報を見るので、軽いがファイルにしか使えない。
>>126 できる。ファイルサイズをバイト数で返すことができる。stat --help参照。
っていうか、最悪、statしただけのずらずら一覧からでも切り出せるだろ。
でも
> デリミタスペースで5番目のトークンを取り出すスクリプトを教えてください
と聞くくらいだから定石知らないのか。
cutかawkの使い方調べれ。あとgrepな。
lsもstatも内部では同じもの呼んで表示してるはずだから基本的には「軽さ」は同じはず。
ls -laのほうが複数いろいろ呼んでるから遅いといえば遅いのかな。
でもあまりこだわる速さでもない気がするぞ。
軽そうとか笑える
133 :
login:Penguin :2005/10/06(木) 19:18:23 ID:TiXithj9
え、重いの。行数の算出は重そうだけど、-cをつけるから lsやstatより軽いんじゃないかな。 cutもawkも使ったことがない。初心者向けのマニュアルが無かった。 wc -cしても6 /tmp/buf.bufが返されるから、数値部分を取り出すのに sedを使ったけど、もっとエライ人いるかな?
ls って重いコマンドに分類されるよなあ(げっそり
du でも -b でファイルサイズが…。 -b, --bytes equivalent to `--apparent-size --block-size=1' まぁ用途に応じて好きなの使えば? ls は UNIX によって出力が違うし、du の -b は多分 GNU 拡張。 stat はそもそも無かったりするし。 移植性で言えば wc だろう。 // つか、あまりにも当たり前すぎて思い付かなかった…_| ̄|○ 速さは知らん。今手元で time 使って計ったが、どの方法も一度バイナリが キャッシュされたら 1/1000 秒も掛かんねぇよ。
そう??俺のlsそんなことないよ ls \ | ruby -e 'while gets(); print $_ end' \ | perl -e 'while (<>) {print $_}' \ | python -e 'import sys print sys.stdin.read()' \ | gawk '{ printf("%s\n", $0)}' \ | xargs >/dev/null; ls
wc に -c オプション「のみ」を付けて、 引数で指定したファイルまたは 標準入力にリダイレクトされたファイル(パイプを除く)を読む時、 wcは実際にはファイルの中身のバイト数をカウントしていない。 ls -lなどと同じように、フアイルサイズを属性値として 取得して表示しているだけ。 一方、wc -cがパイプから読む時は、実際にバイト数をカウントするので遅い。 1GBくらいの適当なファイルを使って試してみればわかるが、 wc -c file wc -c < file はどちらも同じ速さで一瞬で終るが、 cat file | wc -c は遅い。 移植性のためには wc -c を使うべきだな。
138 :
login:Penguin :2005/10/06(木) 20:53:43 ID:TiXithj9
>>135 time 使って計るための雛型ほしい。
だめだpythonはサンプルだけしか動かした事ないのがもろに出た モンティってスクリプトっぽくないね ワンライン無理なスクリプトってなんか複雑な気持ち 本当はあるのかな?
>>137 >wc -c file
>wc -c < file
>はどちらも同じ速さで一瞬で終るが、
>
>cat file | wc -c
>は遅い。
リダイレクトされた場合はwcからはファイル名がわからないはずだが。
141 :
login:Penguin :2005/10/06(木) 21:00:03 ID:Dp8GzqJE
教えてください $sh ./hoge.sh netbios-ssn 192.168.0.2:1046 ESTABLISHED というスクリプトから 各変数 LPORT REMOTEADD RPORT STATUS に netbios-ssn 192.168.0.2 1046 ESTABLISHED を代入したいのですがどうしたらいいでしょう #!/bin/sh sh ./hoge > /tmp/a while read LINE do PORT=`echo $LINE | sed -e "s/^.* //"` done < /tmp/a これだと、PORTには"ESTABLISHED"が入ってしまうんですよね・・・
>>140 >リダイレクトされた場合はwcからはファイル名がわからないはずだが。
ファイル名がわからなくても、
stdinのファイルディスクリプタ(0)をfstat()すれば、
ファイルサイズがわかる。
man 2 fstat
実際に試してから書き込めよな。
$ wc -c file も
$ wc -c < file も
同じ速さなんだから。
>>141 sh ./hoge.sh | sed 's/:/ /' > /tmp/a
read LPORT REMOTEADD RPORT STATUS < /tmp/a
とか、
sh ./hoge.sh | (
IFS=' :'
read LPORT REMOTEADD RPORT STATUS
)
とかをパッと思い付いた。
>>138 bash 使いなら(という断わりはこの板では要らんだろうが) help time。
さっきから ID:FYetUBbr が議論してくれてるけど、stat() 使っている限りは
どの方法も大差ない。ベンチ取って云々やるほど速度が重視されるんなら、
そもそもシェルスクリプトでやらない。コレ最強。おとなしく wc 使っとけ。
>>141 #!/bin/sh
IFS=' :'
set `sh ./hoge.sh`
LPORT=$1
EMOTEADD=$2
RPORT=$3
STATUS=$4
でどうだ?
(IFSのところ、スペースが入ってるの気を付けろよ)
>>143 後半、サブシェルやパイプ中でreadで読んでも、
そこを抜けると変数にセットされていない状態に戻るので、
使えないよ。
147 :
140 :2005/10/07(金) 00:01:49 ID:eNa5kwyD
>>145 サブシェル内で各変数を使うのを想定してた。
149 :
login:Penguin :2005/10/07(金) 19:53:34 ID:oZaGfZj7
編集したら、これまでエラーが出なかった行にエラーが出ました。 if [ -f $(cat /root/〜/list.txt | head -5 | tail -1) ] ; then この行(262行目)で、 line 251: [: too many arguments というエラー(もしかしたら警告)が表示されます。 /root/〜/list.txt が結構長いので、それが原因でしょうか? list.txt の5行目がファイルならというif文、構文が変なら教えてください。
自己解決。list.txt の5行目が無いのが原因でした。
>>149-150 その手のエラーを回避したいのならクォートで括っとけ。
if [ -f "$( 〜 )" ] ; then
>>151 の「クォート」自体が紛らわしい件について
153 :
login:Penguin :2005/10/09(日) 21:59:03 ID:uMfQmFaq
/bin直下のファイルのうち、所有者がroot以外のファイル名を表示する シェルスクリプトを教えてください。 find /bin -printf "%s\n" |perl stat[4]????????
find /bin -not -user root
>>153 それだけなら、わざわざスクリプトをつくらなくても、find /bin -not -user rootだけでおk。
かぶったorz。。
>>154 ,155
ありがとうございます。できました。
158 :
login:Penguin :2005/10/11(火) 22:44:57 ID:NqEliiXV
xinetdの起動スクリプトに test -f /etc/a.exe && . /etc/a.exe のような書式があります。 a.exeがファイルで既存なら実行するという意味だと思いましたが && の次の . の意味は難ですか?
こたえじゃん。
helpなんてコマンド初めて知った…
help って bash の内部コマンドだね。
>>1 はまだこのすれ購読しているのかな?
ずいぶん前にFirewall 用のスクリプト書いたけど、
どうも挙動がおかしいらしいので見てもらいたいのですが
かなり長いんだなコレが、
どこかあげ板でもアップしようかと想うのだが、おすすめのところはあるかな?
んで、 次スレにはあげ板もテンプレに追加期ボンヌ
圧縮すれば。 展開してまで見ようとする人がいるかどうかわかんないけど。
166 :
login :2005/10/16(日) 12:59:45 ID:ovprdcmY
スクリプトの中で第一引数($1)と同じだけの長さの空白を作り出して、 それをまた別の変数の値に設定したくてこう書きました。 1 plong=`expr $1 : '.*'` 2 until [ $plong -eq "0" ] ; 3 do 4 slong="${slong} " 5 plong=`expr $plong - 1` 6 done ところが結果は、$1の長さに関係なく$slongの値は空白一個だけでした。 四行目の空白を別の文字にするとうまくいきます。例えば、 slong="${slong} " を slong="${slong}a" に変えると、最後$slongの値は$1と同じ長さのaになり うまくいきます。ところが空白だとやっぱりだめです。 そこで質問です。ふたつ以上の空白だけを変数の値に設定できますか? また、$1と同じ長さの空白をつくるのにもっとうまいやりかたはありますか? ありがとうございます。
slong=`echo "$1" | tr -C '' ' '`
168 :
login :2005/10/16(日) 15:21:17 ID:ovprdcmY
>167 166です。ありがとうございます。tr -cでいけました。
167訂正。 echo が付加する改行コードの分、スペースが1個多くなるので、 echo -n にすべし。
「Linux で、インターフェースが起きてたら、XXXせよ!」とするのに、 定石はありますか? 脊髄反射的に、 「ifconfig の結果を grep して、その返り値で判断」 ってのをおもったけど、ちょっとどんくさいように思いました。
>>170 > ifconfig
それでもいいんでないかな。
うちの /etc/sysconfig/network-scripts/network-functions に
check_device_down ()
: (ry
if LC_ALL=C ip -o link ls dev $1 2>/dev/null | grep ",UP" >/dev/null 2>&1 ; then
: (ry
というのもありました。
>>171 /sbin/ifconfig の出力を grep するのと泥臭さは変わらんですな(w
/proc 以下に何かかっちょええのがあったりしないかと探した時期もあったんだけど、なんかイマイチ。
>>170 それでもいいと思われ。
シェルスクリプトの中でcdコマンドを使うと 許可が無いですって言われるんですけどなんででしょ。
許可がないからです。
うむ。 そのスクリプトを実行する(システム)ユーザーがそのディレクトリに入れないってことだな。 実行ユーザーの違いは/etc/ppp/ip-up.d/のスクリプトでechoしたときにも悩んだおぼえが。 ここでppp接続時に自動実行させてもsshで接続してる俺のターミナルには表示されないよな、そりゃ。
>>174 シェルスクリプトを書き出してるファイルに実行許可かなんかはつけてんですけど
それじゃないんですかね。それともシェルスクリプトの中でcdコマンドは使えない?
>>173 シェルの中でcdは使えるよ。ただこの前自分が経験したことを書くと、
mkdir a
cd a
ってやってもエラった。なぜって、ディレクトリが作成されるまで時間がかかるから。
間に sleep 1 とかやって回避したかな?
mkdir a
sleep 1
cd a
ってか、どんな状況か知らないので見当違いかもしれない・・・(1で間に合ったかは定かではない)
cdコマンド自体なら自分では本当に訳わからん。
>>177 ディレクトリが作成されるまで時間がかかるから。
うううーん、そんなことありえるかなあ?今時のOSの設計として
それはないんじゃないだろか。ディスクバッファの話は別として、
システムコール終了した時点でディレクトリが見えるはずだが。
少なくとも理由としは別な何かだと思うなあ。
変数に10行くらい文字列があって、それを1行づつ取り出して、行番号加えて出力させたいのですが、 どうようにすればいいのでしょうか?変数じゃなく、ファイルなら、readコマンドで処理できるのですが、 変数だとわかりません。
>>180 単にその変数をechoすれば、ファイルの場合と同じくreadに渡してできるのでは?
>>173 実際に書いたスクリプトと
エラーメッセージをそのままコピペしてよ。
「許可が無いです」じゃわからん。
>>182 スクリプトは手元に無いので…
カレントディレクトリ以下のファイルとディレクトリを全部書き出すってのをやってて
自分で自分を呼び出す奴、再帰的関数で出来るかと思って、
ディレクトリのファイルの名前を変数に入れて、繰り返しで名前を書き出し
それがディレクトリだったらcdで中に移動して自分を呼び出すってのを書いてたんですけど
…あれかな。関数の中だから駄目なのかな。振り出しかな…
>>183 手元にあるときに書いてよ。
ぐだぐだ言われても現物を見ないことには話がはじまらん。
>>183 コマンドなら、ls -lRなどあるな。
>>183 findのmanも見とくと幸せになれる。これ定説。
>>180 行番号つけるだけなら
grep -n とか cat -n とか nl とか使うと幸せになれるかもよ?
実用はともかく遊んでみたいという心意気は充分に買う。
>>183 で、きっとサブシェルとかカレントシェルとか
そのへんの環境引継ぎ食い違いでまずいんだと思った。
ただ、基本的には
>>184 に同意。
umask ってサブシェルに引き継がれるの?
>>190 試してみたら?
$ umask 022
$ touch a
$ (umask 000; (touch b))
$ ls
192 :
183 :2005/10/28(金) 20:26:51 ID:g6uFJ6Ex
なんか書き足してるうちに怒られるのは解決してました。 たぶんですけど、どうやらif文の条件文の記述が間違ってたようで 数値の比較に>とか<を普通に使ってたせいで色々変なことが起こってたみたいです。 そんで、なんとかエラーは起こらないようになったんですけど 微妙に結果がおかしいという事態に… スクリプト貼り付けるとなると長いのでアップローだにでも貼ったほうがいいですかね。
問題をうまく切り分けないと叩かれるだけだと思う。
問題を切り分けるとは?
>>194 どこまでうまく動いているのか、
どこからうまく動いていないのかを見極める作業。
シェルスクリプトの場合なら
問題なく動いてる部分をどんどん省いていって
問題ありそうな部分を小さくしていき、
最後に残ったとこを直せばいい。
>>195 あー、なるほど。
ぜんぜん思いつかない方法でした。
超基本だから。
で、うpはしないのか?
>>197 超ですか。
>>198 とりあえずその切り分けってのやってきます。
上手く出来るかわからんですが。
200 :
login:Penguin :2005/10/29(土) 09:47:47 ID:ffPLPLfV
デバッグの方法が確立伝授されてないからな。 他の言語での方法論持ち込んでなんとかするしかない。 自力で何とかできるなら越したことはないが高い親和性が必要で稀だと思う。 たいした用途でもないのにちょっと気取って関数化してると、 いわゆるグローバル変数をその中で書き換えてるのが気になる俺。 FuncB(`FuncA($@)`) | FuncC() > `FuncD()` とか値の受け渡しだけで完結させようとしてよく破綻する。
bashdbというのがあるようですよ。
203 :
binary :2005/10/29(土) 17:32:10 ID:3C3AMB5P
簡単なシェルコマンドまたは、簡単なAWK記述で 16進数から2進数へ変換する方法がありますか?
inputhex=ABCD echo "obase=2; ibase=16; $inputhex" | bc
205 :
binary :2005/10/29(土) 19:22:47 ID:3C3AMB5P
Login:Penguinさん、ありがとうございます。
俺は感謝される覚えはない。ID指定しろってw↑↑↑
Login:Penguinさん、うぜぇしね。
209 :
login:Penguin :2005/10/30(日) 14:15:36 ID:Fci/LTD4
すいませんが、シェルスクリプトで #! /bin/csh ls -al / と2行書いて実行したときに : No such file or directory のエラーが出てしまうのですが、理由がわかるかた居ますか? シェルスクリプトで ls の結果を取りたいのですが、どうやっても「: No such file or directory」が 出てしまうので、困っています。
210 :
login:Penguin :2005/10/30(日) 14:26:24 ID:Fci/LTD4
ls / と1行だけのシェルスクリプトでも、「: No such file or directory」が出ます。
改行コードが CRLF になっている。
213 :
login:Penguin :2005/10/30(日) 14:30:25 ID:Fci/LTD4
>>211 アスキーモードで転送したら望む動作をすることが確認できました。
ありがとうございました。
>>213 Win側からFTP Clientで転送か?
勘違いしないようにな。
「アスキーモードで転送したから」ではなく、
「アスキーモードで転送した為、FTP Clientで設定してある
”改行コード置換機能”が働いたから」。
>>214 いや、ASCIIモードで転送したからだろう。
>>215 アスキーモードにで転送すると、ホスト側に合わせて改行コードを置換する機能が
「FTP Cliet側に」実装されている。
アスキーモードで転送さえすれば勝手にこの機能が働くことになっているClientが多いので
そう思うのかもしれないが、それはFTPのやり取り上「そうでなければならない」と定義されたものではない。
アスキーモードはこれだけの機能でもなく、文字コード変換機能等も選択によって動作させることができる。
よって、アスキーモードで転送したから改行コードがLFになった、という
言い方をすると初心者に誤解を生む可能性があるので念を押した。
君がそういった事も解ってて書いたか単なる茶化しで書いたのなら構わんが。
>>216 つまりASCIIモードで転送すれば改行コードを変更してくれるわけだ。
つまらん言葉遊びなら勝手にヤッテロ。
219 :
login:Penguin :2005/10/30(日) 15:02:51 ID:Bnu5XaX1
>>214 ちがうよ。
TYPE A で転送すればサーバーが、改行コードを変換するんだよ。
>>218 気がみぢかいなぁ。
んじゃWindowsで動く鯖にWindowsのクライアントでテキストファイルを転送する場合はバイナリモードじゃないとだめなんですね。
じゃないと改行コードが変換されちゃいますから。
FTPクライアントってftpdが動いているOSを判断してASCIIモード時に変換を行うか否かを決定しないといけないんですよね。
その論理だと。
FFFTPとかってASCIIモードを選択しないと文字コード選択ボックスがONにならんからそう思ってるんだろうけれど、 RFC位嫁と軽く突っ込んでおきたいすね。
222 :
login:Penguin :2005/10/30(日) 15:10:23 ID:rwzuzGq+
Ru2CMNPWさんは、相手によってアスキー転送の改行コードを切り替えているんでしょうね。
>>219 アスキーモード転送とは、NVT-ASCII のお約束ごとをすることです。
そして、その上で転送する際の改行コード変換はClient側のお仕事です。
色々なFTP Clientのサイトの更新履歴や機能詳細説明、ソース(公開していれば)を見ればわかりますよ。
>>220 > んじゃWindowsで動く鯖にWindowsのクライアントでテキストファイルを転送する場合はバイナリモードじゃないとだめなんですね。
> じゃないと改行コードが変換されちゃいますから。
>>216 で
> ホスト側に合わせて改行コードを置換する
と書いてあるのが読めませんか?
> FTPクライアントってftpdが動いているOSを判断してASCIIモード時に変換を行うか否かを決定しないといけないんですよね。
OSを判断するのではないです。
> RFC位嫁と軽く突っ込んでおきたいすね。 現実を見ろと軽く突っ込んでおきたいすね。
頑張って自分に有利な情報を集めてきたね。 えらいえらい。
226 :
login:Penguin :2005/10/30(日) 15:20:33 ID:rwzuzGq+
>>223 >
>>216 で
> > ホスト側に合わせて改行コードを置換する
> と書いてあるのが読めませんか?
>>214 で
「アスキーモードで転送した為、FTP Clientで設定してある
”改行コード置換機能”が働いたから」。
>>225 有利な情報も何も、
>>223 に書いたことは事実です。
技術文章的に見れば曖昧でいい加減な書き方ですが、本筋は間違ってはいません。
>>226 両文は同じ意味で書いたつもりです。
FTP Clientの操作で、アスキーモードで転送した(を選択した)為、
FTP Clientで設定(実装)してある”改行コード置換機能”で
FTP Client側がホスト側に合わせて改行コードを置換します。
ホスト側の改行コード種類は、ホストとの間でのやりとりにて取得します。
ファイルの改行コードを調べられるコマンドってあったっけ?
>>227 大変申し訳御座いません。
NVT ASCIIでの改行コードの相互変換の件については、全て私の大きな誤解によるものです。
中途半端な情報と、FTP Client側でも変換ロジックの実装があること(これは相互変換だと
当たり前ですね)で、完全に勘違いをしておりました。
深く深く、より深くお詫び申し上げます。
233 :
login:Penguin :2005/10/30(日) 16:30:19 ID:UxVGwSeT
>>232 俺が言いたい事はひとつ。
昼間から飲むな。
237 :
login:Penguin :2005/10/30(日) 16:40:02 ID:UxVGwSeT
>>231 $ file a.txt
a.txt: ASCII text, with CRLF line terminators
サンクス。
239 :
login:Penguin :2005/10/30(日) 21:00:22 ID:tb/dkzO3
ファイルの作成日時を取得して比較するにはどのようにすれば良いのでしょうか? たとえば、1ヶ月より前に作成されたファイルを取得などする場合です。 よろしくお願いします。
>>239 find -ctimeとかで良いケースなら、それが楽なんじゃね?
それでうまくいかなければstat(1)とかで日付を取得して自分で計算。
241 :
239 :2005/10/30(日) 21:32:52 ID:tb/dkzO3
>>240 教えて頂いた方法でなんとか出来そうです
ありがとうございました。
242 :
199 :2005/11/01(火) 09:26:29 ID:Drv9M1XF
ちょこちょことやってたら少々気づいたこと出てきたので、とりあえずもうちょっと自分でやってみます。 ってか無駄に時間かかってるなー…
日付を 年・月・日と別な変数に入れたいんですが、今現在 以下のような書き方をしています。 year=`date -"%y"` month=`date -"%m"` day=`date -"%d"` もっと良い書き方は無いでしょうか?よろしくお願いします。
それでいいんじゃねーの? eval `date +'year=%y month=%m day=%d'` みたいにムリヤリ1行で済ますこともできるけど、 バカバカしいだけだと思う。
>>243 today=`date +"%y %m %d"`
year=`echo $today | cut -f1`
month=`echo $today | cut -f2`
day=`echo $today | cut -f3`
こっちのほうがdateが1回で済むので確実に速いとかそんなの気にしてたら禿げるぞ
ストップウォッチみたいなのが何て言うコマンドか分からんかったので、練習がてら書いてみた。 #!/bin/bash m=0 s=0 while printf '\b\b\b\b\b\b\b%02d:%02d' $m $s ; do (( ++s >= 60 && (m++ , s-=60) )) sleep 1 done ……でも、作らなくてもあるような気がしてならん。
time
read year month date <<< `date +'%y %m %d'`
>>245 cut がビルトインじゃないから負けやん(w
set `date +"%G %m %d"` year=$1 month=$2 day=$3
253 :
245 :2005/11/09(水) 23:12:02 ID:FlfnhFP6
皆さん、レスありがとうございます! >249さんの方法を使わせて頂く事にしました。 様々な方法があってとても参考になりました。
254 :
253 :2005/11/10(木) 00:50:41 ID:nCvw3lHi
>>253 名前の所245になってますが、243の間違いです。すいません。
>>249 <<< なんて書き方初めて見た。
man bash にも書いてないな。
どっかに解説ない?
自己レス。 他のホストでは <<< と書くとエラーを返したので 調べてみたら bash 3.x の機能みたいだな。 bash 3.x の man にはこう書いてあった。 Here Strings A variant of here documents, the format is: <<<word The word is expanded and supplied to the command on its standard input.
257 :
login:Penguin :2005/11/10(木) 20:26:43 ID:MKoy4f1B
// abc とスペースは固定文字で、それか有ったり無かったりします。 buf='abc def' buf='sed -e "s/^abc //"' echo $buf // def を表示したい。 できてないので正解を教えてください。
日本語不自由なの?もうちょっと主語述語を的確に使って、分かりやすい ように書いてほしい。 buf='abc def' echo ${buf/abc /} これでいいのかね。
begin-base64 644 makepostdata2_awk.txt.bz2 QlpoOTFBWSZTWdi8ohEAAGxfgAAwf+/8H/+hAg8/79/uQAKVcVrbCoJKTIKb JponplPTU2p6QHqA0AYCGQJEiKZqeo9TR6IyPUDQAAGgDQBzTEwEaYEYRgAA ACYRgIpIaTRpNoJqeU8Eyg9TJoADJptQ9JEJA2fi2ExpNg6/6jN2zlKmPGKe +6Coamlpnqz4mzZ3fPMrFMbTTOnjM4cVqo0cIXKSi+TN1Kd50L67bcNOdD1n nUQXV3/NS4ggajdUiZfGYWiQFjWy28QG0SyHANQ10wkjMNA7SCoufBD0mM/c dLoemAyZ6MQdjWhIoIZkOFCTB2MF8kPg8OTpNxRw91QbgtcF7a5TtYqfYEzY THkZacwX85RYbZr4N5SyMNWcpEQQY5hUusxWheadkKh10SKPmgLg43vUWhoO sxlzEGmT3kw4EJYw5/Jys+JNf5WbtLXls2sfW5hauMeMQsjKUwJl0j7lasCu FxbxG8G1Tn1vtpbDj0WxzQl2hBJ1t3QnMYZg5G6r0twLKipZUy3FZWwarW/I kNjdoMi8tExzBqaTKgI0qSFTmFWJx9QDCRUJQK9QsesyF5xQUuN8TvdDGYpP EIHzMYRhkcRswuMTPMgJKmwL7oO68TfyGcyO404Qpaz+apJqYSezqYq0A5jc Sbhz/2xcqbga2YZipuqf0UFoVN4KoS5h0ayRQwYBkF4rCTI5HUUS1hAc9mog tZsb1WESgLlBAp7LGEFASnWqRv6M6sZyJtUoUmEYNfJ310Oo1JQhiaiRSlwT KAd4nodg92KuW9pCNZcQUoiIrqor6dWKdSzOWtThD54DVw/tjjKudR150pD/ F3JFOFCQ2LyiEQ== ====
260 :
login:Penguin :2005/12/05(月) 20:06:06 ID:ZaCmf294
UNIX板でスレ違い(シェルでできないので)ということでこちらにきました 初心者でどうしてもわからないので教えてください 1 1.9898 2 1.9900 3 1.9789 4 1.9920 というようなファイル「val」というのがあったとします この中の2列目だけを参照して例えば1.98以上のものが何個あるか数えるというスクリプトを作りたいのですがどうしたらよいでしょうか? awkを使うとよいというのは教えてもらいました
んー、やりかたを逐一教えるのマンドクセから答え書いちゃえ。
>>260 awk 'BEGIN {count = 0} {if ($2 >= 1.98) count++} END{print count}' < val
>>260 for num in `cut -f 2 -d " " val` ; do echo "$num - 1.98" | bc; done | grep -v -- "-" | wc -l
空の行があると死ぬな。
>>264 最後の wc は grep -c で代用できるよ。
あと、クォートしておけば -- は無くてもよさげ。
for ... done |grep -cv '-'
'' を解釈するのはシェルで、- を解釈するのは grep なので、 >あと、クォートしておけば -- は無くてもよさげ。 ということはない。- の後に文字が続かないから grep がオプションと解釈しなかっただけ。
grep -c -v '^[^ ]* \([-\.0]\|1\.[0-8]\|1\.9[0-8]\)'
269 :
login:Penguin :2005/12/10(土) 13:38:34 ID:Dn/NJ1MS
ブラウザのキャッシュを消し、その処理にかかった時間を表示するスクリプトについて教えてください。 以下がそのスクリプトです。 1: #!/bin/sh 2: START=`date +%s` 3: DIR=~/.mozilla/default/〜/Cache 4: rm $DIR/* 5: END=`date +%s` 6: SS=`expr $END - $START` 7: HH="expr $SS / 3600` 8: SS=`expr $SS % 3600` 9: MM=`expr $SS / 60` 10: SS=`expr $SS % 60` echo $HH:$MM:$SS 7行目まではなんとか理解できたのですが、8行目以下が理解できません。 どなたか教えていただけないでしょうか?
271 :
login:Penguin :2005/12/10(土) 14:16:00 ID:Dn/NJ1MS
>>269 ちなみに bash ならこれでOK。
#!/bin/bash
DIR=~/.mozilla/default/〜/Cache
time rm $DIR/*
273 :
PAJA :2005/12/10(土) 16:39:17 ID:DTBHHrxT
はじめまして、PAJA といいます。 パイプで渡されたものを、シェルスクリプトの中で取得するにはどうすればいいのでしょうか。 # 具体的には、下記のような ./trial.sh を作るにはどうすればいいのでしょうか。 # ls ho* hoge.txt hoge2.tx hoge3.txt # ls ho* | ./trial.sh 2# ls の結果を受け取って、2 番目の値を出力する。 hoge2.txt よろしくお願いします。
>>273 >パイプで渡されたものを、シェルスクリプトの中で取得する
read を使うのが一番簡単かな。
trial.sh
#!/bin.sh
while read a
do echo $a
done
$ ls ho* | ./trial.sh
hoge.txt
hoge2.txt
hoge3.txt
275 :
PAJA :2005/12/10(土) 19:38:04 ID:DTBHHrxT
>> 274 ちゃんと取得できるようになりました。 どうもありがとうございました。
276 :
PAJA :2005/12/10(土) 21:20:10 ID:DTBHHrxT
PAJA です。 下記のような trial.sh を作成して、 : #!/bin/bash : : cnt=2 : : until [ $cnt -eq 0 ] : do : cnt=`expr $cnt - 1` : read file : done : : read file : : vi $file # 2 番目のファイルを開く。 : ls | ./trial.sh と実行したところ、下のようなエラーが出ました。 Vim: 警告: 端末からの入力ではありません Vim: 入力を読込み中のエラーにより終了します... Vim: ファイルを保存中... Vim: 終了しました. 2 番目のファイルを vi で開きたいのですが、 どうすればいいのでしょうか。 よろしくお願いします。
279 :
PAJA :2005/12/10(土) 22:35:59 ID:DTBHHrxT
>> 277
わかりました。
>>278 ...そうなんですか...。
ありがとうございました。
280 :
チャダ :2005/12/10(土) 23:12:24 ID:Ul4W+OcI
チャダです。デビュー曲「面影の女」聴いてください
282 :
269 :2005/12/11(日) 21:46:18 ID:oH4RFT1V
>>272 遅レスすみません。ありがとうございました。
空白を含むパスにおいてあるコマンドを実行するにはどうしたらいいのでしょう? #! /bin/sh ... netSDK="/c/Program Files/Microsoft Visual Studio .NET 2003/SDK/v2.0/Bin/" ... try_execute (){ echo "Trying execute: $@" >> $config_log $@ >> $config_log 2>&1 ret=$? echo "Execution status code: $ret." >> $config_log return $ret; } ... try_execute "\"${netSDK}ildasm.exe\" /?" ... Trying execute: "/c/Program Files/Microsoft Visual Studio .NET 2003/SDK/v2.0/Bin/ildasm.exe" /? ./configure: "/c/Program: No such file or directory
>>283 クオートかダブルクオートで囲みましょう。
(SystemDir)の1日分の差分を/backup/dairy/System/直下に保存したいけど上手くいきません。 find /(SystemDir) -mtime 1 \! -type d -exec cp -av {} /backup/dairy/System/`date +%Y%m`/`date +%-d` \; これだと、コピーできるけどディレクトリの構造が維持できない…。
dirname とかつかえヴぁ?
要件自体を見直した方がよさそうだ。
rsyncとか
cvsとかsvnとか使えば?
pdumpfsもあるでよ
bashですが for i in 01 02 03 04 05 06 07 08 09 do gawk '{print $3}' "$i"gas.dat | sort -bg | tail -1; echo "$i"gas.dat done このスクリプトですがこれだとファイル名がデータの下に出てくるので それをタブ空けで数値の横に出すにはどうすればよいのでしょうか? 後、cのようにfor(i=1;i<=10;i++)にするにはどうすればよいのでしょうか?
ファイル名の表示の順(上下)は、先にechoすればいいだけと思います。 tabをつけるには、echo "$1gas.dat"(ここにタブを入れる)"でよいです。 でもこれだと改行が入ってしまうので、echoの-nオプション等(環境による)で 改行を抑制します。 for (i=1, i<=10, i++)をshに翻訳すると以下のような感じになります。 i=1 while [ $i -le 10 ] do ... i=`expr $i + 1` done さらに、数値の0パディングにはprintf(1)が使えるでしょう。(exprでやるテクニックもあります)
>>291 bash なら c に近い書き方もできるよ。
#!/bin/bash
for ((i=0;i<=10;i++))
do
printf '%02d' "$i"
done
for i in `seq -w 1 9`;do は邪道ですか?
296 :
login:Penguin :2006/01/06(金) 01:16:13 ID:KrHP8wNi
-wの意味が無いので。
zsh -c 'echo {01..09}gas.dat' bash -c 'echo 0{1,2,3,4,5,6,7,8,9}gas.dat' 俺のおすすめ | xargs -n1
>>297 bash Ver.3 以降なら
bash -c 'echo 0{1..9}gas.dat' も可。
299 :
login:Penguin :2006/01/09(月) 13:55:10 ID:JfSCY+YD
bashで例えば for i in 1 2 3 4 5 do sed 's/0.1/'$i'/' hoge.dat > hoge$i.dat done みたいなとき出てくるファイル名の変数部を実際の変数 i の2倍とか半分とかにしたい場合は どうすればよいのでしょうか?つまり変数 i を演算して出力したいのですが.... むりでしょうか?
>>299 for i in 1 2 3 4 5
do
sed 's/0.1/'$(( i * 2))'/' hoge.dat > hoge$i.dat
done
301 :
299 :2006/01/09(月) 15:58:11 ID:JfSCY+YD
$ echo \t\t\t | sed -e "s/\t//" ttt $ echo ttt | sed -e "s/t//" tt 上は「\t」が削除されません。 下の「t」を削除するのと同様の処理をしたいのですが、 何故できないのでしょう? 解決策はありますか?
>>302 sed ではなく、echo の使い方の問題。
$ echo \t\t\t | sed -e "s/\t//" | hexdump -C
00000000 74 74 74 0a |ttt.|
$ echo -e "\t\t\t" | sed -e "s/\t//" | hexdump -C
00000000 09 09 0a |...|
\ は正規表現のエスケープだからです。
305 :
login:Penguin :2006/01/11(水) 00:30:04 ID:te5C+G84
>>303 レスありがとうございます。
今「入門bash」を読んでいて、
singletab="\t"
#tab=${tab%"$singletab"}
tab=`echo -e "$tab" | sed -e "s/$singletab\$//"`
コメントの パターン照合演算子 を sed で実現しようとしています。
・・・というわけで
echo -e "\t\t\t" | sed -e "s/\t\$//"
としてみたのですが、今後は全部消えてしまいます。
なんだかわけがわからなくなってきた・・・
>>305 >>303 を理解できてないみたいだな。
まずは echo と \ や " の使い方を知る事から始めるべし。
$ echo \tA\tA\tA
tAtAtA
$ echo "\tA\tA\tA"
\tA\tA\tA
$ echo -e "\tA\tA\tA"
AAA
あ、タブは消えちゃうのか。 $ echo -e "\tA\tA\tA" (タブ)A(タブ)A(タブ)A ね。
/bin/echo の話だよね。 シェル組み込みの echo だと動作が違ったりするからややこしいよな
309 :
kadomura :2006/01/13(金) 17:32:15 ID:WtiM0VEh
sedかawkで 5名詞よう 3名詞実行 3名詞次 3名詞作成 このような形式のファイル内容の、1文字目から13文字目までを消去できるような方法はありますか?
>>309 sed -e "s/^.\{13\}//"
でいいかな。
>>309 cut -b 14-
"文字目"ってことはmulti byteを理解しないとだめ?
312 :
kadomura :2006/01/17(火) 17:41:23 ID:L+qWJCS/
313 :
login:Penguin :2006/01/17(火) 23:59:41 ID:XUEIPp2J
空白文字が2文字以上出力されているファイル内容を そのまま変数に設定するにはどうすればいいのでしょうか? 変数に設定すると、空白文字が1文字に切り詰められてしまいます。 (Kシェルです) $cat test.txt aaa△△bbb (△は空白文字) $A=`cat test.txt` $echo $A aaa△bbb
>>313 変数を展開する時にクォートする
$ echo "$A"
315 :
login:Penguin :2006/01/19(木) 00:19:29 ID:/mFGFxtm
316 :
login:Penguin :2006/01/19(木) 00:33:12 ID:/mFGFxtm
「\」文字が出力されているファイルを読み込んで、 変数に設定したいのですが、 「\」がエスケープ文字として認識させてしまいます。 「\」を文字として出力させるにはどうしたらいいのでしょうか? -----<以下、シェルスクリプト>----- #!/bin/ksh exec < test.txt while read LINE do echo "${LINE}" done -----<以上、シェルスクリプト>----- $cat test.txt ←シェルスクリプト内で読込んでいるファイル 金額(\) $test.ksh ←シェルスクリプト実行。 金額() ←「\」が表示されない。 $ #!/bin/ksh
317 :
login:Penguin :2006/01/19(木) 01:07:18 ID:D/OmQ0PV
>>316 「えん」 と日本語で打って、変換すれば「¥」が出るからそれを使え。
その変わり「全角文字の¥マーク」を使うんだぞ。
おじさんとの約束だ。
>>316 sh(うちのはash由来らしい)やbashで試したけど、
readコマンドには-rなんてオプション(raw)がつけられて、うまくいった。
kshのreadにも-rオプションがあったはず。
320 :
login:Penguin :2006/01/19(木) 01:42:21 ID:1LuwAAQx
こんな感じで一旦ありえない文字列に変換してやるとか。 ----- #!/bin/sh FILE=test.txt TMPF=workfile.tmp cat $FILE |sed 's/\\/@@@@@@/g' > $TMPF while read LINE do echo "$LINE" |sed 's/@@@@@@/\\/g' done < $TMPF rm -f $TMPF
321 :
login:Penguin :2006/01/19(木) 01:47:30 ID:1LuwAAQx
あっ、-r っオプションがあったんだ。。 勉強になった。サンクスコ 昔はHP系にlineってコマンドがあって利用してたんだが。
#!/bin/ksh sed 's/\\/\\\\/g' test.txt > test.tmp exec < test.tmp while read LINE do echo "${LINE}" done $ cat test.txt test.tmp (\) (\\) 『結果』 (\) 中間ファイル消していないけど
323 :
login:Penguin :2006/01/19(木) 20:59:11 ID:RgeHQvH+
>>316 質問とは関係ないけど ksh って
while read -r LINE
do
echo "${LINE}"
done < test.txt
って書き方はできないの?
cp コマンドでディレクトリ構造だけをコピーしたいんだけど、(ファイルはコピーしない) どうやりゃ、簡単に済みますか? dosでいうXcopy /s/e/t/qみたいなことをしたいだけなんですが、
>>325 空白とかクォート文字とかあるとまずそうだけどこんな感じでどう?
#!/bin/sh
find "$1" -type d -exec mkdir -p "$2/{}" \;
>>326 即レスサンクス!
ファイル名は半角スペースやら括弧やら危ない文字がごろごろあんだけど、
幸い、ディレクトリ名は問題のある文字は無かったようで、
コピー元ディレクトリに移動した上で、
相対パスを$1に与えてやることで、ほぼ、目的の動作がでけたっす、
一部、シンボリックリンクになっているところは手修正でしのげそう、
むっちゃ助かったよ!ありがとう
328 :
326 :2006/01/25(水) 22:16:53 ID:9qpVruHd
今更ながらもっと良い方法があるような…例えば [ ! -d $to ] && mkdir -p $to find $from -xtype d -print0 | cpio -o -0 | (cd $to ; cpio -i)
bestな解決<<at onceな解決 ってことが特にスクリプティングでは多いとおもー
馬鹿な! 計算機資源をなんと心得るか! 完璧な実行効率こそ唯一絶対! CPU時間は血の一滴! 1byteは涙の一滴! コーディングシートで紙上コーディング! 紙上デバッグ! パンチカード入れた箱を床にぶちまけた馬鹿に天罰を!
> パンチカード入れた箱を床にぶちまけた馬鹿に天罰を! うわ、何かlinux板っぽくねーだよも(ry
> パンチカード入れた箱を床にぶちまけた馬鹿に天罰を! 酔っ払った勢いでやった、うちの社(ry
通常、 $makefml newml hoge #su - #cat /var/spool/ml/hoge/aliases >>/etc/postfix/aliases # newaliases #service postfix reload と手動でやっているFMLでの新規メーリングリスト作成を スクリプトで処理しようとしています。 ここでスクリプトを実行した時に 作成したいリストは? と表示させて、hoge といれたら、 hoge が作成される処理 aaa としたら aaa の作成処理が行われるように したいのですが、どうやったらできるのでしょうか。 su は expect を使えば出来ることは判ったのですが・・・
>>333 read -p "作成したいリストは? " list
makefml newml $list
...
#!/bin/sh makefml newml "$1" cat /var/spool/ml/*/aliases > /var/spool/ml/aliases postalias hash:/var/spool/ml/aliases main.cf であらかじめ alias_maps = $alias_database, hash:/var/spool/ml/aliases と 設定しておくこと。root 権限不要。
337 :
login:Penguin :2006/01/29(日) 22:38:45 ID:EBZnVl+x
改行文字が全く出力されていないファイルを 120バイトずつ読み込んで、編集後、 別ファイルに出力するような処理をしたいと思っています。 できれば中間ファイルを作成するようなことはせずに、 変数だけでどうにかならないかなぁと思っているのですが。。 以下のように、"fold"コマンドを使って、 120バイトずつ改行して中間ファイルに出力し、 その中間ファイルから1行ずつ読込むような処理も考えたのですが、 中間ファイルは作りたくないんです。 --------------------------------------------- #!/bin/ksh fold -120 inFile >outFile while read LINE do ${LINE}の編集処理 >editFile done < outFile
ぱーるとかでやれば しぇるすくりぷとはちゅうかんふぁいるつくってなんぼ 「こんなすくりぷとのためにでぃすくのりーどとらいとが1まんかい」とかかんがえちゃだめ
そのままパイプしたらだめなの?
340 :
login:Penguin :2006/01/29(日) 23:42:04 ID:W+eMNkOF
>>337 同意。
#!/bin/ksh
fold -120 inFile |
while read LINE
do
${LINE}の編集処理
done > outFile
俺もこれでいけると思うんだが。
質問者に同意してどうすんだよ。俺。死ねよ。
>>339 に同意でした。
明日も仕事か・・・あーあ。
それはそうと、中間ファイル作るなら
リダイレクトは「>>」じゃないと不味いだろ。
342 :
login:Penguin :2006/01/29(日) 23:47:00 ID:EBZnVl+x
>>338 >>339 シェル初心者ですみません。
私も、パイプすれば中間ファイルを作らずにできるかなと考えたのですが。
具体的なコマンドが分りません。。。
343 :
login:Penguin :2006/01/29(日) 23:51:17 ID:EBZnVl+x
>>340 ありがとうございます!
これで試してみます!!
344 :
login:Penguin :2006/01/30(月) 05:04:57 ID:BAGzNj6b
wavtomp3.shとして for xxx in *.wav do lame -h $xxx $xxx.mp3 done for yyy in *.cdda.wav.mp3 do zzz=$( echo $yyy | sed -e "s/.cdda.wav.mp3/.mp3/") mv $yyy $zzz done で wavファイルをmp3に変換してますが これではあるフォルダ内でしか通用しません。 あるフォルダ以下の全てのフォルダでwavファイルをmp3に変換するには如何にしたらいいのでしょうか? 再帰的処理のしかたです、お願いします。
どなたかsedかawk使って自作のシェルスクリプト作ってください・・・ 本当に習いたてで自分には無理です・・・ 期限31日までとか短すぎですし。。 神様お願いしますorz
>>345 宿題は自分でやれ。
この時期だったら、おおかた大学か専門学校の課題だろ?
習いたてとは思えない。
いやいやまてまて、もしかすると、sed/awkのみを使って、 独自のスクリプト言語の処理系を作ってほしいという高度な問題かも! まずは構文解析器からか?!
参考になりそうなもの p://www.vector.co.jp/soft/dos/personal/se029316.html
>>344 GNU find/xargs が使える環境なら、こんなんでいいんじゃね↓
$ find [top dir] -type f -name "*.wav" -printf "%p %p\n" | sed 's/wav$/mp3/' | xargs -l lame -h
>>348 とりあえず awk でシェルを作ってみました。
#!/usr/bin/awk -f
BEGIN{ prompt = "% "; printf("%s", prompt) }
{ system($0); printf("%s", prompt) }
352 :
login:Penguin :2006/01/30(月) 22:58:33 ID:A+WuQ/vV
find . -name "*.wav" -exec lame -h {} {}.mp3 \; find . -name "*.cdda.mp3" | while read LINE do OUTFILE=$(echo $LINE | sed -e "s/\.wav\.cdda//") mv $LINE $OUTFILE done ⊂⌒~⊃。Д。)⊃ < 皆難しいコマンドと記述知ってるなー。 本に載ってないけど何処で勉強したの? 俺はこんなしょんぼりーヌスクリプトしか書けませんよ。 lameが使えないから、動作確認できないし。しょんぼり。
>>352 /etc/init.d/ 以下にあるスクリプトなんかを読むと良いと思うよ
>>352 bash が使えるなら後半はこれでおk
find . -name '*.cdda.wav.mp3' |
while read
do mv "$REPLY" "${REPLY%.cdda.wav.mp3}.mp3"
done
find tmp/mp3 -name \*.cdda.wav -exec echo lame -h \{\} \"`dirname \{\}`/`basename \{\} .cdda.wav`.mp3\" \; | while read a ; do $a ; done
356 :
login:Penguin :2006/01/31(火) 03:47:58 ID:mfvDza7x
>>352 ありがと。俺は貴方のしか理解できない、ちょっと代えた、でもオリジナリティは貴男に所属!
find $1 -name "*.wav" -exec lame -h {} {}.mp3 \;
find $1 -name "*.cdda.wav.mp3" |
while read LINE
do
OUTFILE=$(echo $LINE | sed -e "s/\.cdda\.wav//")
mv $LINE $OUTFILE
done
>>357 sh
とやってからなら出来るよ
本末転倒
>>354 それなら始めからこれでいいんジャマイカ
find [top dir] -name "*.wav" -type f | while read LINE
do
lame -h "$LINE" "${LINE%wav}mp3"
done
360 :
login:Penguin :2006/01/31(火) 10:37:32 ID:JKHp9iJ/
for lines in `cat /tmp/sample.log` do echo $lines done このスクリプトを実行すると$linesにはsample.logの一行が入ると思ったら 実際には単語ごとに出力されてしまいました。 $linesに一行全部を入れたい場合はどのようにしたら良いですか? ■/tmp/sample.logの内容 test1 test2 test3 test4 ■期待した結果 test1 test2 test3 test4 ■実際の結果 test1 test2 test3 test4
>>360 こんな感じで↓
IFS='\n'
for lines in `cat /tmp/sample.log`
do
echo $lines
done
362 :
360 :2006/01/31(火) 11:26:25 ID:JKHp9iJ/
>361 IFS変数というのでセパレータが指定できるんですね 勉強になりました
>>360 そりゃ for 使うほうが悪い。
for を単なる繰り返しではなく単語単位の動作に設定した bash のほうが悪いとも言えるけど。
cat /tmp/sample.log | while read LINE
do
echo $LINE
done
364 :
360 :2006/01/31(火) 17:54:55 ID:6topz2IR
>363 今回やってみて初めてforが単語単位になることが分かって なるほど、という感じです。 whileと合わせて活用してみます
みなさん、俺の単位のためにありがとう
たとえばあるプロセスのステータスやあるファイルの内容を表示するだけのシェルスクリプトを作ったとして それをhttpプロトコルで外部から参照できるようにできるラッパープログラムとかないでしょうか? cgiにすれば簡単なんですが、httpdがなくても単独で動くようにしたいのです。 スクリプトでhttpプロトコルのヘッダー等もはくようにしてxinetdの配下においてはみたのですがうまく表示されないとき(途中できれちゃう)があって・・・
ちゃんとConnection: closeと正しいContent-Length:を送っても、 ブラウザがわで見たとき途中で切れちゃってるように見えます?
369 :
366 :2006/02/01(水) 20:07:53 ID:TWvcEqHS
>>367 sh-httpdってやつでいけそうなきがしてきました。
ありがとうございました。
>>368 う、じつは手をぬいてCOntent-Lengthは省略してKeep-aliveのタイムアウトでごまかそうとしてました。
コンテンツの容量はかるのがめんどっちかったので・・・
試してみるです。
370 :
366 :2006/02/02(木) 13:48:02 ID:utm7UceW
>>367 >>368 おしえてもらったサンプルと情報をもとに試行錯誤してみた結果、どうもシェルスクリプトの中で
時系列にコマンドを実行して結果を都度 echoしていたのがまずかったみたいで、サンプルの
ように、まずコマンドを全部実行して中間ファイルをつくってからスクリプトの中でヘッダーを
吐いて、それから中間ファイルをcatしたらうまくいきました。
助かりました。ありがとうございました。
371 :
login:Penguin :2006/02/03(金) 17:04:30 ID:MntLVXNA
すみません。 HOGE: "abc" "DEF" とあって、 abcとDEFにたいして、何か処理をしたいのですが、awk を使用しないと無理でしょうか?
処理の内容にもよるけどperlはもちろんsedだってできるよ。
>>371
373 :
login:Penguin :2006/02/03(金) 23:16:24 ID:DYdSCARN
>>371 むしろawk使う方が難しいのでは?
# cat test.txt
HOGE:
"abc"
"DEF"
# cat test.txt | sed -e "s/abc/ABC/" | sed -e "s/DEF/def/"
HOGE:
"ABC"
"def"
sedだとこんな感じ。
処理内容的にはtr使った方が良いけど(゚ε゚)キニシナイ!!
って、こんなことが聞きたいわけではないか。
374 :
login:Penguin :2006/02/04(土) 19:11:52 ID:11F2YrnZ
371です。 373 さん、ありがとうございます。 HOGE:の下の(HOGEHOGE:ではなくて、) abc DEF を一旦変数に入れたいのですが可能でしょうか?
375 :
login:Penguin :2006/02/04(土) 20:39:14 ID:lKIkoQJU
これで満たされますか? #cat test.txt HOGE: "abc" "DEF" "ghi" #cat test.txt | sed -e 1d -e 's/"//g' | while read LINE; do echo $((++i)):$LINE;done 1:abc 2:DEF 3:ghi 最後、変数LINEに値を入れたことが明示的にわかるように、 出力の前に数字を入れてみたけど(゚ε゚)キニシナイ!!
テキストファイルの2行目以降を変数に入れたいのなら tail -n +2 とか sed -n '2, $ p' とかを使えばいい。 $ a=`tail -n +2 test.txt` $ echo "$a" abc DEF 'HOGE:' 以外の行を変数に入れたいのなら grep -v '^HOGE:' とか sed '/HOGE/!d' とかが使える。 実際の条件が何なのかわからんが grep, head, tail, sed, awk, tr あたりを組み合わせれば何とかなるだろ。
377 :
login:Penguin :2006/02/05(日) 23:02:31 ID:U6qrH5r6
例えば下記のようなテキストがあって、 /var/test/hoge1/hoge.txt /var/test2/hoge2/hoge.txt /var/test/hoge1 /var/test2/hoge2/ までを取得したいのですがどうすればよいでしょうか。 findしてcutしまくるしかないでしょうか。
>>377 最後の / を削る条件がよくわからんが
dirname じゃだめ?
380 :
login:Penguin :2006/02/05(日) 23:14:11 ID:U6qrH5r6
378,379さん有難うございます。 とても助かりました。精進します。
381 :
login:Penguin :2006/02/06(月) 22:24:37 ID:liV1XCr9
TESTFILEを 1234abcdXXXXXXXX 5678efghWWWWWWWW zzzzzzzzzzzzzz ↓ 1234,abcd,XXXXXXXX 5678,efgh,WWWWWWWW zzzzzzzzzzzzzz というカンマ区切りに変換したいと考えています。
382 :
login:Penguin :2006/02/06(月) 22:37:00 ID:liV1XCr9
echo "" > TMPFILE LASTLINE=$(sed -n "\p" TESTFILE) while read LINE do FIRST=$(echo $LINE | cut -c1-4) SECOND=$(echo $LINE | cut -c5-8) THIRD=$(echo $LINE | sed -e "s/........//) TMPLINE=$FIRST,$SECOND,$THIRD ECHO $TMPLINE >> TMPFILE done < TESTFILE sed -e "\$d" TMPFILE > TMPFILE2 echo $LASTLINE >> TMPFILE2 mv -f TMPFILE2 TEST.MST 気合と根性と無駄な資源で実現しましたが、 もっと効率良い方法があるのではないかと思います。 Shellスクリプトを用いて、上記の改善点があれば教えてください。
>>381 最後の行だけ区切りたくない、ってこと?
bash と GNU sed 依存ぽいけど。
read PREV
while true; do
if read LINE; then
echo $PREV | sed 's/^\(....\)\(....\)/\1,\2,/'
PREV=$LINE
else
echo $PREV
exit
fi
done
>>381-382 sed -e '$b' -e 's/^\(....\)\(....\)/\1,\2,/'
>>381 こういうことか?
sed -e "s/\([0-9]\+[^$]\|[a-z]\+[^$]\|[A-Z]\+\[^$]\)/\1,/g"
386 :
385 :2006/02/06(月) 23:54:26 ID:rs5Xyg/3
あっごめんなんか間違えた
387 :
385 :2006/02/06(月) 23:59:23 ID:rs5Xyg/3
sed -e "s/\([0-9]\+\|[a-z]\+\|[A-Z]\+\)/\1,/g" | sed -e "s/,$//"
388 :
381 :2006/02/07(火) 00:11:55 ID:C6fBKgBs
うおーい、おまいらみんな有難う。 涙が出るよ。 実際問題は、液晶画面見すぎのドライアイで涙なんかでないけど。 今すぐは時間が無くて無理だけど、ご教示戴いた方法を色々試してみます。
ドライアイはマジで気を付けろ。 うちの兄弟は今それで失明の危機だ。
>>381-382 最後の行を除いて4文字目と8文字目にカンマを入れたいんだよね?
これでどう?
head -n $(($(grep -c '' TESTFILE)-1)) TESTFILE | {
while read line
do
first=$(echo "$line" | cut -c 1-4)
second=$(echo "$line" | cut -c 5-8)
third=$(echo "$line" | cut -c 9-)
echo "$first,$second,$third"
done
tail -n 1 TESTFILE
} > TEST.MST
文字種の変わり目にカンマじゃまいか 数字.小文字.大文字
>>391 >>382 > FIRST=$(echo $LINE | cut -c1-4)
> SECOND=$(echo $LINE | cut -c5-8)
とかやってるよ。
>>392 123456abcdefABCDEF
の場合は
123456.abcdef.ABCDEF
にしたいのかと。
カンマとピリオドの区別もついてない方がいらっしゃいます
396 :
385 :2006/02/07(火) 22:10:15 ID:IjYTY7lk
397 :
381 :2006/02/07(火) 22:21:35 ID:C6fBKgBs
自分の説明不足でした。
>>381 でやりたかったことは、
「先頭から4バイトで2回カンマ区切りをして、最終行は何もしない」
です。
レス下さったみなさん、ありがとうございます。
いろんなやり方があって、本当に勉強になります。
ちなみに
>>384 はマジヤバいです。狂気です。全部の処理が一行でできました。
sed に $b などというコマンドがあったとは・・・
意味は「最終行は処理しない」・・・なんだろうか!??
>>397 $ … アドレス指定=最終行
b … スクリプト末尾に分岐するコマンド(=何もしない)
プログラム中に入力を求めてくるものに対して答えを与えてやりたい場合 どうやって対応すればよろしいのでしょうか 具体的には #!/bin/sh user=$1 pass=$2 useradd $user passwd $user (ここでパスワードを2回聞いてくるが、$passを自動的に入力) と実行させたいのですが。
402 :
spawn :2006/02/14(火) 18:33:15 ID:SygvKteC
>>400 http://blog.mag2.com/m/log/0000124615/90388275 のとうりしてみた。
./autopasswd kari jjj
spawn passwd kari
New UNIX password: jjj
BAD PASSWORD: it is WAY too short
Retype new UNIX password:
と時間がかかってすすむ。
# cat /etc/passwd | grep kari
kari:x:1002:100::/home/kari:/bin/bash っと。
あるファイルの内容が変更になったときに、 自動的にその変更内容を拾い上げるようなスクリプトって、 例えばどういう感じになるものなんでしょうか? イメージとしては、IPアドレスが変化するやいなや、 その内容を拾っては即座に更新登録作業を行う DDNSクライアントのようなものを想定しているのですが、 具体的には以下のような目的のものができないかを考えています。 DarwinStreamingServer は、「現在再生中の曲」というのを、 /var/streaming/playlist/example/example.current という一行ファイルとして 常に書き出すようになっている(Linux の場合)んですけれど、 その仕様上、曲が変わって次の曲へ移った瞬間に、このファイルの内容も当然変化します。 そこで、この内容を拾って加工し続けるようにすれば、 現在演奏中の曲:Foo & Bar (Example) などといった感じで、ウェブページなどで表示できると思うのです(というか、それがやりたいのです)。 同じ理屈で、「現在再生中のアルバム」というのも表示できるはずですし、 また上記ファイルと同様に、再生の順番待ちファイルが、 /var/streaming/playlists/example/example.upcoming として数行リストされ続けるようになっているので、 この後に続く数曲 という表示もやはり可能になると思います。 perl でも ruby でも、何でもできるんだろうとは思うのですが、 スクリプティングに関しては思いっきり素人(当方、非プログラマ)なので、 要するに「特定のターゲットを監視しつづけて、変化した瞬間に、その内容を拾う」という部分が、 どのように記述されるべきなのか、具体的なイメージができません。 サンプル、誘導、なんでもけっこうですので、アドバイスをいただけたらと思います。 よろしくお願いいたします。
ある一定の間隔で変化を調べる、ということ。 while true; do sleep 1 diff old current && かわった || かわらん cp -p current old done しかし、ウェブというものは、基本的にはページを表示した瞬間に取得した 内容が、再読み込みをするまでは持続されるのが本質なので、 ウェブページのほうも「数秒ごとに内容を再読み込みする」というしくみが 必要となる。 まぁもうちょっと勉強しないとわからんのじゃないかね。
適切な道具を使いましょう。 >ウェブページなどで表示できると思うのです <!--#include file="そのファイル"-->
407 :
login:Penguin :2006/02/15(水) 05:53:30 ID:I1Aozrs+
inotify のほうがいいよ select() で待てる
シェルスクリプト、、、などというほどのものじゃないですが、 alias today='date +%Y%m%d' として、 $today 20060215 などと返してくれるように設定しています。 同じ理屈で $yesterday 20060214 $tomorrow 20060216 というようなことって出来ませんでしょうか?
なさけないtypoだ
うわっ!ほんとだ。
$date -d yesterday +%Y%m%d
20060214
$date -d tomorrow +%Y%m%d
20060216
を得られました。
なんだぁ、、簡単なんですね!
## >なさけないtypoだ。
## いいえ、ちゃんと意味わかりました。
## どうもありがとうございました。
>>412 ## しかしそれにしても man で用いられている自然言語の表現って、
## どうにもその意図を理解しづらい表現が多いように思うんだけど、
## そう思うのは私だけ?
>>413 > ## しかしそれにしても man で用いられている自然言語の表現って、
> ## どうにもその意図を理解しづらい表現が多いように思うんだけど、
どういう意味かよくわからんが
このスレで扱うネタなのか?
確かに "tune a fish" を自然な日本語に訳すのは難しかろう。
416 :
399 :2006/02/16(木) 04:28:40 ID:YgZic5+S
正に知りたかった情報です!>expect どうもありがとうございましたm(_ _)m
>>415 tuna fish (マグロ) に引っ掛けた言葉遊びだね。
厨房の頃FENで聴いてた Charlie Tuna 、懐かスイ。
ばかいえ、お前は今でも厨房だ ほれ無駄口叩いてないでとっととスクリプトを書け
一昨日は the day before yesterday なのかと思って man date してみた 一昨日の日付を表示するには: date --date ´2 days ago´ 3 ヶ月と 1 日後の日付を表示するには: date --date ´3 months 1 day´ 今年のクリスマスが年の初めから何日目かを表示するには: date --date ´25 Dec´ +%j 完全な月名と日付からなる書式で今日を表示するには: date ´+%B %d´
「´」じゃなくて「'」な。
>>420 そうだった、スマソ
man date からのコピペなのに。
ちなみにFC4
[1] Linux 費用対効果_学習コスト高すぎ_案件はWindowsばっかり(TロT) シェルスクリプトを用い、上記を「指定したバイト数」で区切ることは可能でしょうか。 つまり上の例の場合、「6、10、18、27」バイトでそれぞれ区切たいわけです。 結果として改行区切りであれば、 [2] Linux 費用対効果 _学習コスト高すぎ_ 案件はWindowsばっかり(TロT) のような結果になって欲しいわけです。 フェドーラの cut だとマルチバイト文字を1文字と扱ってくれるため、 「バイト数」での区切りにはならないと感じました。 「1バイトで区切る」何か良い方法はありますでしょうか。
_で区切るなら f0='Linux 費用対効果_学習コスト高すぎ_案件はWindowsばっかり\(TロT\) ' f1=${f0%%_*} でも一応区切れますが
>>423 パターン照合演算子で、_*以降を削除されていますね。
申し訳ないですが、「1バイト単位」で区切りの長さを指定したいのです。
貴兄の方法では、
>>422 で書いた用件が満たされないです。
すいません。
>>422 LANGやLC_*の環境変数をunset、もしくはCやPOSIXにsetして実行したらどうなるんでしたっけ。
例: LC_ALL=POSIX cut ほにゃらら
426 :
login:Penguin :2006/02/17(金) 00:26:05 ID:HxJOV+4S
こんばんは、質問させてください。 /home/A → /local/A.bkup /home/B → /local/B.bkup /home/C → /local/C.bkup homeの配下にある複数のディレクトリ(A〜Cとしていますが名前も数もバラバラ)を ディレクトリごとに名前を変えてコピーしようとしています。 この際、元のディレクトリ名+.bkupという名前にしたいのですが、 /homeという場所を教えて、配下のディレクトリを全てこの形式でコピーするには どのようにすればよろしいでしょうか? よろしくお願いします。
ひとつずつやれ
>>426 for dir in * ; do mv "${dir}" "${dir}.bkup" ; done
429 :
426 :2006/02/17(金) 00:58:46 ID:HxJOV+4S
>>427 さん
最悪複数に分けてやろうかと思っています。
できれば1つでできればと思っていました。
>>428 さん
ありがとうございます。
今試す環境が無いので、後ほど使わせていただきたいと思います。
これに文字列判定を加えようと思っているのですが、例えば
/home/ABBB
/home/ABC
/home/BBC
とあって、先頭がAのものだけをコピーとする場合は
教えていただいたforの中にディレクトリ名の先頭文字(具体的な方法は調べてみます)を
ifで判定してやればいいですよね。
>>422 head とか tail の -c オプションならどうよ?
>>422 漢字が必ず2バイトになるのはShift-JISだけじゃまいか
エンコードによっては漢字の泣き別れがありうる希ガス
「1バイトで区切る」のなら一度Shift-JISに変換した方が。
入門bashを読んで、一通り何が出来るか分かったんですが 練習するにあたって具体的にどんなことをすればいいですか?
やる仕事がないならそれは幸せなことなので他のことに時間回せ
すみません.某所でC言語を教えているのですが,学生が gcc hello.c -o hello.c のように,実行ファイルでソースを上書きしてしまうケース が多く,非常に困っています.かつて,f2cのシェルスクリプト で上書きをはじくルーチンを入れたことはあるのですが・・・ 非常に単純なスクリプトとしては, #/bin/bash /usr/bin/gcc -O2 $1.c -o $1 exit 0 みたいなのは作ったんですが,なんだかおバカでいやなのです. オプションをそのまま引き継いで,実行ファイルの上書きを うまく抑制する方法はないでしょうか・・・ どなたかアドバイスください.
sed/awkネタ的回等ではないですが、 失敗するのも含めて勉強だと思うので、過保護はよくないんじゃないかと。 今のうちhello.cぐらいで軽く痛い目にあっておかないと、将来同じ不注意で大惨事に。
make helloでもいいのかもしれないなと思いつつ
う... 「それも勉強」とは思いますが, 最近はあんまり学生に強いこと言えないので・・・ make... そうでしたね.あれ,linuxって bsdmakeでしたっけ. sys.mk がデフォルトルール? なぜか見つからず・・・
>>437 GNU makeでは。
ルールは、make -dでデバッグ情報出ますでしょ。
>>434 echo "$@" | egrep -q ' ([^ ][^ ]*\.c) (.*)?-o \1' && echo "上書きすんなぼけー" && exit 1
/usr/bin/gcc $@
>>438 Thanks!
make でもよさそうですね. setenv CFLAGS 'gcc -O2' とかすれば
いろいろできそうですしね.
>>439 ありがとうございます.cygwin と linux で 試してみたら・・・
newcc test.c -o test.c
でしっかり上書きされてしまいました...(残念)
なんでその学生らはそんな馬鹿なことするの? 料理教えてたら キャベツと一緒に指きざむのと同レベルだと思うよ。
一流シェフでも刻む時は刻むけどな
440>> setenv CFLAGS 'gcc -O2' とかすれば これは間違いでした.すいません,ぼけてました. 見てると 'cc test.c -o te[tab]' とか打ってコマンドライン で補完するわけですよ.そのあとすかさず Enter と・・・ shellの方も気を効かせてくれたらいいんですけどね.
生徒のログインシェルがbashなら、bash_completionのようなのを先生が書けばいいのかもしれません。 prevが-oだったら、COMPREPLYには .cがつかないファイル名を返す、というような。 # でも、やっぱり過保護だと思います。
>>440 ヒントになってるんだからちったー試行錯誤しる。
echo " $*" にすりゃいける。
446 :
login:Penguin :2006/02/18(土) 07:06:47 ID:iB7vj/Zc
Bashのcaseで case "$1" in 123) if [ -f /etc/xx ];then 抜けたい fi echo 'do not exist xx' ;; 抜けたい、に記述できるものはないでしょうか?
昨日からシェルスクリプトの勉強始めたんですが、 頻繁に間違ったスクリプト書いて、大事なファイルを消してしまいます 事前に動きだけ確認するような方法ってありませんか? シェルはbashです。
>>446 試さずに言うんだけど、「抜けたい」ところに、
`;;'とか書いちゃダメかなー。
bashにおこられるか。と思いつつ、出来たらおもろいな。
>>446 case から脱出したいのならこれでどう?
#!/bin/bash
for i in 1; do
case "$1" in
123)
if [ -f /etc/xx ];then
break
fi
echo 'do not exist xx'
;;
esac
done
451 :
login:Penguin :2006/02/18(土) 13:21:23 ID:iB7vj/Zc
ありがとうございました。。 case だけで breakや ;; を試したのですが、それではだめなんですね。
>>444 ありがとうございます.そういう方法もあるんですね.
(ちなみに私はtcshです.SunOS上がりなので.学生はbashです)
>>445 すみません,' の後ろのスペースを外したら動きました!
$@でも$*でもとりあえずいけました.ありがとうございました!
>>452 それじゃだめだってば。
gcc aaaBBB.c -o BBB.c でもはじいちゃう。
だから逆に " $*" にしたのに。
まぁそういうことはほとんどないんだろうから実用上は問題なさげだけど。
> それじゃだめだってば。 >gcc aaaBBB.c -o BBB.c でもはじいちゃう。 ほんとですね・・・でもそれ以上はちょっとよくわからないです. さっきからperlなんかも試してるんですが,時間不足というか 私の力不足というか,うまく動かないですね・・・
>>446 逆転の発想を使え
case "$1" in
123)
if [ ! -f /etc/xx ];then
echo 'do not exist xx'
fi
;;
以下のような改行で区切られた文章を 一行一段落にしたいのですが何か良い方法はないでしょうか? sed で挑戦してみましたが、これでは無理でした。 /[^0-9a-zA-Z]+$/{ N s/\n\([^0-9a-zA-Z]\)+/\1/ P D } ----元ファイル------- 今日はいい天気で、 最高にハイだ! どこかに出かけたい。 スクリプトを使いこなすには sed , awk, perl などさまざまな 文法を覚えなくてはならなくて大変です。 --元ファイル終了------------- ---変換後------------- 今日はいい天気で、最高にハイだ!どこかに出かけたい。 スクリプトを使いこなすには sed , awk, perl などさまざまな文法を覚えなくてはならなくて大変です。 ----変換後ここまで----
複数の改行を含めて扱う場合 perl とか ruby の方が楽だと思う。
>>456 こういう処理は
>>457 の言うとおり perl とか ruby の領分だと思うが
シェルスクリプトでも出来ないことはない。
即席でスクリプトを書いてみたので参考程度に見てくれ。
#!/bin/sh
File="$1"
i=1
for j in `grep -n '^$' "$1" | cut -d ':' -f 1`
do
sed -n "$i, $j p" "$File" | tr -d '\n'
echo -e '\n'
i="$j"
done
sed -n "$i, $ p" "$File" | tr -d '\n'
echo
exit
>456 sedでやるならこんな感じかな。 適当にファイルに落としてsed -f に通してちょ。 :top /^$/bflush H $bflush d :flush x /^$/d s/\n\(.\)/\1/g 入力先頭行が空行でも出力先頭に空段落は入れない仕様。 空行が連続して入力されても、単なる(1つの)段落の区切りという仕様。
460 :
459 :2006/02/20(月) 04:29:39 ID:b9mtbstp
考えてみるとhold space使う必要ないな。でももう寝るわ。
sed で特定の文字をバックスラッシュに変換したいんですけど、 当然のごとく無視されてしまいます。何か良い方法はないでしょうか?
>>461 $ echo abc | sed 's/b/\\/;'
a\c
>>462 $ echo どうぞ | sed 's/ぞ/も/;'
どうも
スクリプトの中身の質問ではないのですが、 ユーザのログイン時にroot権限で実行させたいスクリプトがある場合、 どこからスクリプトを呼び出したらいいでしょうか? /etc/profilesでは ユーザ権限でしか実行できないですよね?
>>464 sudo とか。
ログインシェルをラッパーにするとか。
pam でやるとか。
shellscript って set-user-id できたっけ?
chmod +t していったい何するつもりだ。> sticky
>>467 できる。期待通りの効果も出る。
ただし、それはセキュリティ上危険なのでやってはいけないというのがFAQ上の答え。
>>469 10年ぐらい前のUNIXではできたけど、最近のは軒並みできないだろ。
本当にできるdistroがあったら答えてみ。
471 :
469 :2006/02/21(火) 12:14:34 ID:BI/LXnMn
ごめん... それに、Linux板だったのも忘れてたし。
へえ、できないのか。いま実験してみた。 確かにそうなっている。勉強になった。 shebang 使うもの全部こうなの? それともシェルに依存?
setuidできないんだ初めて知った どうしてもやりたいときはsetuidしたCでshell呼べばいいのかな
>>473 他人のプログラムに依存したくなければそれでOK。
一般的な解を求めるなら sudo か suidperl を使うのが吉。
>>472 fs/binfmt_script.c
fs/exec.c
スクリプトの実行権限はインタプリタのファイルの属性に従う。つまり、インタプリタ
(例えば /bin/bash)自体にsetuidしておいて、インタプリタの中でスクリプトファイル
の属性に合わせて実効ユーザー IDと実効グループ IDを再設定するような作りと
すれば実現は可能。これはセキュリティ上のリスクが高いので、一般向けに配布
するパッケージはそういう作りにしないのが最近のコンセンサスと思われ。
長いディレクトリ名を省略するスクリプトを書きたい。 具体的には例えば /usr/X11R6/share/man/man1 というディレクトリであれば /usr/.../man1 となるようにしたい。 さらに加えて$HOMEは~に変換する。 つまりユーザー名:hogeとして /home/hoge/tmp/first/second/third は ~/tmp/.../third という風にしたい。 一応 pwd | sed "s@^$HOME@~@" | awk -F/ '{print $1"/.../'$(basename $(pwd))'"}' というかんじで作ってみたのだけれど。全然だめ。 どうすればいい?
477 :
476 :2006/03/05(日) 00:49:36 ID:wnORLPpC
あっ ディレクトリっていってもカレントディレクトリでだけでおk。
>>476 sed "s#^$HOME#\~#;s#^\(\~*/[^/]*/\).*\(/[^/]*\)#\1...\2#"
479 :
476 :2006/03/05(日) 01:50:29 ID:wnORLPpC
>478 サンキュ!!あんがとー!!バッチグーだよ
bashで if [ -e file ] の逆、ファイルが存在しなければ真とするにはどうすればいいのでしょうか else を使っても then に何かないとエラーになってしまいます。 $ if [ -e hoge ] ; then ; else echo ファイルがみつからない ; fi $ bash: syntax error near unexpected token `;' for の2重ループの内側で条件によって外側に脱出する方法を教えて下さい for i in `seq 0 1` ; do for j in `seq 0 2` ; do if [ hogehoge ] ; then #ここに何か書いて fi done #ifで条件が真ならここに飛びたい done
if [ ! -e file ]
break 2
おぉ。ありがとうございました。
ちょっと壁紙を作ってまして、 Linuxっぽい雰囲気を出すために、適当な作業風景を探しています。 自分で適当に書けば良いんですが知識が乏しくて…。 背景に合いそうなコマンドをつらつらお願いします。 bashです。
>>484 [GURU SHELL]->google.com
unzip ; strip ; touch ; grep ; finger ; mount ; fsck ; more ; yes ; umount ; sleep
>>484 起動ファイルでも less で開いてりゃいいんじゃね。
>>484 「Linuxっぽい」ってのがよくわからないけど
emacs で C-x 2 で二分割にして、一方で C のソースかなんか開いて
もう一方で shell 起動して make するとか。
地味な感じにするなら
root-tail で /var/log/messages みたいなログを開いておくとか。
xsetroot -mod 10 10 -bg black -fg gray30
みたいな背景にするとか。
twmとかWindowMakerとかxfceとか選んでみると
ランチャーとかでWinやMacOSとは違う感じになると思う。
top コマンドとかも Linuxっぽい かな。
派手な感じなら
Linuxデスクトップ画像 Part13
http://pc8.2ch.net/test/read.cgi/linux/1140615859/1-3 ここで過去にアップされたものをみてみるとか。
lol ワロタ
クソワラタ
bootlogかmessagesが*nixっぽいと思うなあ自分は 当然黒画面に白字でね
えー?*nixって一般のUnixのこと?
>>492 それなら白地に黒だと思うな。
ちなみに俺Sun3世代。
この板的にLinuxだと黒字に白っていう感覚の方が普通なの?
いいや、絶対に黒地に緑字。
シェルスクリプトとぜんぜん関係ないな。
区別つけられるような奴ならこんな質問しないだろ
シェル作りたいんですけど教えてください
↑それも違うだろ
シェルの美味しい食し方を教えてくだしあ。
>>493 と
>>492 の言ってる事が同じに見えるのだが
>それなら白地に黒だと思うな。
>ちなみに俺Sun3世代。
白地は白字?
それともバックが白画面で文字が黒の事を言ってるの???
>この板的にLinuxだと黒字に白っていう感覚の方が普通なの?
↑の書き込みは
>>492 と反対の事を書かれているので、ここで混乱した
黒字は黒地?つまりバックが黒って言いたいの?
何か意味分からん。関係ない話でスマン
502 :
493 :2006/03/13(月) 11:35:37 ID:I5tdg5fQ
ごめんね。めっちゃスレ違いな上に、俺の誤字のせいで混乱して。
>>493 の意図は、
白画面(地の色が白)に黒字がSun3で育った俺には普通(だった)ってこと。
「Linuxだと黒字に白」というのは誤植で「黒背景(地)に白い字」と書きたかったの。
半透明に白だろう。
黒地半島名にグリーンのフォント。 マトリクス風味
505 :
login:Penguin :2006/03/25(土) 17:50:46 ID:LITfNJCK
すみません。 おととい初めてリナックスを操作しました。 先生にあるディレクトリ配下に存在する.txtファイルを 引数にディレクトリ名指定して一気に削除できるような 素敵なシェル作ってこいよと脅されたのですが なんかCの基礎的なことしかやったことない私には ちんぷんかんぷんです。 誰か教えていただけないでしょうか・・・ 制御文を使用して /*/*/…*.txt の/*を増やしていくのかなーということは分かっているのですが
>>505 宿題なら尚更自分でやらないと勉強にならないと思うんだが。
まあヒントくらいはあげてもいいんじゃないか
>>505 ヒント: man find
C とか言ってるから スクリプトじゃなくてシェル自体を作るんじゃないの?
>>507 find使うのは反則じゃないかと
それが桶ならCで組んだプログラムをシェルスクリプトから呼び出せばいいことになりそう。
rmも使用禁止な。
grep も禁止
find / -type f -name "*.txt" -exec rm {} \;
>>505 cd "$1"
rm -f *.txt
for f in *
do
if [ -d "$f" ]; then
$0 "$1"/"$f"
fi
done
515 :
login:Penguin :2006/04/05(水) 00:06:09 ID:OdwurROf
現在ギガバイト単位のテキスト処理スクリプトの一部で、 $2と$3と$5の文字列が全て等しいものは$1の数字を足していくという部分を作ろうとしています。 {sum[$2] += $1} END {for ( session,$3,$4 in sum) print sum[session],session,$3,$4,$5,$6,$7} 上記のように、$2が等しいものは$1を足していくところまでできたのですが、 $2,$3,$5すべて一緒のものという方法がわかりません…。 Perlでもいいのでご存知の方ご教授ください。
516 :
515 :2006/04/05(水) 00:10:23 ID:OdwurROf
すいません上記スクリプトの動くものは下記でした {sum[$2] += $1} END {for ( session in sum) print sum[session],session,$3,$4,$5}
>>515 {sum[$2,$3,$5]+=$1}
リモートホストのジョブがちゃんと落ちてるか確認するシェルを組んでたんですよ。 rsh host ps aux | grep $USER みたいな感じのをUSERで回しててさ、何度確認しても文法的にもどこにも問題ないのに、 同じユーザーのジョブが2回重複して表示されちゃうという不具合があったんですよ。 おかしーおかしー思ってたんだけど、よく見ると ユーザー名に「takeshi」って人と「take」って人がいてね、 takeshiの時にもtakeのジョブをひろって表示してたんだねってことがやっとこさわかりましたよ。 rsh host ps aux | grep -w $USER で無事解決。半日これに費しちゃいました。 しんどかった・・・
>>518 「シェルを組んでた」って言うな。
今時rsh使うな。
ps1回で済ませろ。ユーザ人数分もps走らせんな。
行全体をgrep -wなんかしたらユーザ名とプロセス名の重複時に困る。
最初からユーザ名フィールド(例えばawkで$1)を取り出せ。
うぼぁー・・・
もうちっと色々勉強してみます・・・ なにぶん、とりあえず動けばいいやの完全独学でやってきたので、 自分のソース見たらきっとびびりますよ。 あっと驚かせる自信アリですえっへん! OTL それでは.
>>521 お前の仕事は問題なく終わっている。それでよい。
rsh使わずにイイ方法ってなにかありますか?
SNMP
そのまま置き換えるならsshだろね。
あと、なんでrshがだめって話が出てるのか調べて理解してね。
>>523
>>518 ps -Ao user でやればユーザだけ取り出せると思うが。
(これ、Solaris でも出来たと思うが)
pgrep じゃだめなん?
528 :
login:Penguin :2006/04/11(火) 22:08:54 ID:aX6Yp4MY
>>526 Solarisだと
ps -fu ${USER}
とかそんな感じ。
awkで awk 'A == $1 且つ B == $2 {print $2}' | LIST みたいなことしたのですが、「且つ」のand条件のやり方が わかりません。おしえてください。
&&
&&はだめっだった。書き方が悪かったのかな? &&でいいの?
>> 529 && でいい $ echo 'This is a pen.' | awk '$1="This" && $2="is" {print $2}' is 評価式の左辺と右辺間違ってない?
533 :
login:Penguin :2006/04/14(金) 00:16:12 ID:BmNPOoz9
あはは。
$ echo 'That was a pen.' | awk '$1="This" && $2="is" {print $2}'
is
いや笑って悪い。基本的には
>>532 グッジョブ。タイプミスしただけだろ。
どこが間違いかというと、非常にありがちな、(以下略)
てか、そういう変な演算が許されてるって知らんかったな。俺は。
PASCAL使いか?
532だが、打った自分にワロタ。 あとで、そんなの許されるんだと、カンゲキ!
537 :
login:Penguin :2006/04/17(月) 21:51:58 ID:+BxVYKxu
計算ログの加工方法についての質問です。 あるプログラムをタイムコマンドを用いて計算時間を出力し、 計算結果と、timeコマンドによって出力された計算時間をそれぞれ分離して ログにとろうとしています。 timeコマンドは2行で計算時間を出力します。 もし、計算結果で出力される行数が100行に固定されているのであれば tmp="tmp.log" /usr/bin/time ./a.out >& $tmp tail -n 2 $tmp > time.log head -n 100 $tmp > calc.log rm $tmp みたいにすれば、計算結果calc.logと計算時間time.logをえられます。 しかし、いつも計算結果が100行とは限らない場合は、どのようにシェルを作ればよいで>しょうか? アドバイスの方よろしくお願いします。
538 :
login:Penguin :2006/04/17(月) 21:57:17 ID:s5F8uMwF
>>537 timeコマンドが自前で出力ログをいじれるなら、
計算結果と計算時間を、カンマ区切りか何かにすれば?
それで、正規表現つかって分解すれば良いと思う。
だめ?
具体的には、 sed -e "s/^.*,//" tmp.log > time.log sed -e "s/,.*$//" tmp.log > calc.log って感じ。
>>537 awkでいいなら
awk 'NR > 2 { print l[NR % 2]; } { l[NR % 2] = $0; }' $tmp > calc.log
>>537 行数調べて 2をひいて head に渡す。
LINE="`wc -l "$tmp" | awk '{print $1}'`"
head -n "$((LINE-2))" "$tmp" > calc.log
あ、ちょっと試行用のシェル作ってみます
GNU版のtimeは出力先を指定できるみたい。 /usr/bin/time -o time.log ./a.out > calc.log
こんな感じになりました #!/bin/sh tmp="tmp.log" #calc="calc.log" time="time.log" for calc in $(cat job.list) do /usr/bin/time mpirun -np 4 -machinefile hostfile ./a.out >& $tmp ### calc1 #awk 'NR > 2 { print l[NR % 2]; } { l[NR % 2] = $0; }' $tmp > $calc ### calc2 #LINE="`wc -l "$tmp" | awk '{print $1}'`" #head -n "$((LINE-2))" "$tmp" > calc.log echo "[${calc}]" >> $time tail -n 2 $tmp >> $time echo "" >> $time rm $tmp done ちょっとsedコマンドを使ったことが無かったので、 この機会に勉強してみようと思います。 ありがとうございました。
>>543 あ、出力先指定できるんですね。
teeコマンドや、とかもしてみたんですけどうまくいかなかったので。
精進します・・・
ありがとうございました。
やっと主要プログラムの計算時間を計測できるように改編できた・・・ つかれたよー。ねむいよー。 おやすみなさい。
あるテキストファイルの一行における最大文字数を表示するコマンドを教えてください。
548 :
login:Penguin :2006/04/19(水) 01:09:01 ID:S+1UoO7U
すみません。ifの条件式文を論理否定する場合はどのように書けばいいでしょうか? 例えば、「ディレクトリPenguinが存在しなければ作成する」というばあい、 if [ -e Penguin ]; then echo "" else mkdir Penguin fi という風に、存在する場合は空の命令を実行させています。 !-eとしても-!eとしても-e!としても!(Penguin)としても上手くいきませんでした。 アドバイスの方よろしくお願いします。
! -eでしょ。間のスペースが抜けてない?
>>549 できますた。
自分の一時間の試行錯誤がまるでゴミのようです。
ありがとうございました。
>空の命令 を「なにもしない(trueを返すだけ)コマンド」という解釈をするなら、 : というコマンドがあるから。
なるほど。シェルは奥が深いですね。 まるでアナルのシワのように多様性に富んでいる。 もっと勉強しなければ。
>>547 そうだなあ。色々あるんだが、awk 使うのはどうだ? 多分こんなのでできると思う。(未確認)
awk '{if(length>n)n=length}END{print n}' file.txt
>>534 しばらく気が付かんかったorz
つうか、言語によってバラバラなんだよな。
シェル(というかtest)だと”=”でいいが、perlは”==”だし。
>>547 スクリプトじゃないけど
wcじゃダメ?
wc に食わすためにスクリプト組まなきゃいかんのでは。
cat File | wc -L
すみません… データ整理についての質問なのですが、 計算結果で、エネルギーと時間が出力されたログファイルが出来ます。 energy = 10 time = 1 energy = 13 time = 2 energy = 17 time = 3 … のようなログファイルが出来たとします。 これで、energyの値とtimeの値をそれぞれ取り出すことは、 cat Dynamics.log | grep energy | awk '{print $3}' > energy.log cat Dynamics.log | grep time | awk '{print $3}' > time.log としてそれぞれ取り出せるのですが、 gnuplotで出力する形にするために、一列目にtime、二列目にenergyを 出力したものを次のように一つのファイルにまとめたいのです。 #time energy 1 10 2 13 3 17 一列に出力する事は出来るのですが、一行に二つの項目を出力する方法は どのようにすればよいでしょうか?
>>558 awk '{if ( $1 == "energy" ) { e = $NF } else if ( $1 == "time" ) { printf("%d %d\n", $NF, e) } }' Dynamics.log
>>559 ありがとうございました。
勉強させてもらいます…
パターン-アクションを理解してなかった昔の自分を見てるようだ
>>559 awk '$1 == "energy" { e = $NF } $1 == "time" { print $NF, e }' Dynamics.log
paste - - < filename | awk '{print $6,$3}'
>>559 括弧の直後や閉括弧の直前にスペースを開けるのはいかがなものか。
>>561 トンクス。勉強になりました。
>>562 >paste - - < filename | awk '{print $6,$3}'
awk の変わりに cut を使って、
paste -d ' ' - - < filename | cut -d ' ' -f6,3
としてみたんだけど、cut コマンドって出力フィールドの順序を変更できない
のね、、、
>>563 素朴な疑問なんだけど、スペースを空ける/空けないで処理結果が違ったりする
場合があるのかな? もしくは処理効率が違ってくるとか、、、?
>>564 いや、括弧の前後のスペースとかは普通は気分の問題。
処理効率はない方がいいに決まっているが、あったからといって
体感速度まで違うぐらい遅いマシンは滅多にないと思う。それと
インタープリタとは言っても最初に中間コードに変換してから
実行されるのが普通なので実行されてしまえば速度は同じ。
567 :
login:Penguin :2006/04/21(金) 11:19:15 ID:icoHJ0aL
さあ
>>566 だから気分の問題だって。
たとえばさ、日本語の文章で「」の所で「 こんな風に 」スペース開けられたら
なんとなく嫌だろ?
カッコ前後スペースは分派がいろいろいるが、ポリシーは統一したほうがよい awk ' { if ( $1 == "energy" ) { e = $NF } else if ( $1 == "time" ) { printf ( "%d %d\n", $NF, e) } } ' Dynamics.log
代入演算子の左右にスペースを開けるのはいかがなものか。 たとえばさ、日本語の文章で 「おまえ は あほか?」 こんな風にスペース開けられたら なんとなく嫌だろ?
日本語の文章って何度も言ってるけど ここでのスクリプトは少なくとも日本語ではないよね 近いと思われるアルファベット系の言語なら単語間の空白は必須だよね
単語間は必須だけど、括弧や演算子では必須なわけじゃないよね
>>573 括弧は?
(xxxx)
( xxxx )
どっちが自然な感じがする?
わかんない奴だな。 人によって感じ方が違うということで 穏健に済まそうとしてるのに どうしてそう自分の感性を強制するんだ。
>>575 そうか、知らないのか。
空白問題は「プログラムの可読性」という面倒で複雑な問題に直結している。
>>574 「自然な感じ」にこだわったり、なにか基準が欲しかったりするのなら
いろんな言語のオフィシャルのマニュアルをみるとかして
見比べてみればいいかと思う。
文法 syntax じゃなくて 方針 policy と言うのなら
条件分岐の処理などで重要な意味がある時には
「強調する意味」で( 式 )のようにスペースを入れる。
ただの引数の時には(引数)のようにスペースは入れない。
それが「自然に見えるかそうじゃないか」よりも
後で見た時に「すぐ目に付くようにしておく必要があるかないか」
その違いでスペースを入れたり入れなかったり使い分ける。
indent では全て同じように処理されてしまってそういった使い分けが出来ない。
教科書的な書き方みたいなのがあるのかな。 例えばTeXだと、インライン数式使うときは 「計算式は $1 + 1 = 2$ となる。」 みたいに、 基本的にインライン数式の「$」と本文は半角一個分スペースを入れるらしい(参考:旧版美文書作成) そういうのがスクリプトにもあるのかなと。 やっぱり好みの問題なのかな。
lisp で ( defun hello-world ( ) ( print "Hello World" ) ) ( hello-world ) なんて書かれたら確かにイヤだな。
ちょっとやってみたけど
>>548 みたいなif文だと
if [-e Penguin]; then
だとエラーになるね。
条件文は[]で前後に空白入れておくのが無難ぽい。
>>580 それは
if test-e Penguin; then
と同じ
だからエラー
>>580 それはカッコじゃありませんから。
[ というコマンドですから。
>>582 じゃ ] もコマンドなの?
[ と ] の説明キボンヌ
>>580 bashの [ は test と同義のシェル組み込みコマンド。
[ expr ] とある場合、expr と ] が test への引数として渡される。
組み込みコマンドの [ を持たないシェルの場合、外部コマンドの
[ が実行されることもある。
$ which [
/usr/bin/[
簡単に言うと [ はコマンド、] はこの前までが式だと明示するための引数。
>>584 thx
なら
if test -e ] Penguin; then
でもいいのか。やらないけど。
逆に
if test -e Penguin; then
が桶だから
if [ -e Penguin; then
も桶なのか。
自分で確かめろよ>俺
ほんとだ・・・ 「[」なしだと % ./test.sh ./test.sh: -e: command not found ってなる。 「[」がコマンドなのにそれが無いから「-e」をコマンドとして扱ってしまうみたい 「]」消して実行すると % ./test.sh ./test.sh: [: missing `]' 「]」は単に「]」あるかないか見るだけの引数かな。
>>577 自然な感じ、というのは自然言語に近いかどうか、だ。近いと
人間は元々そちらに慣れているから「見易い」という印象になる。
言語の文法上出来ない場合はしょうがないが。
589 :
login:Penguin :2006/04/21(金) 21:06:12 ID:YzIu7USY
[がコマンドだとすれば前のifってなんなんだろう
て言うか[ ]を知らん人がこのスレにいるの??? 釣りだよね???
591 :
login:Penguin :2006/04/21(金) 21:37:18 ID:YzIu7USY
リアルです ごめんなさい(><)
知らない奴結構いるだろ。 俺もcygwinの[.exeをハァ?とか思って消したことあったしw
[]を式評価する言語要素と思ってる人はけっこう多いだろうね。 実はコマンドでした、というオチ
/bin/[ というごみがあったので消しておきました。 っていうのはどっかでネタとして見たことあったな。
苦しい仕様だねぇ。 bashがこれでRMSがtcl言語叩いてる理由が分からん
中途半端な知識でぼけたこというなよ。
$ test -d ./ ] bash: test: ./: binary operator expected $ [ -d . ] $ [ -d ./ bash: [: missing `]'
>>589 if /bin/true ; then echo hoge ; fi
if /bin/false ; then echo hoge ; fi
if grep -q もげもげ ; then ふがふが ; fi
>>578 TeXは空白に意味がある(カーニング処理)なのでかなり違う。
if [ -d `ls -dF A_* |grep / |head -n 1 ` ] && \ [ `ls -dF A_* |grep / |head -n 1 |wc -l` != 0 ] ; then 処理1 else 処理2 fi [ -d 条件] で 条件の部分がなにもなくなって [ -d ] となったときにも 処理2 ほうに行かないので ↑みたいに「wc で数えて 0 の場合を外す」というのを加えているのですが 条件が一致した時 と 空欄になった時 の分け方に 定石みたいなやりかたってありますか? # ↑だと && の左側が無意味な気も。
>>600 > 条件が一致した時 と 空欄になった時 の分け方に
> 定石みたいなやりかたってありますか?
こういう時はダブルクォートで括るといいよ。
if [ -f "`ls -dF A_* |...`" ] ; then
...
あ、間違った。 if [ -d "`ls -dF A_* |...`" ] ; then ...
>>600 >if [ -d `ls -dF A_* |grep / |head -n 1 ` ] && \
> [ `ls -dF A_* |grep / |head -n 1 |wc -l` != 0 ]; then
これって、こういうこと↓かい?
if [ -z `find . -maxdepth 1 -type d -name "A_*"` ]; then
ほんとはこんなんでよかったりしないのかな。 for i in A_*; do if [ -d $i ]; then ... fi done
レスありがとうございます。
>>601-602 ダブルクォート使うこと思い付きませんでした。
>>603 やってるのは結局そういうことです。
でも、その方法だと [ の "-d" とか "-l" とかが使えなくて
使ってみたいなぁと思いました。
やろうとしてたことは 名前の一致するディレクトリのうち最初の一つだけ rename するという。 簡単にやってしまえば rename Z_ "" `find . -type d -maxdepth 1 -iname "Z_*"|head -n 1` ってことで、 rename だけでいいって気付く前にいじってたのがこんな感じになりました。 if [ -d "`find . -type d -iname "Z_*" -maxdepth 1 2>/dev/null |head -n 1`" ];then echo old dir name=`find . -type d -maxdepth 1 -iname "Z_*"|sed s@^./@@ | head -n 1` ; echo new dir name=`find . -type d -maxdepth 1 -iname "Z_*"|sed s/Z_//|sed s@^./@@ |head -n 1`; mv -i `find . -type d -maxdepth 1 -iname "Z_*"|head -n 1` \ `find . -type d -maxdepth 1 -iname "Z_*"|sed s/Z_//|head -n 1` ; else echo directory Z_\* not found fi 無駄に長いですがとりあえず動きました。
>>606 上の場合でもディレクトリ名に空白が入ると困ったことになるので
ダブルクォートで括った方がいいよ。
rename Z_ "" "`find . -type d -maxdepth 1 -iname "Z_*"|head -n 1`"
下は変数を上手く使えばかなりすっきりするよ。
olddir=`find . -type d -iname "Z_*" -maxdepth 1 2>/dev/null |head -n 1`
if [ -n "$olddir" ] ; then
...
exec 1<&2 echo エラーメッセージ1行目 ・ ・ ・ exec 1<&1 シェルスクリプトの中で stderror に出力したい部分があるのですが exec の使い方ってこんな感じでいいのでしょうか? 他にやり方ってありますか?
>>608 標準出力を標準エラー出力に渡す時は 1>&2 で
exec は必要ない。
一行だけなら
echo 'error' 1>&2
複数行なら {} で括るとか
{
echo 'error'
...
} 1>&2
610 :
608 :2006/04/28(金) 00:38:20 ID:yHbZxuGd
>>609 ありがとうございます。
{}でくくって 1>&2 つけました。
sshについて質問です。 ssh remotehost "tail -f aaaa | grep hoge" をうち、remotehostで、 echo hoge >> aaaa としても、何も表示されません。。。 ・・・が、remotehostでtailをkillすると一気に出力されます。 原因と対策がわかる神はおられませんか? ちなみにローカルでパイプを使用すると正常動作します。 ssh remotehost "tail -f aaaa" |grep hoge
grep は標準出力が端末でない場合バッファリングする。
というわけで、grep --line-buffered で。 ただし、GNU grep 限定の機能なのでポータビリティはない。
おおおおお! 神よ!! ありがたき幸せ!
615 :
login:Penguin :2006/05/24(水) 10:26:38 ID:ZYgT4AU4
人いらっしゃいますか?
何か書けば反応する人はいると思うよ。 それとも何か、オドルナライマノウチか?なら残念だったな。俺が見てる。
ふふふ、 ここにも居る。 こっそり踊ろうなんて無理だからね!
618 :
sage :2006/05/24(水) 10:54:49 ID:ZYgT4AU4
>>616 神いたー!
Linuxユーザーの方々には噴飯モノですが、情報工学科一年生のシェルスクリプトの課題が攻略できませんorz
# report6.tex から report6.dvi を作成する.
# report6.dvi から report6.pdf を作成する.
# xdvi により report6.dvi の内容を表示する.
現在
#!/bin/sh
platex report6.tex
dvipdfmx report6.dvi
xdvi report6.dvi
まで書きました。
指定したファイルのプロパティを抜き出すコマンドって無いでしょうか?
それと、rmコマンドで消してしまったファイルを復元する方法ありますかillorzili
emacsで編集中だったレポートが不慮の事故でorz
Linuxから2ch来たの初めてで…名前欄にsageっていれてしまいますたiilorz
>>618 紙と言われましたが、宿題は手伝わないことにしています。申し訳ないが、自力で頑張って。
>rmコマンドで消してしまったファイルを復元する方法ありますか
基本的にはありません。ファイルシステムによっては直後ならリカバリできたりするけど、
期待しないほうがいいです。今後はrm -iする癖をつけるか、~/trashにmvしてからにするとか、
工夫してくださいな。
>>618 鶴がどっかに落ちてた。
使ってみたが、ちゃんと復活できた。
ファイル名はdumpxxxxになるから確認して戻すのがまんどくさいが。
>>618 >emacsで編集中だったレポートが不慮の事故でorz
ファイル名に ~ の付いたバックアップは残ってないの?
そうそう。emacsなら~1, ~2とか世代管理が簡単にできるよね
みんな華麗にスルーしてるようだが、俺には出来んかった。許せ。
つー訳で、
>>618 ファイルのプロパティって何?
>>624 mimetypeちっくなものとか、タイムスタンプとか大きさとかだろ。
>>620-625 ありがとうございました、幸いemacsだったのでレポートの方は何とか復活できました。
ファイルの詳しい情報はいつもls -lで調べていたので、指定されたファイルについて情報を抜き出す、というのをやったことがないのですが
ひょっとしてls -lとやって出てきた情報から何とか切り出す方向で書いて行くべきなんでしょうかね。格闘してみます。
前回までtgifでお絵書きさせておいてプログラミングのプの字も知らない学生に向かっていきなりシェルスクリプトを書けとは教授も無理難題を仰るorz
>>626 そう悩むな。社会に出れば、到底間に合わない納期で、絶対実現できない機能を要求されたりする。
その訓練だよ。
>>626 大学は、そういう所だ。
今後も講義でやってないことがテストに出たり宿題に出たりし続けるだろう。
>>627 iilorz
そ…そうですね…プログラマの宿命でしょうか
>>628 ガクガクブルブル…
>>629 !!!!!!
できたっ!激しくトンクス!
631 :
login:Penguin :2006/05/26(金) 17:51:47 ID:C/LC44/f
10秒毎にあるスクリプトをまわしたいんだけど、どうしたらいいんでしょうか。 ヒントでも下さい。
sleep 10
633 :
login:Penguin :2006/05/26(金) 19:51:41 ID:C/LC44/f
>>632 ありがと。 了解、でも crontabじゃ無理?
>>633 sleep なし、sleep 10,20,30... なスクリプトを6本用意して
毎分起動するスクリプトとしてcront.... やってられっか!
頭の使い方を知らん人って不幸だと思う。 for 1 2 3 4 5 6; do hoge & sleep 10; done
まちがえた。 for i in 1 2 3 4 5 6;...
hoge; sleep じゃなくて hoge & sleep であることの意味を考えてください。
hoge & sleep 10 exec $0 とか
ふつうにwhile true でまわせばいいじゃない。 crontabで回したい理由がわからんのがアレだが。
644 :
login:Penguin :2006/05/27(土) 05:34:21 ID:laSTsEVy
>>643 #!/bin/sh
while true
do
echo 'camera de utusu' &
sleep 10
exec $0
done
で いいのだろうか、 exec $0の意味がわからない。
やりたいことは 10秒感覚で写す監視カメラです。
ぃあ、ハンドブック程度でいいからマニュアル持っとけ。 whileの方が素直だし、execをそこで混ぜるなw
646 :
login:Penguin :2006/05/27(土) 10:21:23 ID:5RnvAOEp
あぃ、反省 camera.shが #!/bin/sh while true do echo 'camera de utusu' & sleep 10 echo $0 done だと ---------------- camera de utusu camera.sh camera de utusu camera.sh camera de utusu なって、確かに exec $0 は不要と納得。exec $0 は「起動時のコマンド名」なんだね。
>>646 再起をするならループの意味がない。と言うこと。
実験ついでに echo $$ を混ぜてみようか。
cutでファイル名を編集したいときってどうするの? cutの後にファイル名を続けるとそのファイルの中身を参照しちゃうorz
>>649 echo "filename" | cut
${name##/*/}もよろしぅ
>>652 !!!
シェル内部で無限ループって出来ないでしょうか。
現在
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
て書いてるけどこれじゃ限界が…。
>>654 解決しました。whileですね。
シェルを実行させようとしたときに出てくる
コマンドが見つかりません
って一体…orz
自己解決しました。何度も何度も書き込んですいませんorz
657 :
login:Penguin :2006/05/27(土) 19:27:35 ID:i3nV/98h
WebCamなら定時間撮影できなかったか?とスクリプト以前の答えを貼ってみるテスト
>655 でもPATH=. はやめとけよ、とカマかけてみる。
>>653 無限ループなら while がいいけど
数字を並べるのなら seq ってコマンドがある。
for i in `seq 100` とか。
bash 3.0 以降なら seq の替わりにこんな書き方も出来るよ。 for i in {1..100}
661 :
659 :2006/05/29(月) 03:41:54 ID:urN8bWVv
>>660 ありがとう。知らなかった。
でも、うちではまだ使えないみたい。
GNU bash, version 2.05b.0(1)-release (i686-pc-linux-gnu)
ksh由来の算術つかえばいいじゃん。
>>660 情報THX
エロ画像落すのが楽になる鴨 w
GNU bash, version 3.1.7(1)-release-(i386-redhat-linux-gnu)
cnt=0 while [ 0 ] do cnt=`expr + 1` … done が無難な悪寒…。
Linuxは : が使えないのか。
つ while :
Linux と言うよりは、shell の問題でそ? POSIX な bourne shell なら使える。 てか while : のつっこみ乙 ずっと気になってた
for ((;;)) なんかは? ;;の前、あいだ、後にナンカ入れてもいいし。
>>669 bash 限定ならそれなりに使えるな。
672 :
login:Penguin :2006/05/31(水) 04:24:55 ID:VPSqygej
bashのシェルスクリプトでlsをしてサブディレクトリ名を列挙したいです oldIFS=$IFS IFS="\n" for elem in $(ls -1 $dir); do if [ -d $elem ]; then echo $elem fi done IFS=$oldIFS と書いたのですができませんでした
>>672 find 使うんじゃダメなん?
$ find $dir -mindepth 1 -maxdepth 1 -type d -print
for i in $dir/* ; do test -d $i && echo $i ; done
ls -aF $dir | grep '/$' | sed 's/\/$//'
676 :
login:Penguin :2006/05/31(水) 10:21:55 ID:1zkbxtPB
cronスレがなかったのでこちらでお聞きさせて下さい。 analog を深夜にバッチで動かしたいのですが、 ana.sh というファイルに #!/bin/sh /usr/bin/analog -G +g/home/sites1/site.cfg /usr/bin/analog -G +g/home/sites2/site.cfg と記述して crontab -e にて 30 4 * * * * /home/ana.sh を動かしています。 ところが、結果は /bin/sh: *: command not found となり 動いてくれません。 シェルから直接 #]/home/ana.sh と叩くと動いてくれ、結果も満足するものを出してくれます。 作業は全てrootで行ってます。 何が原因で動かないの?
>676 あっはっは、わかっちゃったけど答えはくだ質で。
681 :
672 :2006/05/31(水) 17:07:16 ID:SiCy2Kb+
できました ありがとうございます 成果物を発表します ファイル内の文字を見つけるシェルスクリプトです. findwordと名づけました #!/bin/bash function call_grep { word=$1 dir=$2 file=$3 grep -s -H ${word:1:${#word}-2} $dir\/${file:1:${#file}-2} } function ondir { word=$1 dir=$2 file=$3 call_grep $word $dir $file for subdir in $dir/*; do if [ -d $subdir ]; then ondir $word $subdir $file fi done }
682 :
672 :2006/05/31(水) 17:08:08 ID:SiCy2Kb+
# ここからmain word="" dir="." file="*" oldIFS=$IFS IFS="\n" # 引数チェック if [ $# -lt 1 -o $# -gt 2 ]; then echo "Usage: fw word [file]" exit 1 fi # 検索文字列を取得 if [ $# -ge 1 ]; then word=$1 fi # 検索対象ファイル名を取得 if [ $# -ge 2 ]; then file=$2 fi # メタキャラクタが展開されないように{}で囲んで呼び出し ondir {$word} $dir {$file} IFS=$oldIFS
>>681 . で始まるディレクトリが検索対象にならないけどいいのか?
つーか、grep の -r じゃだめなん?
684 :
672 :2006/05/31(水) 18:32:57 ID:SiCy2Kb+
さっそくバグが見つかりました
IFS="\n" で改行を区切り文字にすることを望んだのですが
文字nが区切り文字となっていました (とりあえずコメントアウトで対応しました
>>683 for subdir in $dir/*; do を
for subdir in $(find $dir -mindepth 1 -maxdepth 1 -type d); do にしました
grepの-rオプション初めて知りました.
つーか、find 使うんなら、単に find /PATH/TO/TARGET/DIR -type f -exec grep REGEXP {} \; で良いんじゃ? grep -r が使えなくても、これでおk
686 :
login:Penguin :2006/06/01(木) 00:43:10 ID:8xyw2hha
awk の正規表現の表し方が分からないんですが、 ^ap$ を含む行を表示させるにはどう書いたらいいですか? awk '/^ap$/ { print }' ファイル名 ←どこが間違っていますか? 誰か教えて‥
687 :
login:Penguin :2006/06/01(木) 00:47:40 ID:8xyw2hha
ファイルの中身はこんな感じです 00001 aaa 001 ap bap001 AAAAAAAAAA 00002 aaa 002 db bdb002 BBBBBBBBBB 00003 bbb 003 ap bap001 CCCCCCCCCC 00004 bbb 004 db bdb002 DDDDDDDDDD
689 :
login:Penguin :2006/06/01(木) 00:50:07 ID:8xyw2hha
‥というと?
「^」は行頭。 「$」は行末。
691 :
login:Penguin :2006/06/01(木) 00:54:57 ID:8xyw2hha
文字列はブランクで区切られるから、 文字列の頭が^で 文字列の最後が$という風ではないんですか?
693 :
login:Penguin :2006/06/01(木) 00:59:34 ID:8xyw2hha
そうですか‥ 文字列ではなく、行なんですか‥ では、この場合にはどういった書き方をすればpsのみの文字列と一致します?
>>687 の1行目と3行目をひっかけたいだけなら
awk '/ ap / { print }' でいける。
ap が行頭に来るときとか
区切りが TAB その他だったりとかの場合があるなら
話が変わってくる。
処理系によっては単語の境界を表現できるものもある。
grep '\bap\b' とか。
696 :
login:Penguin :2006/06/01(木) 01:11:51 ID:8xyw2hha
目的としては、15〜16バイト目が「ap」となっているレコードをひっかけたいんです。 ヒントをください。あと、TABではなく半角ブランクです。
697 :
login:Penguin :2006/06/01(木) 01:15:30 ID:8xyw2hha
awk '/ ap / { print }'だと、 1行目と3行目だけではなく、 2、4行目もひっかかってしまうんですよ‥
>>696 awk ってレコードって概念無かったっけ?
それを上手く使えばいけそうな気がする。
>>696 話が違うじゃねーか。
それなら
awk '/^..............ap/ { print }'
>>697 なんでひっかかんの?
700 :
login:Penguin :2006/06/01(木) 01:22:02 ID:8xyw2hha
多分bap001-bap002という文字があるからじゃないでしょうか‥
701 :
login:Penguin :2006/06/01(木) 01:23:34 ID:8xyw2hha
>>698 すいませんawkは初心者なもんで、
その概念が全くわかりません。
702 :
login:Penguin :2006/06/01(木) 01:24:32 ID:8xyw2hha
>>698 すいませんawkは初心者なもんで、
その概念が全くわかりません。
703 :
login:Penguin :2006/06/01(木) 01:25:38 ID:8xyw2hha
>>698 すいません。初心者なもんで、その概念が全く分かりません。
704 :
login:Penguin :2006/06/01(木) 01:43:56 ID:6G8R1aVM
殺すよ
>>700 「/ ap /」は「bap001」にはマッチしないっしょ。
釣りなのかな。
>>701 レコードという概念に用がなく
単に正規表現にマッチする行を抜き出したいだけなら
grep でいいじゃん。
707 :
login:Penguin :2006/06/01(木) 01:48:36 ID:6G8R1aVM
ていうか
awk '/ ap / { print }' で2,4行目がひっかかるわけねえじゃねえか
2,4行目は " ap "なんて含まれてないし
>>697 なに言ってんの
もう一回見直せ
708 :
login:Penguin :2006/06/01(木) 01:50:28 ID:6G8R1aVM
awk始めて5日の俺でもこれくらいは簡単にできたぞ
awkならindex使っちゃえ。
awk 'substr($0,15,2) == "ap"' awk 'BEGIN{FIELDWIDTHS="14 2"} $2 == "ap"' awk '$4 == "ap"' 結果は同じだけど少しずつ意味が違うので、そのへんはてきとーに。
711 :
login:Penguin :2006/06/02(金) 00:01:39 ID:8xyw2hha
すみません問題解けました。 みなさんありがとうございます。 まだ初めて一日目なので全く分からずみなさんにご迷惑をかけました。
712 :
login:Penguin :2006/06/02(金) 00:04:16 ID:rwsot8dG
ちなみに各項目が可変の時はどうすればよいんですか? テキストファイル(a.txt)があったとして。 ---ここから------------------------------ 000001 aaa 001 ap bap001 AAA 00002 aaa 002 db bdb002 BBBBBBBB *0002 aaa 002 db bdb002 FF 003 bbb 003 ap bap001 CCCC 000000004 bbb 004 db bdb002 DDDDDDD ---ここまで------------------------------ 問題としては‥ @a.txtファイルを読み込み、4つ目の項目が「ap」となっているレコードを ファイル(b.txt)に出力して下さい。 但し、先頭が*の場合は、ファイル(b.txt)に出力しないで下さい。 Aa.txtファイルを読み込み、5つ目の項目の先頭3バイトがが「bdb」となっている レコードの、 6つ目の項目をファイル(c.txt)に出力して下さい。 こういった場合です。
宿題は自分で調べて書くから意味があるんだ。
来年はちゃんと授業聞こうな。
715 :
login:Penguin :2006/06/02(金) 00:22:32 ID:rwsot8dG
宿題ではなく自習をしています。 中学なので授業とかはないんですよ‥ それで書き込みました‥
716 :
login:Penguin :2006/06/02(金) 00:36:16 ID:rwsot8dG
ちなみにこれじゃあ駄目でしょうか? @awk ' $4 == "ap" { print }' a.txt > b.txt Aawk ' $5 = "bdb" { print $6 }' a.txt > c.txt
どっちも駄目だし、すべて一行野郎にするなよ。 @はnextとか、Aは正規表現をちゃんと使え。
中学生だったら時間がめちゃくちゃあるだろうから自力で頑張れ 陰ながら応援している。手は貸さないが
□ >但し、先頭が*の場合は、ファイル(b.txt)に出力しないで下さい。 これがないよ。 あと、アクションは {print} だけなら省略できる。
720 :
login:Penguin :2006/06/03(土) 01:56:02 ID:IqdR3P7a
出来ました。 誰か指摘お願いします。 @awk '{ if($1!~/^\*/){if($4=="ap"){print}} }' a.txt > b.txt Aawk '($5~/^bdb/){print $6}' a.txt > c.txt
間違っちゃいないが@はifを減らせるな。
722 :
login:Penguin :2006/06/03(土) 02:25:51 ID:IqdR3P7a
723 :
login:Penguin :2006/06/03(土) 12:44:42 ID:TXm2oY86
@ cat a.txt | awk ' $4 == "ap" && /^[^*]/ { print }'
1つのノード ( 管理ノード ) から , そのノード自身や他複数ノードを相手に いろいろゴニャゴニャするのが目的です。 シェルスクリプトに複数オプションに 1. -c オプション : コマンド ( やりたいこと , 必須オプション , 10 種類程度 ) 2. -f オプション : ファイル名 ( コマンド種 ( 例えばログを見るとか ) によっては必要 ) 3. -n オプション : ノード名 ( 他ノードに ssh とか expect でアクセスするコマンドで種で使用 ) 4. -p オプション : ログインパスワード ( 他ノードに ssh とか expect でアクセスするコマンドで種で使用 ) の機能を付けるとして , -c オプションによって 5. 他オプションはいらない場合もある 6. -f オプション指定のみでよい 7. -n だけ必要 8. -n と -p が必要 と必要なオプションがまちまちだったりもします。 複数オプションが必要な場合 $ maint.sh -c hoge1 -n node000 $ maint.sh -n node00 -c hoge1 とオプションの入力順は問わないとして , 未定義なオプション $ maint.sh -x hogehoge はエラーメッセージ ( -x ダメポとヘルプメッセージ というか usage ) を表示させたい。 オプション指定は $# が 0 になるまで while で回して shift して刈るとして 何番目のオプションが -c なのか -n なのかを判定するのに , うまくすっきり できる方法がいまいち纏まらないです。 説明 ( 命題 ) が下手でスマソですが , アドバイスください。
725 :
724 :2006/06/10(土) 12:16:16 ID:IBZqYfFj
あと , $maint.sh -c hoge1 -c hoge2 と同じオプションをダブらせたりとした場合もエラーメッセージ表示 させたいです。
>>724 オプション指定は $# が 0 になるまで while で回して shift して
このくらい複雑なオプション指定なら、/usr/bin/getopt,getopts使うべきでは。
ディストリによっては入ってないんだっけ?
一番内側のループは case "$1" in -c) ;; -f) ;; *) echo $1はダメポ esac かなぁ。オプション毎に変数に値を入れておけばダブりチェックは出来そう。
>>724 自分ならoptcとoptfとoptnとoptpの四つのスクリプトに分けます。
どうしてもまとめたいなら後でoptallでラップする。
(一つにする必然性ある?)
case "$1" in
-c)
optc
;;
-f)
optf
;;
optc〜optpを使ってスクリプトを書く使い方の方が便利だと直感的に感じる。
分割と階層化、整理整頓。
あるテキストから正規表現でマッチした文字列を削除するのは sed 's/正規表現//' を使って一発で出来ますが、逆に正規表現にマッチした文字列だけを 抽出するにはどうしたらいいのでしょうか?とりあえず、 sed 's/\(正規表現\)/\n\1\n/' | grep 正規表現 などと無理やりやってはみたのですが、きっと一発で出来る簡単な コマンドがあるような気がしたのでお尋ねしています。ちなみに sed 's/\(.*\)\(正規表現\)\(.*\)/\2/' では、マッチさせたい\2の頭の文字列が\1の最後の方にマッチして しまうことがあってうまく行きませんでした。
>724 古い手だがオプションごとに2^nな重み付けして加算したらどだ。 値の評価に応じたエラーを出せばよい。
>>730 レスありがとうございます。&がパターンスペースのマッチした部分を参照する
ということはわかったのですが、置換をしても&以外の部分は残ってしまうので
&の部分だけを切り取る方法がどうしてもわかりません。&は変数か何かで後から
参照出来たりするのでしょうか?
734 :
733 :2006/06/10(土) 22:17:25 ID:qVDPaaNu
訂正 VERSTRが2.10.1の場合 NUM=$(expr $VERSTR : "\([0-9]*\)") でNUMには2が入ります。
>>729 &ってパターンスペースでしか参照できないんじゃなかったっけかな。
漏れの知識だとパターンを記号で囲って、
その記号の外側を消してゆく処理を思い浮かべてしまう。
sedだとこんなん感じw
s/\(pattern\)/<<&>>/g;
s/>>[^>]*<<//g;
s/^[^<]*<<//;
s/>>[^<]*$//
perl -ne '/(test)nanodesu/g;print "$1\n";'
なんかいろいろ案が出てるけど、729の >sed 's/\(.*\)\(正規表現\)\(.*\)/\2/' で方針としては正しい。 >では、マッチさせたい\2の頭の文字列が\1の最後の方にマッチして >しまうことがあってうまく行きませんでした。 おかしなマッチしてしまう正規表現が問題。 最長一致なので、最初の .* で意図しないところまでマッチしてしまう。 そうならないように .* ではなく [^文字]* とか状況に応じててきとーに変える。
>>737 どれでも良いところで敢えて自分の意見が正しいと行ってしまう神経に乾杯。
739 :
729 :2006/06/11(日) 10:04:58 ID:BbTEJ+qg
皆さんありがとうございます。 色々なアプローチの仕方があることがわかり勉強になりました。 それぞれ教えて頂いた方法で試してみて、理解を深めたいと思います。
740 :
login:Penguin :2006/06/16(金) 02:45:12 ID:v0D7ixZG
>>740 そのスレで書かれてるように、値を戻す必要はない。で終了。
awk側からsh側って発想がヘンなのであって、
UNIXでのプログラムの基本はパイプにそったたった1本のテキストの流れだ。
awkを含む各種コマンドはそれを加工するフィルタにすぎない。
>>740 result=`echo $2 | test.awk`でよくね?
>>740 $2 じゃなくて $1 になりそうな気がするんだけど。
#!/bin/bash
echo \$0 $0
echo \$1 $1
echo \$2 $2
みたいなスクリプトを書いて確かめておいたほうがいい。
#!/bin/bash
INPUT="$1"
echo "INPUT = $INPUT"
AWKOUTPUT="`echo $INPUT |test.awk`"
echo "AWKOUTPUT = $AWKOUTPUT"
>>741 パイプ使いまくって全部一行で書くってのを推奨するのか?
途中の段階を保存する方法を知らないとそうなる気がするのだけれど。
入力→パイプ→(パイプ→パイプ→パイプ→パイプ→)出力
の流れは変わらないと思うがね
ていうか
>>741 は単に概念的な話であって具体的なテクニックの話ではなさそうだ
「戻したい」と表現したい感覚はわかる
他のコマンド(awk)の出力をスクリプト中で受け取る方法がよくわからん、という話っぽいので
バッククォートで括る
>>742 で答えだと思う
>>742 のようにすれば変数 result に echo $2 | test.awk の実行結果が入る
あえて結果をシェル側に取り込みたい時はテンポラリなファイルに書き出して 後段で読み込むということもある。 素直にパイプや変数だけでは書きづらい処理のときには有効。 もっともこの場合 awk $* とかで呼び出して、全部awk内で処理しちゃった方が 柔軟に書ける悪寒。
つ FIFO(名前付きパイプ)
>>744 そのやり方は誘導元でもらっていましたがアホか。と言われていました。
だからそれはおかしいんだと思います。
>>747 誘導元を見てたけど、「アホか」とか言われてたか?
結局「値を戻す」ってのは、何がしたいの?
よくわかってなかっただけじゃね?
よくわかってなくてもやりたいことは変わらないだろ やりたいこと言ってくれればアドバイスできたりできなかったり
752 :
login:Penguin :2006/06/20(火) 06:39:29 ID:zbAvqj6J
a.exeに-xxという引数を与えます。 # a.exe -xx [Etner] aaaaaaa このように1行の結果が表示されました。この結果を変数に入れたくて myval=a.exe -xx echo $myval とやりましたが、違いましたね。どうすればよいですか?
素人考えだけど myval=`a.exe -xx` # バッククオートでくくる ってやってみたらどうかな。
754 :
login:Penguin :2006/06/20(火) 09:11:08 ID:zbAvqj6J
バッククウォートにしたら、a.exeを引数付きで実行が できるようになりました。 しかし、左辺には値が入りませんでした。 a.exeは値を返すものではないから、無理かもしれません。 a.exeが標準出力する文字列を変数に入れたいです。
ぱんつ上げて、ぎゅっぎゅっぎゅっ、ぎゅっぎゅっぎゅっ
myval=`a.exe -xx` echo "$myval" myval=$(a.exe -xx) echo "$myval" myval="a.exe -xx" echo "$myval" myval='a.exe -xx' echo "$myval" echo myval
758 :
login:Penguin :2006/06/20(火) 15:19:09 ID:zbAvqj6J
どれもだめでした。a.exeが返す値が変数に代入されるみたいで、 やろうとしているa.exeが出す標準出力文字を変数に入れることは できませんでした。evalでやってみましたが、それもだめでした。 変数に値を入れる方法としてこのようにできたらよいのですが。 "a.exe -xx" > myval
>>758 シェルは何使ってるんだよ?
まさか cmd とかじゃないよね?
760 :
login:Penguin :2006/06/20(火) 15:30:44 ID:zbAvqj6J
>>759 bashかshのどっちかだと思います。
>>760 bash で出来ないとか考えられん。
% echo $BASH_VERSION
の結果を書いてみ。
そもそも、なんで .exe なのかと。cygwin か?
cygwinだろう。 7割でcygwinだったで 3割が標準エラー出力に出してるプログラムだった に一票。 そもそも「だめでした」とだけ口走るような奴に親身親切にしてやる義理などないわ。
Cygwin だとできないもんなん?
>>762 いや、たとえ cygwin でもシェルは bash だから出来るはず。
>>758 を見ると
a.exeが返す値が変数に代入 != a.exeが出す標準出力文字を変数に入れる
と言っているから、現状は main 関数が返す戻り値が入るって事でしょ。
bash で言うところの $? かな。そんな結果、あり得ないって。
で
> 変数に値を入れる方法としてこのようにできたらよいのですが。
> "a.exe -xx" > myval
って書いていることから、何も分かっていないことは明白。
全然意味違うやんと。
765 :
login:Penguin :2006/06/20(火) 19:46:10 ID:6wP2WKm3
そもそも
>>758 の言ってる意味がわからん
a.exeが返す値 と a.exeが出す標準出力文字 ってどう違うの?
コマンドラインで a.exe -xx とたたいて出た結果 aaaaaa を変数に格納したいんだろ?
a.exeが出す標準出力文字 が aaaaaaだとしたら
a.exeが返す値 は何?
myval="a.exe -xx"
echo $myval
↑これを実行した結果なにが表示されたの?
ちなみにCYGWINでも全然問題なく出来るよ、デフォルトでbashだしね
まさか今使ってるシェルが難なのかもわからないやつが起動シェルを変えられるとも考えられないしね
>>765 $ cat hoge.sh
#!/bin/sh
echo hoge
exit 1
$ ./hoge.sh
hoge
$ echo $?
1
$
hoge が標準出力に書かれる文字列。
1 が返す値。
767 :
login:Penguin :2006/06/20(火) 20:02:24 ID:6wP2WKm3
それだったら変じゃない? myval=$(a.exe -xx) これでmyvalに返り値が代入されるわけないじゃん 少なくとも俺はそんなの見たことない ちなみに俺はbashとshとcshしか使ったことないけど 考えられるとしたらこれら以外のシェルじゃないの?
結局単純なポカミスでした(テヘ みたいなオチじゃなかろうな?
>>767 おいおいw
VAL=`a.exe -xx`
と
VAL=$(a.exe -xx)
は同じ意味だよ。
バッククォートはクォートと間違えやすいから$()の表記もあるのです。
771 :
login:Penguin :2006/06/20(火) 21:11:28 ID:6wP2WKm3
>>769 んなこたーわかっとるわ
それでなんで返り値が代入されちゃうのかがわからんわ
ちなみに俺の環境はCYGWIN、会社ではLINUX
馬鹿だから
773 :
login:Penguin :2006/06/20(火) 21:15:36 ID:6wP2WKm3
>>772 えっ?
馬鹿って俺?
俺のこと?
何、喧嘩うってるわけ?
おまえそれで本当にいいのか?
馬鹿な子ほどかわいいっていうから、ID:6wP2WKm3は特上の美女だな
775 :
login:Penguin :2006/06/20(火) 21:31:25 ID:6wP2WKm3
あら、そんな、美女だなんてっ・・・ 俺ァ男じゃ!!!っボケが
エスパー達が集うスレはココですか?
エスパーまみ
a.exe -xx | od -a とやるとどうなる?
bsh でも bash でも直前に実行したコマンドの ステータスコードが欲しいのなら $? だ。 a.exe -xx myval=$? 単に a.exe の実行が成功したか否かで処理を分けたいだけなら わざわざステータスコードを変数に格納する必要は無いけどな。 if a.exe -xx ; then echo "success" else echo "error" fi
780 :
login:Penguin :2006/06/21(水) 02:40:10 ID:mv0GRGyF
>>761 # echo $BASH_VERSION
2.05b.0(1)-release aは32ビットELFです。
781 :
login:Penguin :2006/06/21(水) 02:43:12 ID:mv0GRGyF
>>762 ハズレだボケ!Linuxだよバーカ!!
>>781 1.
>>762 の“3割”の方の当否はどうだったの? やりたいことは出来たの?
2. シェルスクリプト総合スレで、シェルスクリプトの基本さえ勉強してない君が、
どうしてそんなに居丈高なの?
783 :
login:Penguin :2006/06/21(水) 09:17:50 ID:mv0GRGyF
>>782 “3割”の方、読んでいませんでした。言われてみれば
標準出力ではなくて標準エラーかもしれません。
他の方が絶対できるはずみたいなことを書いていたので
753,756をa.exe以外(ifconfig -aなど)で実行すると変数に入りました。
できなかった原因はa.exeだったわけです。
a.exeをhttpdにして引数を-tにすると、僕がa.exeでできなかった
というのを誰でも再現できると思います。そういう状態です。
>>782 >>762 の忠告(に見えんが)は基本だからな
「俺のやってることや起こったことについては一切教えてやらんがおまえらきちんと答えろバカ」
という状態で何ができるというのか
情報小出し君は煽られて当然
問題の解決などできぬと知れ
>>783 a.exeに
echo "戻り値"
を一行足せば全ての謎が解決するよ。
>>783 % httpd -t 2> /dev/null | wc -l
の結果は 0 です(=標準エラー出力)ですから。
つまらないオチでした。
きちんと謝れば、皆が気持ちよく一日をすごせるのに。
どっちのスタンスが良いだろうか? 1. さっさと正解を教えて「もう来るな」と言う 2. 絶対に正解を教えない
789 :
742 :2006/06/21(水) 15:07:21 ID:IEkFGiJz
>>786 標準エラーを取り込みたいなら stderr を stdout にマージすれば?
$ httpd -t 2>&1 | wc -l
>>789 なんで教えてもらってるんだ? オレ…
違うよ、オレじゃないよ。
>>788 頭の足りないバカだとわかった時点でひとしきり煽って遊ぶが
エラーと前提の詳細を結局最後まで教えてくれなかったので誰も正解を教えられない
だと思う
もうスルーでいいんじゃね。
釣りじゃなかったんだ 本物だったんだ
おそまつな釣りでした。
796 :
login:Penguin :2006/06/21(水) 22:20:27 ID:XIoRED2O
標準エラー出力を思い切り標準出力って書くやつはしんじまえ それくらいの区別もつかんやつはしんじまえ
797 :
login:Penguin :2006/06/21(水) 22:30:15 ID:XIoRED2O
おまえの人生コアダンプ
>>765 myval="a.exe -xx"
echo $myval
↑これを実行した結果なにが表示されたの?
ちなみにCYGWINでも全然問題なく出来るよ、デフォルトでbashだしね
まさか今使ってるシェルが難なのかもわからないやつが起動シェルを変えられるとも考えられないしね
ぷっはー!w
799 :
login:Penguin :2006/06/22(木) 22:55:16 ID:QvJn1WH6
>>798 何?
どこがぷっはーなのか3行でまとめろよ
だから その クォ(ry
myval="a.exe -xx" echo $myval ↑これを実行した結果なにが表示されたの? a.exe -xx
802 :
799 :2006/06/24(土) 03:50:34 ID:4R6vhkzi
myval="a.exe -xx" ↑何これ? あほですか? `←これと "←これの区別もできんの? あほですか?
804 :
login:Penguin :2006/06/24(土) 19:09:06 ID:M/KKhdyS
ここの連中は声にする度胸の無いガキでFAだから期待すっだけ無駄だぜ。 毎日毎晩、串挿してシコシコキーボード叩いてろって一蹴しちゃえ。 ちなみに俺と話すならスカイプIDは dj-tama で検索なりしてくれればOK。 どっかで見覚えあるID? 細かい細かい。知ったこっちゃね。
clear
806 :
login:Penguin :2006/06/24(土) 22:55:46 ID:ZfUSZWls
ちょっと助けて下さい。 awkで、検索した1行の複数の列の内容を、 それぞれ別のシェル変数へ代入したいのですが、 良いやり方を思いつきません。 イメージとしては、 TITLE1 DATA1 DATA2 TITLE2 DATA3 DATA4 TITLE3 DATA5 DATA6 という TextFile があるとして、 hoge=`awk $1 ~ /TITLE1/ {print $2} TextFile` huga=`awk $1 ~ /TITLE1/ {print $3} TextFile` とやるのと同じ結果がほしいのです。 ↑のやり方はカッコ悪いので、どなたかスマートなやり方を教えて下さい。
配列を使うのはだめ? a=($(awk '/TITLE1/{print $2,$3}' TextFile)) echo ${a[1]} とか
set -- `grep TITLE1` TextFile echo $2 echo $3
809 :
login:Penguin :2006/06/25(日) 03:08:39 ID:zOOlhhVH
fedora core5を使用しています。 以下の入力でエラーが出ました。 [root@user ~]# rpmbuild -tb openssh-4.2p1.tar.gz エラー: 旧来の構文はサポートされません: copyright エラー: 7 行目: 不明なタグ: Copyright: BSD 解決策お願いします。
>806 cat textfile | while read title hoge huga do if [ "$title" == "TITLE1" ] ; then break unset hoge huga done
>811 fiわすれてやがる...orz
フィヒw
>>811 その発想で書くのならこんな感じかな。
while read title hoge huga ; do
if [ "$title" = 'TITLE1' ] ; then
break
fi
done < textfile
817 :
806 :2006/06/25(日) 20:09:28 ID:MlXCRoHi
レスありがとうございます。 いろんなやり方があるものですね。 awkの機能で出来るかと思ったのですfが、そういうワケでもなさそうですね。 awkを使いたいのには理由があって、 CDDBから取ってきたトラックリストから項目ごとに変数に入れたいんです。 このリストの形式が、 TTITLE0=Artist Name / Track Title という形式なんです。 空白入りの文字列を取り出さなければならないので、 sed -e ''s/\(^[^\=]*\)\=/\1 \/ /' とやって awk -F" / " で処理できるようにはしたんですが、そこで>806のやり方で 詰まってしまったんです。 レスで教えて頂いたやり方だと、空白に引っかかってしまうのです。 すいません。最初からこう書いておけばよかったですね。 awkの機能で出来るかと思ったので。
なんで awk でやりたいのにシェルの変数に格納したいのかわからん。 っつーか、なんで awk が awk 以外の言語の変数に値を格納できる機能が あると思ったのかわからん。 # perl で C の変数をセットできますか? -- できるわけねーだろ。 eval `awk -F= '$1=="TITLE1"{split($2,a," / ");print "hoge=\"" a[1] "\"\nfuga=\"" a[2] "\""}'`
819 :
806 :2006/06/25(日) 22:08:17 ID:MlXCRoHi
>818 できました! ありがとうございます。 ># perl で C の変数をセットできますか? -- できるわけねーだろ。 そりゃそうですよね。 シェルから呼び出して使ってても、bashとawkは別個の処理系ですもんね。 うっかりしてました(^^;
>>820 seq 2 100 | factor | awk 'NF == 2 {print $2}'
おれは↑これがすき。
sh の例があるのに「bashで」って言ってんだから 外部コマンド使わずにってことじゃないかな。
>>822 外部コマンド使わずにって
/etc/ にあるコマンドを使わないってこと?
/etc以下にあるコマンドってあんま単一目的以外に使い出もないような気もするが lsでなく echo * だとかそんなことだと思われ
825 :
天才現る :2006/06/26(月) 20:28:12 ID:MrWTpj7s
while(true); do if [ aaa -eq 素数 ] then echo $aaa fi aaa=`expr aaa + 1` if [ aaa -gt 100 ] then break fi done
826 :
天才現る :2006/06/26(月) 20:29:00 ID:MrWTpj7s
$ ↑忘れてたからすきなだけ持ってけ
821はいかにもらしくていい感じだと思いますよ。 正規表現だとこうかな seq 2 100 | factor | grep '^[0-9]*: [0-9]*$' 最初に頭に浮かぶのは20行くらい、最後は一行になってしまう面白さ。
factor を使うぐらいなら primes で一発だろ。 GNU coreutils には factor だけがあって primes がないから たいていの Linux にはないかもしれないけど、 もともとは同じ man を共有していた兄弟コマンドなんだし。
では seq 2 100 | factor | grep ': [0-9]*$'
ついでに #!/bin/bash # <<primes>> seq $1 $2 | factor | grep ': [0-9]*$' | sed -e "s/[0-9]*://"
CSV 形式のファイルを最終的には Excel の表に したくって , 文字列で ... { } カッコの中にあるカンマだけをスペースに変換 したいんだけど , おバカなので分かりません(´・ω・`)。 例としては "hogehoge1",{"hogehoge2"},1,2,{"hogehoge3","hogehoge4"} の場合に "hogehoge1",{"hogehoge2"},1,2,{"hogehoge3" "hogehoge4"} と { } 内の "hogehoge3" と "hogehoge4" の間のカンマだけ スペースに変換 ... といった感じです。 よろ。
834 :
なぁなぁ〜 :2006/07/04(火) 17:57:26 ID:my5N4gNu
「どのシェル使ってる?」スレから来ました。 snmpの勉強がてら、適当な内容で作ってみたのだが・・・。 command not foundやら、許可がありませんやら・・・。 なにが悪いのだろう・・・?おちえてくだせぇ〜。 ==================================================================== #!/bin/sh DISK=(.1.3.6.1.4.1.2021.9.1.9.1 .1.3.6.1.4.1.2021.9.1.9.2) COUNT=0 echo "#####ディスクの領域%状態を調査します。#####" for i in ${DISK[@]} do PERCENT=`snmpget -v1 -c public $1 ${DISK[${COUNT[@]}]} | awk -F " " '{print $4}'` case ${COUNT[@]} in 0) echo ">>>/varディレクトリの使用率は、" $PERCENT"%です。<<<" ;; 1) echo ">>>/usrディレクトリの使用率は、" $PERCENT"%です。<<<" ;; esac if `$PERCENT>=5` then echo "現在使用領域がまだ5%を超えたばかり、全然大丈夫です。" else echo "まだ大丈夫。らくしょーです。" fi COUNT=`expr $COUNT+1` done ====================================================================
835 :
なぁなぁ〜 :2006/07/04(火) 17:58:28 ID:my5N4gNu
↓実行結果↓ #####ディスクの領域%状態を調査します。##### >>>/varディレクトリの使用率は、 2%です。<<< ./kadai.sh: line 1: 2: command not found まだ大丈夫。らくしょーです。 ./kadai.sh: line 1: /root/bin/10: 許可がありません まだ大丈夫。らくしょーです。
>>834 > if `$PERCENT>=5`
なんだよこれ。
>>833 #!/bin/awk
function quote(s, i, c) {
while (1) { c = substr(s, i ++, 1); if (c == "") return i
printf("%s", c); if (c == "\"") return i}
}
function brackets(s, i, c) {
while (1) { c = substr(s, i ++, 1); if (c == "") return i
if (c == ",") printf(" "); else { printf("%s", c)
if (c == "}") return i; else if (c == "\"") i = quote(s, i) }}
}
{
i = 1; while (1) { c = substr($0, i ++, 1); if (c == "") break
printf("%s", c); if (c == "{") i = brackets($0, i)
else if (c == "\"") i = quote($0, i) } print("")
}
>#!/bin/awk ……えー。
……と文句つけるだけじゃアレなので。 #!/usr/bin/awk -f BEGIN{ RS = ORS = "," } /^{/{ ORS = " " } /}$/{ ORS = "," } { print }
840 :
login:Penguin :2006/07/05(水) 00:08:18 ID:kFt/2fJW
>834 $PERCENT いらないか。$4のままでいいよね。ゴメ。 MIB値からdiskの%を取り出して、何%以上とか以内とかで処理を分けようと してたのです。別にsnmp.conf 何%になったら云々て設定できるけど、 スクリプトの勉強として作ってみた次第なのですよ。
自分にレスしちゃった。 >836ね
だめだめ、違った。$4のままじゃ、余計な文字がはいるから整形して 整数だけ$PERCENTに入れたんだった・・・。 もうね、わかんね。
if文がおかしいことはわかった。
` ` が何だかわかってないでしょ。
コマンドがなんたらだっけ。なんか変だったから、とりあえず入れてみたw if [ $PERCENT -ge 5 ] でエラーは消えました。 スペースの大事さが身にしみた。
あと、COUNT=`expr $COUNT+1`もおかしかった。 $COUNT+1 →$COUNT + 1 これもスペースがらみ・・・。 なんとか意図通りに動きました。今晩このスレ一から読んでみまつ。 色々ヒントというか、はまりやすい変な罠が解説されてるかも。わくわく。
847 :
833 :2006/07/05(水) 17:22:05 ID:oTOZpsl3
>839 GJ! ばっちりですた。 ... でもまだ問題がありますた ... 。 "hogehoge1",{"hogehoge2"},1,2,"mou, damepo",{"hogehoge3","hogehoge4"} と , " 内のコメントに , があった場合 ... "hogehoge1",{"hogehoge2"},1,2,"mou damepo",{"hogehoge3","hogehoge4"} としたいのです。 前後の文字が 『 " { } 』 で無い場合の『 , 』をスペースに変換したいけど おバカなのでまたしても分かりません(´・ω・`)。 すみませんがもう一個おしえてください。
848 :
833 :2006/07/05(水) 18:58:26 ID:a7stFWq4
自己つっこみ >前後の文字が 『 " { } 』 で無い場合の『 , 』 だと "hogehoge1",{"hogehoge2"},1,2,"mou, damepo",{"hogehoge3" "hogehoge4"} の場合 , 1と2の間がダメで "hogehoge1",{"hogehoge2"},1 2,"mou, damepo",{"hogehoge3" "hogehoge4"} になっちゃうか ... 。 使いたい CSV ファイルを良く見ると 『 " 』 内のコメントは英語メッセージで 『 , 』 の後ろにはスペースがあるっぽい。 だとすると ... sed 's/ ,//g' だけでいいのかもしれないが ... やっぱ 『 " 』 内のコメント という条件もちゃんと考えないとダメっぽい(´・ω・)。
質問ス シェルスクリプトで先月を"2006-06"のような書式で出力しようとしています。 以下をawkのif文で作成しようと思ったのですが、なかなか上手くいきません。 #月の部分が10未満の場合 date "+%Y %m"|awk ' $2<10 { printf("%s-0%s\n", $1,$2-1 ) }' #月の部分が10、11の場合 date "+%Y %m"|awk ' $2>9 { printf("%s-%s\n", $1,$2-1 ) }' #月の部分が01の場合 date "+%Y %m"|awk ' $2==1 { printf("%s-12\n", $1-1) }' ↓こんな感じで1行にまとめたんですが、どこが間違ってて、どう修正すればいいか教えて下さい。 date "+%Y %m"|awk '{ if ($2==1) if ($2<10) if($2>9) printf("%s-12\n", $1-1) ; else printf("%s-0%s\n", $1,$2-1 ) ; else printf("%s-%s\n", $1,$2-1 ) }'
"%04d-%02d", $1+0, $2-1
>>849 GNU date を使ってるなら、
date --date="1 month ago" +%Y-%m
でいいんじゃない?
>>849 ifで押し通す一途さは反省した方がいいですよ。
やり方は何通りもある、解は一つだけではない事を忘れたらダメ。
レスありがとうございます。
>>850 以下のように直しましたが、else=それ以外の場合、が利かないです。
間違ってる箇所がおわかりでしたら指摘お願いします
date "+%Y %m"|awk '{ if ($2==01) printf("%04d-12\n", $1-1) ; else printf "%04d-%02d", $1+0, $2-1 }'
>>851 初めて知りました。凄い便利ですね。
ただ、テストはcygwin上でやってるのでうまくいくのですが、
本番は10年前のHP-UXなのでダメかも・・・
この辺はシェルで書きたくないな。 perl かなんか使えないの?
>>852 とは思うのですが、なかなか頭が回りませんで(汗
とりあえず、awkのifの使い方を覚える為にも今回は
この路線でいってみようかと。
連投すみません
>>854 シェルスクリプトが初めてのプログラム言語(?)でして(汗
>本番は10年前のHP-UXなのでダメかも・・・ Linux 板には Linux 以外でも通用する汎用的な知識を持ってる人は少ない。 よって、ここで聞いても求む解はまず得られない。要するに、板違い。 UNIX 板でも視野狭窄なアホは多いが、ここよりはまだマシ。 ↓GUN awk 必須。HP-UX ではたぶん不可。 awk 'BEGIN{print strftime("%Y-%m", systime()-86400*30)}' ↓たいていの環境でも動くだろうけどマネしちゃいけない汚ない例 date "+%Y%m" | awk '{ --$0%100?$0:$0-=88; printf("%4d-%02d\n",int($0/100),$0%100)}'
つーか本番環境が HP-UX で開発環境が Cygwin なら 完全に板違いだな。
>>857 厳しいお言葉の割りには、ご親切にありがとうです。
スレタイにawkってあったので、こっちでいいのかと思って
ましたが、UNIX板のシェルスクリプトスレも普通にawkの
話題が出てますね。
また行き詰ったら、あちらに相談させてもらいます。
>>ID:u4ZDwB8Q 喪前恥かしいから出てくんなや
>>847 #!/bin/awk
function quote(s, i, d, c, lc) {
while (1) { c = substr(s, i ++, 1); if (c == "") return i
if (lc == "\\") printf("%s", c); else if (c != " " || lc != ",")
if (c == ",") printf(" "); else { printf("%s", c)
if (c == d) return i } lc = c }
}
{
i = 1; while (1) { c = substr($0, i ++, 1); if (c == "") break
printf("%s", c); if (c == "{") i = quote($0, i, "}")
else if (c == "\"") i = quote($0, i, "\"") } print("")
}
>#!/bin/awk えー?
は?
865 :
742 :2006/07/07(金) 10:44:59 ID:fcVFtCvN
>>863 /usr/bin/awk にしないと気持ち悪い人?
手元の RedHat / Fedora Core ではこうなってたから、間違ってはいない。
/bin/awk -> gawk*
/bin/gawk*
/usr/bin/awk -> ../../bin/gawk*
>>863 じゃないけど
$ which awk
/usr/bin/awk
だしね。VineLinux3.2です。
大間違い。 #!/path/to/awk じゃなくて、 #!/path/to/awk -f にしないと動かない。
ls -l `which -a awk`
純粋awkスクリプトを許すのならPerlで書いたほうが傍目にもわかりやすいような希ガス
Perlで全部済むとか言ってやるなよ
Pythonがいいよな
Cでやれ。
#! /usr/bin/env awk -f
envは引数考慮してくれないからな
>>857 えー?
HP-UXも普通に使えますけど。
>>875 引数を解釈してるのは env じゃなくてカーネル。
>>876 使えるとしたら標準の awk ではなく GNU awk を追加インストールしてるんだろ。
↓のようなスクリプトの一部があるんだけど、 ループに使われる m の変数が0から始まらないのはなんで? h は0から始まるのに・・・。ちなみに、hもmもここでしか使われてないよぅ。 -------------------------------------------- for h in `seq 0 $HOST_count` do a=${HOST[h]} for m in `seq 0 $MIB_count` do b=${MIB[m]} done func_snmp $a $b done ------------------------------------------
>>878 適切に問題の切り分けしろよ。
俺のところではちゃんと動くぞ。
$ for h in `seq 0 2`; do for m in `seq 0 2`; do echo $h $m; done;
done
0 0
0 1
0 2
1 0
1 1
1 2
2 0
2 1
2 2
単体では動くんだけど、適切な問題の切り分けが出来なかった。 んで、一行順番入れ替えたら動いた。
881 :
忘れてた :2006/07/10(月) 10:39:30 ID:LojfYAgG
ありがとう
>>878 func_snmp が for m のループの「外」にあるけどそれでいいのか?
それだとfor mのループの存在意義がほとんどないぞ。
ループ全体を b=${MIB{$MIB_count}}に置換してしまえる。
883 :
:2006/07/10(月) 11:19:03 ID:LojfYAgG
>882 そう、それをfor mの中に入れたら、正常に動いたのです。
以下のような6行の文字列の内、"hogehoge"のみに000〜999という文字列を 順番付加してコピーしようと思っています。 { hogehoge mogemoge mogyu-moygu- moga-moga- } ↓ { hogehoge000 mogemoge mogyu-moygu- moga-moga- } { hogehoge001 mogemoge mogyu-moygu- moga-moga- } ・ ・ ・ { hogehoge999 mogemoge mogyu-moygu- moga-moga- }
下のスクリプトとsedやawkを組み合わせて考えたのですが、どうも いい考えが浮かびません。 どなたかお力をお貸しください〜 #!/bin/bash i=000 while [ $i -le 999 ] do echo "$i" 1>&2 i=`echo $i | awk '{printf("%03d",$1 + 1)}'` done
>>884 もとの6行がファイルにあるとして、こんなのはどうだろう
for x in $(seq -w 0 999);do sed "/hogehoge/ s/$/$x/" ファイル名;done
% which awk /usr/X11R6/bin/awk ちょwwwDebian www
>>884 #!/usr/X11R6/bin/awk -f
/^{$/ { h=1 }
h==0 { print }
h==1 && /^hogehoge$/ { l=l $0 "%03d" "\n" }
h==1 && ! /^hogehoge$/ { l=l $0 "\n" }
h==1 && /^}$/ { for(i=0;i<=999;i++) printf(l,i); h=0; l="" }
$ ll /usr/X11R6/bin
lrwxrwxrwx 1 root root 6 Jul 4 00:36 bin -> ../bin/
/usr/bin へのリンクじゃん。
それより
>>887 の PATH の順番がおかしい。
>>886 修行不足で、まだ完全に理解できてませんが、ばっちり動きました。
ありがとうございます。
>>888 awkも勉強始めたばかりで、さっぱりわかってないのですが、
とにかく実行速度が速いのに驚きました。ありがとうございました。
もっと精進しますですm(_ _)m
FC5でシェルスクリプトの勉強をしてるんですが、 $PWDや$PATHや$DIR_STACKなどの環境変数って そもそもどこで(どのファイルで)定義されているんでしょう? /etc/bashrc には、$PATHは記述されていたので イメージがわくんですが、 他の環境変数は見当たりません。 どっかに環境変数一覧を初期化してるファイルが 存在してるんじゃないかって思ってるんですが、 この考えが根本的に間違ってるんでしょうか??? エロイ人教えてよ!!
死ねよ厨
変数 $personal_dir が/home/xxxx/per となっています。 ファイル AAAの中身は次のようになっています ../../temo_folder /backto これを csh上のsed で /home/xxxx/per/temo_folder /backto とするのはどうしたらいいのでしょうか? sed 's/..\/..\/temo_folder/$personal\/temo_folde/g' AAA とやってみたのですが $personal/temo_folde /backto となってしまいます 初心者の質問で申し訳ありませんが教えてください
'を"にする
895 :
893 :2006/07/11(火) 23:35:49 ID:IIPfiq+y
>>894 早速のレスありがとうです。
それもやってみたのですが、出力結果がカラッポになってしまいます。
.を\.にする
897 :
893 :2006/07/12(水) 00:09:02 ID:LGy+DaqM
>>896 それはやってなかったので明日試してみます。
会社環境でしかできないので。
親切な皆さんありがとうです。
>>893 cshは分からないけど、
$ echo $personal_dir`cut -d '/' -f 3- AAA`
/home/xxxx/pertemo_folder /backto
% echo $personal_dir /home/xxxx/per % echo $personal personal: Undefined variable. だったらダイナソー。
901 :
893 :2006/07/13(木) 19:43:03 ID:3CztQj16
>>896 だめでした。変わらず。
>>898 うまく行きました!ありがとう
>>899 ダイナソー?すいませんよく意味がわからないです。
>900
区切り文字を変えてみるということですか?
シングルコーテーションのせいで変数が文字列として扱われてしまっているのですが
区切り文字を変えて解決するのでしょうか?
sed s:../../temo_folder:$personal/temo_folde:g AAA これは?
なぜ会社の先輩に聞かない
サンプルとして a.exe って書いてあるのを見ると、 つい avex を伏字にしてあるのかと思ってしまう。
スレ違いを承知で尋ねる [ 皆さん awk をなんて呼んでる? ぽくは、オークちゃん!!
老化現象その1 繰り上がりの足し算を間違える 老化現象その2 分数を2倍するのに、分母と分子の両方に2を掛けてしまう 老化現象その3 老化対策としてpythonの対話モードを電卓代わりにしていたが、 電卓ごときにスマートじゃないのでexprコマンドを使ってみる。 が、なぜか掛け算だけが出来ない。これはバグではないか?
>>908 老化現象その4
chmod -r hogeの"-r"をコマンドオプションと思い込んで詰まってしまう。
>>907 > が、なぜか掛け算だけが出来ない。これはバグではないか?
expr に渡す数式をちゃんとクォートしてないとみた。
↓こんな風に書いてないか?
$ expr 2 * 3
911 :
login:Penguin :2006/07/19(水) 17:53:18 ID:3lWh75/p
awkでprintつかって awk '{print $1 " datafile '+db2' size " $2 "M";}' で HOGE datafile '+db2' size 1000M FUGE datafile '+db2' size 500M って感じで定型文山ほどつくりたいんですが シングルクオーテーションをエスケープできず難儀してます awk '{print $1 " datafile \'+db2\' size " $2 "M";}' じゃだめなのね。出力にシングルクオーテーションを 含めたい場合はどーすればいいでしょうか? GNU Awk 3.1.1
>>911 awk '{print $1 " datafile '\''+db2'\'' size " $2 "M";}'
cat datatextfile|sed -e "s/[年]\|[月]/-/g"|sed -e "s/[日]/:/g" bash プロンプトからではうまく変換できますが、スクリプトファイルに 同じ文を入れて実行するとすべて空振り(何も変換されない)します。 export LANG=ja_JP.eucJP LANGUAGE=ja_JP.eucJP LANGVAR=ja_JP.eucJP LC_ALL=ja_JP.eucJP の行を入れて実行しましたが変わりませんでした。 何か必要なものがあるのではないかと思います。みなさまの知恵助けを必要としています。 環境;FC5 sed は version 4.1.5
>>913 スクリプトファイルの文字コードが SJIS ってことはないよね?
915 :
login:Penguin :2006/07/20(木) 10:24:44 ID:7oEuQoVS
>>914 ありがd
なぜか JIS でした。EUC-JP にエンコードしなおしたら正しく実行できました。
配下のフォルダ内にあるファイルの数を出力するにはどうしたらいいでしょうか フォルダ構成は2階層3階層、それ以上なっており、それぞれに格納されているファイル数が知りたいのですが。
find BUILD/ -maxdepth 3 | wc
find folder -type d -depth -exec sh -c 'echo -n {}; find {} -type f -print | wc -l' \; かっこわるい orz
919 :
login:Penguin :2006/07/20(木) 23:43:51 ID:AriyPYTd
a=$a a="$a" この違いが現れるような$aの値はどんなものがありますか?
>>919 色々ある。
man bash の "展開" の項を参照汁。
921 :
919 :2006/07/21(金) 10:50:16 ID:0kBXYfCK
>>920 夏の宿題なんで…もっと的確に教えてくれませんか?
適切な情報への適切な誘導だと思うがね
>>920 嘘教えるなよ。
a=$a の場合はもともと「展開」は一切行なわれないので、
a=$a も a="$a" も全く同じ。
>>922 不適切な情報への、不適切な誘導ですね。
CSVファイルを1行づつbashのスクリプトで読んで、 各カラムを変数に分割して格納したいのですが、 分割する処理がわかりません。 イメージとしては、 while read line; do column1=COMMAND(0) column2=COMMAND(1) done < test.csv こんな感じでやりたいのですが、 csvファイルから読んだカンマ区切りの1行を、 column1、column2に分けてやるにはどう書けばいいでしょう?
>>924 awk とか sed とか。
でもそういうことやりたいなら
perl かなんかで書いた方が楽じゃないかな。
926 :
924 :2006/07/21(金) 16:21:57 ID:ydP4o8rM
>>925 レスありがとう。
perl使えない環境なので、他の手を考えてますが、
cutコマンドで解決できそうです。
頑張ってみます。
927 :
924 :2006/07/21(金) 16:27:04 ID:ydP4o8rM
解決。できました。 while read line; do column1=`echo $line | cut -f1 -d','` column2=`echo $line | cut -f2 -d','` echo "COLUMN(1)=$column1, COLUMN(2)=$column2" done < test.csv こんな感じです。 もっと調べてからカキコしろよ>漏れ ;y=ー( ゚д゚)・∵. ターン
>>927 cut コマンドを使わない場合だとこんな感じ↓
OLD_IFS=$IFS
IFS=','
while read column1 column2; do
echo "COLUMN(1)=$column1, COLUMN(2)=$column2"
done < test.csv
IFS=$OLD_IFS
929 :
927 :2006/07/21(金) 17:46:01 ID:ydP4o8rM
>>928 おお、ありがとうございます!
さっそく試してみます。
930 :
927 :2006/07/21(金) 18:29:48 ID:ydP4o8rM
>>928 試してみたところ、カラムが3コ以上ある場合は、
column2にカラム2以降が全部つながって出てくるようです。
でも、IFSの使い方が気になるので、勉強してみます。
ありがとうございました。
>>923 もちろんmanなんて実行していません。
やはり違いはありませんね。
>>930 それはまぁ、
while read column1 column2 column3; do
とかしないと(カラム数の分だけ read の引数を増やす)。行によってカラム数
が不定の場合は引数の数を最大カラム数に合わせるか、一行全体を読み込んで
から set コマンドを使うなりして工夫した方が良いでしょうね。
>>930 その場合の常套手段は、よけいな値を格納するための変数を
あらかじめ用意しておくこと。
while read column1 column2 trash; do
case "$column2" in
"") echo "値足りねーぞバカ"
continue;;
esac
case "$trash" in
"") ;;
*) echo "値多すぎだバカ"
continue;;
esac
echo "COLUMN(1)=$column1, COLUMN(2)=$column2"
done < test.csv
あるいは、
while read line; do
set -- $line
case $# in
0|1) echo "値足りねーぞバカ";;
2) echo "COLUMN(1)=$1, COLUMN(2)=$2";;
*) echo "値多すぎだバカ";;
esac
done < test.csv
>919さんとは別人ですが>923さんの仰ることが 理解できなかったでよろしければ教えてください。 manは>84さんのJMですがパラメータと展開の項目を読みました。 パラメータ展開の後で行われる展開動作(コマンド置換、 算術式展開、単語分割、パス名展開、クォート除去)のうち、 パラメータ代入では単語分割とパス展開が行われず、 ・IFSとパターンはそのまま ・クォートは単に取り除かれる ・例外扱いの$@は左辺値にならない ことから a=$a と a="$a" は常に同じ結果になるとの理解で よろしいでしょうか。
936 :
934 :2006/07/22(土) 23:33:37 ID:06kWwsBG
遅くなりましてすみません。
>>935 さん回答ありがとうございます。
>934の"$@"の解釈は間違えている気がしてきました。
a=$@ と a="$@" の結果も同じように見えるので、
manは"$@"の展開動作そのものを単語分割と表現しているだけで、
要素リストへの変換を行っているわけではなさそうです。
苗字スレにあったよ 門廻[せど]さん
938 :
login:Penguin :2006/07/25(火) 16:04:44 ID:13eS8Aya
シェルスクリプトにて既存のテキストファイルにテキストを追加するにはどうすればよいのでしょうか? echo "test" > hoge.txt とやればテキストに出力できるのはわかったのですが、 このあと続けてecho "test2" > hoge.txt とするとhoge.txtの中身はtest2となってしまいます。 また、テキストファイル内にて改行させるにはどのような文字列を指定すればよいのでしょうか? よろしくお願いします。
940 :
Linux初心者 :2006/07/25(火) 16:31:22 ID:v8Kk3/bs
はじめまして超初心者です。会社の嫌がらせでパソコンぐらいしか使ったことない 私にshellを作れといわれて苦労している45才です。教えてください。 問題が、日付を手入力したときに正常な日付かどうかと、うるう年の計算 方法です。たとえば20051313はエラーですが20060220は正常ですよね。そのときに 曜日も表示したいのでやり方をすいませんがはじめから詳しく教えてください。 すいませんが、お願いします。
>>940 カズくんのチンポしゃぶったら教えてやるよ
login:Penguinさん(カズさんですか)なんでもしますから、教えていただけませんか 私もかなりあせっていますので、ぜひ助けてくれませんか よろしくお願いします。
なんでもするって? それじゃあ体で払ってもらおうか(*´Д`)
login:Penguin (カズさん)お願いします。できることはさせてもらいますから 教えてくださいませんか。
login:Penguin (カズさん)そうですね。はじめから教えてもらうしか ありませんからよろしくお願いいたします
950 :
938 :2006/07/26(水) 17:47:21 ID:lnXsx7nB
>>939 できました。どうもありがとうございました。
951 :
login:Penguin :2006/07/28(金) 13:58:30 ID:R56f3fDc
モラルの無い下品掲示板
もっとぶって!
953 :
login:Penguin :2006/08/01(火) 02:01:19 ID:aVWxa+ZH
/var/www/html/koko/top/ の koko だけ取り出しんですけど、方法ありますか? 今、オライリーの本見てるんですけど、まだまだ時間かかりそう。 ちゃんと勉強するので、今教えて下さい。もう眠いです(T.T)
echo /var/www/html/koko/top/ | awk -F/ '{ print $5 }'
>>954 ありがとうございました!
やっと寝れます。あー、よかった。明日からより一層精進致します。
レコードごとにセパレータが違う場合、 FS を変えてから再度レコードを読み込みたいが いいコマンドが見つかりません。 (getline は次の行を読みにいく。) gawk に拘りませんが何かいい(スマートな)方法がありますか?
957 :
login:Penguin :2006/08/01(火) 12:41:30 ID:aVWxa+ZH
上のやり方で、-Fセパレータで取り出す方法は、教えて頂いた後に勉強 して理解致しました。で、疑問なんですが /var/www/html/koko/top/ を /var/www/html/top/ と省くやり方とかもあるんでしょうか?
>>956 split
>>957 echo /var/www/html/koko/top/ | cut -d / -f -4,6-
>>958 なるほど。cutを使って出来るんですね。
今まで、あまり使ったことありませんでしたが、見直しました!
とても勉強になります。
とぷくすり
>958 さんきゅー、 助かりました。
今オライリーのsed & awk の「正規表現」のとこ読んでるんですけど まるで呪文ですね。ここらは暗記するとこでしょうか?それとも、何 と無く覚えておいて、必要な時に開いて見るくらいでいいんでしょうか? 理解しようとして、ずっと読んでるけど、頭痛くなって来ました(T.T)
>>962 正規表現はテキストをシーケンシャルに読むだけでは、なかなか理解できるものではないよ。
とにかく自分で試行錯誤して、アハ体験(あぁなるほどそういう事か!という得心)を
積み重ねていく。
それを継続していくと、いつのまにか呪文だった式が意味を持った表現として
すーっと理解できるようになる日が来る。
オライリーだけでは心細かろう。
「正規表現最新リンク集」「sedは日暮れて」あたりでぐぐってみると、webでも結構優良かつ
柔かい解説に巡りあえるぞ。
正規表現は一文字がひとつのコマンドのプログラム言語です。 アルゴリズムをコーディングするという考え方で理解するべし。
正規表現を見くびる傾向があるように思えるのは、 制御文がないとプログラム言語じゃない、または低級だという 先入観があるからかね。 もともとコンパイラの基幹技術だし、UNIXが公開した技術のなかでも ベル研の太っ腹ぶりが最も現れてるところだと思うけどな。 正規表現は甘くないし、真剣に取り組むべきものだと思うよ。 ちなみにRMSは、一押しの入門用プログラム言語に「HTML」を挙げている。 Lisperらしい答えだと思った。
最初の頃はまずCのコードで頭に浮かんでそれを正規表現にコーディングしてた。 Cは立派なプログラム言語でスクリプトは下級言語、正規表現に至ってはプログラム言語にあらずw Cよりpythonの方がずっと高級だと思う今日このごろ。
969 :
login:Penguin :2006/08/02(水) 02:40:31 ID:7vm0Jg4L
>>968 結局のところ何が言いたいのかよく分からん.
書き込みを読む限り,術語としての「高級」とか「低級」という言葉を知らないように見える.
>>969 おはよう。
プクグラミングを知らない人の不思議な偏見を言ったまで。
正規表現になるともうプログラムに見えてない。
ちょっと笑えたからさ。
プクグラミングなんて俺は知らない。
^:先頭 $:末尾 [^]:否定 +:1文字以上の繰り返し *:0文字以上の繰り返し .:任意の1文字 ?:最小マッチ ():グループ化 これで全部事足りてるなぁ・・・。 うむ、アルゴリズムと言うよりもパラメータだな。俺の印象だと。 なんか因数分解が出来る正規表現とかもあるらしいけどね。
>>973 俺もそれだけだな。
最初覚えたのがWindowsで秀丸使ってるときで、ヘルプにそれくらいしか載ってなかったから、それ以外はわからんw
975 :
login:Penguin :2006/08/03(木) 00:12:47 ID:NQ3T36sk
質問です。 # comment 0 6 * * * 1 6 * * * 10 0 * * * 15 * * * * * * * * * とあり、左全てを0にしようとして sed 's/^[^#]/0/g' file とやったんですが # comment 0 6 * * * 0 6 * * * 00 0 * * * 05 * * * * 0 * * * * となってしまいます。なんで???
一番初めの#以外の文字を0に変換しなさい。
クーロンの「分」をすべて0分にしようとして、覚えたてのsed使ってみるか と思ってやったのですが、期待に反しました。手で直せと言われればそれまで ですが、ここはなんとしてでもsedでやりとげたいです。
sed 's/^[^#][^ ]*/0/g' file
>>976 ^[^#]
これであってると思うですけど、まちがってますか?
>>978 sed 's/^[^#][^ ]*/0/g' file
で出来たんですけど、なぜ出来るのか、わかんないです。
勉強足りないですね。
すいませんでした。ご迷惑お掛け致しました。
一番初めが#以外その後スペースが現れるまでの文字列を0に変換しなさい。
>>985 ありがとうございました。
不愉快にさせてしまって申しわけありませんでした。
もう答は出てるし間違ってはいないんだけど、sed 的には sed '/^[^#]/s/^[^ ]*/0/' とする方がふつーだと思う。
gnu拡張が読みやすい。sed 's/^[0-9*]\+/0/g'
次スレ無理だった。つーか考えてみたらこのスレの必要性もよく分からん
gいらんだろ。
993 :
login:Penguin :2006/08/03(木) 13:07:35 ID:NQ3T36sk
>>991 もう、992だけど、このスレ必要です!!
one
two
tree
とあり、改行を取り除いて「,」でつなぎたいんですが
sed 's/\n/,/g' file
だと動いてくれません。viだと、%s/\n/,/g で動くのに。
sedでの改行は\nで合ってますでしょうか?
>>992 gいらないんですか?
>>993 $ cat delme.txt
one
two
tree(木?)
$ column delme.txt | sed 's/\t\+/./g'
one.two.tree(木?)
>>994 ごめんなさい。
立てれないって見て、立てたら2重でした。
削除依頼だします。
よくある行き違いって奴よ 別に謝る必要はない うむうむ
>>991 ム板とUNIX板にもシェルスクリプトスレはあるけど
合流しても犬厨は嫌われるからな。
>>993 paste -s -d ,
銀河鉄道
すいません。1000貰わせて頂きます。
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。