□シェルスクリプトでよく使うコマンド:
制御・条件判定系:
[とtest, expr, true, false, yes, getopts, apply
テキスト処理系:
cat, awk, sed, tr, sort, uniq, grep, wc, head, tail, cut, paste, comm, join
ファイル名・ディレクトリ系:
find, xargs, basename, dirname
出力系:
echo, printf
対話コマンド制御系:
expect, でも単にftpしたい奴は素直にwget使っとけ
あ〜緊張した。なんとか立てられてよかったです。
それではまたーり参りましょう。
前スレでテンプレの相談したときにおっしゃって下さい (´・ω・`)
ま、テンプレは網羅することが目的ではないので……
>>7 名著だけど、今からシェルやらなきゃって人に
最初に勧める本ではないと思う
多少書けるようになった頃に読むと卓効、という感じ
>>1 乙です!
タイトルもシンプルでいいと思います。
>>8 >>11も言ってるようにやっぱり古すぎるし、
テンプレに入れるほどでないので、テンプレ外でひっそり書いてみた。
次回もテンプレからはずしておいてくれ。
質問です。偽コンソールログインを洒落で作っておりますUNIXユーザ1年生です。使用shはcshです。
コンソールログインの画面みたいな状態にして、
login: <-ここの行に入力を行い、
passwd: <-ここは入力しても画面には出力しないであたかも本当にパスワード入力画面みたい
んな感じで、エンターすると
You are an ideot.hahaha by 俺
って表示して自分のログインシェルを強制killして、騙された人のidとpassをゲットするというのが夢です。
で、考えてみたのが下です。
#!/usr/bin/csh -f
clear
banner 'logout'
echo 'console login'
set ID=$<
echo $ID >> $HOME/list
echo '$ID password:'
set PASS=$<
echo $PASS >> $HOME/list
sleep 1
echo "You are an ideot.hahaha by ore"
sleep 1
set END='ps auwx |grep 私のID|grep tcsh|awk "{print $2}"|sort|head -n 1'
kill -9 $END
コレですと、loginをechoしたあと自動的に改行してしまうのがまず悩みです。
また、入力した変数$IDの中身もecho表示できない、HOMEのlistに文字が送られてなかった、自分のプロセスを自動的に
消して強制ログアウトしてくれない、という悩みつきです。最期のset END=.....killまでは、logoutでいいかなぁと思ってます。
教えてクンで申し訳ないです。よろしくお願いします。
あと、決して好きな子のパスをゲットしようとか企んではいません。ごくごく健全な大学1年です。なにとぞ。
あと、前期で初めて作ったシェルスクリプトですが、殆どどこかのサイトにあったソースのパクリですが、厨らしくて
よろしいと思ったので晒します。
#! /usr/bin/csh -f
echo 'へいらっしゃい!'
sleep 1
echo 'ラーメンの待ち時間は? 1:3分、2:4分、3:5分'
set t=$<
if ($t == 1) then
echo "$t 番を選択したよ。3分まっててね"
sleep 170 && perl -e 'print "\x07"; print "カップラーメンできますた\n"'
exit(1)
else
if ($t == 2) then
echo "$t 番を選択したよ。4分まっててね"
sleep 230 && perl -e 'print "\x07"; print "カップラーメンできますた\n"'
exit(1)
else
if($t == 3)then
echo "$t 番を選択したよ。5分まっててね"
sleep 290 && perl -e 'print "\x07"; print "赤いきつねできますた\n"'
endif
スレ汚しすみませんでした。精進します。
宿題 ?
>>17 そんなレベルです。将来はCadenceで回路図カリカリ作る学部です。
まちがえました
>>19 でした。
>>20 ちゃいます。シェルを勉強する授業なんてなかとです。
夢はRuby使う生活ですな。寝ます。失礼しました。
新スレ立って一発目がideotか。
>>17 じゃないけど
ncftp などにパスワードをわたすとき
read pass; ncftpput -p $pass
ってなことをするために,
パスワードをエコーバックしないように
できないものかと思ったら,
ググったらすぐわかった.
>>17 cshは分からないのでshで。
#!/usr/bin/env bash
clear
banner 'logout'
echo -n 'login: '
read ID
echo ID=$ID >> $HOME/list
echo -n 'password: '
stty -echo
read PASS
echo
echo PASS=$PASS >> $HOME/list
sleep 1
echo "You are an ideot.hahaha by ore"
sleep 1
kill -9 $PPID
>#!/usr/bin/env bash
あんまりないと思うけど、複数の場所に bash がインストールされてる場合、
$PATH によってどれが使われるのか不定。
ruby の人がよく使ってるけど、あんまりよろしくないと思う。
#!/usr/bin/env 〜 だとbashとかのパスを調べる必要がないようにという
つもりだろうけど、本来はインストールスクリプトで固定すべきものを
サボっているだけだと思う。
環境変数によって挙動が変わるとか、スクリプトはPATHの中にあるのに
rubyやらbashやらpythonやらにPATHが通ってないと動かないというのは
あまりよくない。
そもそも"shで、"と書いてあるのにbashなのは
別途犬板にbashスクリプトのスレを立てると
事がなにかとスムーズに運ぶのかも。
>>30 ぜひ誰か立ててください。
実は関連スレに載せようと思ってテンプレ作ってるときに探したんですが、
見つからなくて諦めたんです。
32 :
名無しさん@お腹いっぱい。:04/12/01 21:33:20
犬板にスレ立ててレベルの差別化を図った結果、
あちらのほうが情報量が多くなるのが最近の傾向
>>27 /bin/bashと書くとlinuxがどうのこうのと言われると思ったので。
>>29 すまん。shで書こうと思ったら、$PPIDがshにはなかった。
>>32 お互いにS/N比の向上(sh/bashの棲み分けや、煽りとかの削減含む)が望めれば、
あちらのスレが発展するのはこちらにとっても結構なことではないでしょうか。
副作用としてどういうレベルの人たちに最適化されるかという違いができるかも
知れませんけど。
両方見るのめんどくない?
向こうを見るつもりあるの? 俺はない。
こっちがまったりのんびりいけるようになれば万々歳。
いっそのこと、これからスレは全部 linux 板に立てることにしようよ。
Linux板にはへんなスレがあるよ。
新しく立てたほうがいいかもしれないけど。
【Shell】どのシェル使ってる?【Script】
http://pc5.2ch.net/test/read.cgi/linux/1067330754/l50 1 :login:Penguin :03/10/28 17:45 ID:DZdBw1H1
おまいらが使ってるShellを晒せや(#゚Д゚)ゴルァ!!
そして便利なShell Scriptがあれば晒して( ゚Д゚)ホスィ…
GUI Shellも使ってる香具師はそいつも晒せ(゚∀゚)アヒャヒャ
>>26 ありがとうございます。むちゃくちゃ勉強になりました。
上は自分とこのワークステーションに入っているbashのパスを入れます。
read と echo の使い方が特に勉強になりました。
bourne again shell のほうが書きやすいのでせうか。。。うちはCやってるからtcshの方が趣味としてはいいかなと思ったのですが。
>>25 昨日の夜
エコーバックしないやり方を
>>25のレスみてから調べてたんですが、自分には分かりませんでした。
むずかすい。
>>39 最後のkill $PPIDは洒落だろうから普通の/bin/shでいいっしょ。
うちの客先、oracleDBAユーザのログインシェルがcshになってて、スクリプト自体もcsh。_| ̄|○
ヒアドキュメントを与えてshを呼んでしまえ
1Gくらいのでかいバイナリの任意のバイトを書き換えるにはどのコマンド使えばいいんですかね?
エディタで開こうとしても無理っぽいのでどうしたものかと
dd
私ならmmapして直接書き換えるプログラムを書いてしまう。
と思いつつなにげにコマンドラインでmmap[TAB]とか叩いてみると、
知らんうちにmmapwとかいうコマンドが入ってたw
% mmapw -h
mmapw [-{bwlqL}] <file> <offset> <value>
endianness flags:
-b write one byte
-w write two aligned bytes
-l write four aligned bytes (default)
-q write eight aligned bytes
-L same as -l
xorg-serverについてきたらしい(FreeBSD)。
バイトオーダーも指定できるといいのにな。
-Eでbig endian, -eでlittle endianとか。
splitで編集できる大きさにバラせばいいのでは。
それをすすめると、ddで必要な部分だけ取り出せばいいのでは、ってことですね。
[じっけんしてみよう: ddでひつようなぶぶんをとりだす]
$ ed
a
あいうえお
かきくけこ
さしすせそ
.
w 001.txt
33
! dd if=001.txt of=002.txt bs=1 count=2 skip=15
読み込んだブロック数は 2+0
書き込んだブロック数は 2+0
2 bytes transferred in 0.023819 seconds (84 bytes/sec)
!
! cat 002.txt
く!
q
[じっけんしてみよう: heredocをつかう]
---きりとりせん----
#!/bin/sh
echo "[のりしろ]"
ed << EOF
a
あいうえお
かきくけこ
さしすっせそ
.
w 001.txt
!dd if=001.txt of=002.txt bs=1 count=2 skip=15
!cat 002.txt
q
EOF
echo "[のりしろ]"
----きりとりせん----
少し前にくだ質で出てたsourceで現在読んでるファイルのフルパスを知る方法って、
bashとか、シェルによっては特殊な方法が用意されていたりしますかね?
かなり無理矢理な方法としては、ファイルごとにユニークなキーを
magic=GYUUNYUUDAYOMON
みたいに埋め込んでおいて、lsofで開いてるファイルを調べて片端から$magicで
grepして引っ掛かったのがアタリ、というのを思い付いた。
元ネタを知らないから現在読んでるファイルのフルパスって意味がわからないんだけど、
FreeBSD なら /proc/PID/file
Linux なら /proc/PID/exe
とかいうこと?
cat /proc/$$/exe
>>54 元ネタ知らんが、おれは
>>52から、
. foo.sh
した先の foo.sh の中で、自分が foo.sh かどうかを知りたいんだと
解釈したんだが、ちがうのか?
>>52 元ネタしらないけど。
history | tail -n 1 とかやって
pwd と組み合わせれば、フルパスの取得も可能かも。
百者百様の解釈ですな。。。
すげえ、読み進めるほど訳が判らなくなる…(w
>>56 いや、元質問者自体が途中から
>hoge?.shでは. ./base.sh として設定を読み込んでいます。
とか言ってるので、それをベースにすると
>>52も
>>56も間違っていない。
そうだったのか
アホよばわりして正直すまんかった
>>52 フシアナと呼んでくれ
zshだと知る術が用意されているようです。
setopt FUNCTION_ARGZEROした上で$0を参照すればいいらしい。
0 <S> The name used to invoke the current shell. If the FUNC-
TION_ARGZERO option is set, this is set temporarily within a
shell function to the name of the function, and within a sourced
script to the name of the script.
52=元質問者?
ちゃいますよ。
私が元ネタの質問者ならあそこまでグダグダにはならんw
元質問者がlsof知ってるとも思えんし。
通常の$0と同じだろ。単独でフルパスになる必要はないと思われ。
気がついたら、こんなスクリプトが・・・。
だれかデバグきぼんぬ。
----BEGIN BASE64----(upkenget.sh.bz2)
QlpoOTFBWSZTWYLwQcEAAGHfgEAwf/f/Gj9v3o9////+QAHdktVlEFCHpAA00A2o
NDNQAAADI9QANRoTQGgRkZJk9TGoAHqBoGTQPSNDIcZMmhiMTRgEYCYQBgJpo0yN
AMMSQm1TNNJgRo9Rk09TTIaGgyMgaaABo4lyzxZ7kGXtpZNGh4DZByUJBM9gvbcg
gnQFMl+lgS4gd6n9sNrPAI4jhGnyzb+qh9b3qV1+Z8Qy+cUTV+iqArZ4zSTuZ9GZ
wuXGu+jCia+2DIG2Oc6qEqPFJ2z8ml7j5yPDXNLeydZ1CF4A/AjKFfwG+cdswxMm
AYooMyWTZzQZYDgFWgMWHLeqSiClGI6lAMB0I2kBvZA5wDFETsVSXqJ9NfNt2U7P
0QMQgYPFFVnw1ZItdN7OSGJqOSRhy6JtDzRALEuVj4mS3cQFiW4zZcw0SUz4DhMa
+LhvEHwAtBwIXTKqIoQ+gg8S5v1qHUpFlo9AoQXULgyFCkWtCJT5TvGecgEeUBxA
jcaDYMQlBF4gFrUfzTbB5Lg1yOgOz6pgDulpgfsB0lErLMAyCDJEB7g2IBQ6qA5D
HKr9CxdUTpl6RuneZYGsTNYlQslJFkoukm1k0ImArCEUaVCqC+sdVQbix6nnxl3Z
RVBt1xRUIurFtWY7toBmjIYNMK8KN4SERAxuiHG5Iyuo4X0bYLYWBldddwUBQdNW
3uHmxSEZqmrXSkzx3H2YzmmpOHRutiRzJIROe1g2jqsCnDGJK0KeKaF2RXIGU4H7
Eb/yl/i7kinChIQXgg4I
----END BASE64----
>>69 ですが、最後に wget を呼び出している行で \ の後に \x20 が入ってるので、
そいつを消してください。
$ mv *.txt *.doc
なスクリプト無いですか?どうも上手い方法が無くて困ってます。汎用性のある
シェルスクリプト誰か書いてませんか?
for f in *.txt; do
mv $f `basename $f .txt`.doc
done
そんなのでいちいちスクリプト書かない。
$ mv *.txt *.doc
usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
#!/bin/sh
for file in *.$1
do
mv $file ${file%.$1}.$2
done
>>72 $ cat rename.sh
#!/bin/sh
ls *.$1 | sed "s/\(..*\)\.$1/mv & \1.$2/" | sh
リネームしたいファイルがあるディレクトリに cd して
$ rename.sh txt doc
>>72 autoload zmv
zmv '(*).c' '$1.h'
alias mv='noglob zmv -W'
皆さんどうもありがとうございま下。私はlinux||cygwinでbashなのでzshとか
ワカラ無いのですが参考になりました。
一応、こunixuserの新山センセのsedっぽいパターンマッチを使うコマンド
formv.shを使って解決していたのですが、もっとスマートな方法無いかと。
formv.sh
------
#!/usr/bin/bash
if [ $# -lt 2 ]; then
echo 'usage: formv "s/pattern/pattern/" filename(regexp)'
exit 1
fi
s=$1;shift
for i in $*; do
j=`echo "$i" | sed "$s"`
echo $i "->" $j
mv $i $j
done
-------
$ formv 's/txt/doc' *.txt
$ formv 's/merry_crithmas/aho!/' *.txt;
変更してないならbashだろう。echo $SHELLで確かめれる。
うちの linux には rename(1) がある
ファイル名が数字のファイルのみ表示したいのですが、
良い方法がありませんでしょうか?
$ ls
hoge 645 b7a 7ba
となるディレクトリで
$ コマンド
645
としたいのです。perlを使うってのは無しで
/bin/ls -1 | egrep '^[0-9]+$' | xargs echo
1行1列にしたければxargs echoはなしで。
zsh なら
ls <->
$ echo $BASH_VERSION
2.05b.0(1)-release
$ shopt -s extglob
$ mkdir foo
$ touch foo/{hoge,645,b7a,7ba}
$ ls foo/+([0-9])
foo/645
$
ありがとう
84さんの方法だけうまくいきませんでした。
$ echo $BASH_VERSION
3.00.14(1)-release
なのでバージョンの違いなのかな。
$ /usr/local/bin/bash
$ echo $BASH_VERSION
3.00.16(1)-release
$ shopt -s extglob
$ mkdir foo
$ touch foo/{hoge,645,b7a,7ba}
$ ls foo/+([0-9])
foo/645
>>85 shopt -s extglobが肝だよ
...なるほど
#!/bin/bash
shopt -s extglob #肝
ARGUMENTS=`ls`;
proc_args() {
while :; do
case $1 in
+([0-9]))
echo $1;
;;
"")
return;
;;
esac
shift;
done
}
proc_args ${ARGUMENTS};
90 :
名無しさん@お腹いっぱい。:05/01/13 02:23:12
c shellスクリプトで配列の(部分的)コピーをする方法はありますか?
できるだけ一時ファイルを使わず、メモリ上で配列をコピーする方法です。
いま、set arr0 = (abc def ghi jkl mno pqr)とすると、
$arr0[1], $arr0[3], $arr0[5]を配列 arr1 に格納するのは可能ですか?
91 :
名無しさん@お腹いっぱい。:05/01/13 05:15:37
したいことがよくわかんないけど
set arr1 = ( $arr0[1] $arr0[3] $arr0[5] )
じゃダメなん?
92 :
名無しさん@お腹いっぱい。:05/01/13 06:10:42
どの要素をコピーするかは、条件によって変わってくるんで、
インデックスを使いたいんです。動的コピーしたいという事です。
条件によって一個ずつ取り出して、一個ずつ格納するようにすれば?
#/bin/csh
set arr0 = (abc def ghi jkl mno pqr)
set i = 1
set n = $#arr0
foreach x ($arr0)
set a$i = $arr0[$i]
@ i++
end
set j = 1
while ($j <= $n)
echo $a$j
@ j++
echo $j
end
--------------------------ここまで
このようなスクリプトの場合、
$a$j の部分をうまく処理できません。
改善策や、もっとまともなやり方はあるでしょうか?
95 :
名無しさん@お腹いっぱい。:05/01/13 09:12:48
eval
単一ディレクトリ中のファイルをFTP転送するシェルで、
mput *
とすると、巨大なディレクトリでは
Arguments too long
と出てしまいます。
Cシェルがグロブ展開しているようなのですが、何かうまい回避方法はないものでしょうか。
回避するだけなら先頭文字で適当に分割して何度かやればどうよ。
シェルで画像展開してサムネイルを表示させるようなことってできますでしょうか・・・?
>>98 やりたいことをもっと具体的に書け
画像のサムネイルのhtmlファイルを生成するスクリプトなら落ちてるだろ
100
(・∀・)マサムネ!!
ファイル名の空白文字を _ (アンダーバー)に一括で変更したいんですが,
for i in *.jpg みたいな書き方だと空白の前後で2つに分かれて厄介です。
何かいい方法ないですか?
mv "hoge hoge1.jpg" "hoge_hoge1.jpg"
mv "hoge hoge2.jpg" "hoge_hoge2.jpg"
いつもこんなスクリプトを書いてる(とっても面倒)。
>>102 手元の bash 2.05.0 では for で 2 つに分かれないんだが,
ls -1 *.jpg | while read a b ってのはどう?
あはっ
#!/bin/zsh
for i in $*; do
mv -- "${i}" $(sed 's/ /_/g' <<<"${i}")
done
>>102 for i in *.jpg
do
ls "$i"
done
>>103 いいかもしんない。
とにかく思いっきり嘘をつきました。m(..)m
GNU bash, version 2.05b.0(1)-release (i686-pc-cygwin)
で
>>102 の書き方では2つに分かれないです。
ちなみに for i in `/bin/ls -1` だと2つに割れます。
107 :
98:05/01/17 07:54:34
すみません。
例えば、objやpngやepsやらが存在しているフォルダがあって、
そのフォルダでlsをすると、普通のテキストファイルやらはファイル名だけでいいんですが、
画像ファイルに関してはサムネイルをコンソール上で表示したいな、と思いました。
html作ってw3m介して画像インライン表示すれば一応できるわけですね。。。
ありがとうございました。
gimv等のビュワーを使う方が早いんでないかい
110 :
名無しさん@お腹いっぱい。:05/01/17 10:21:55
tcshを使っているのですが、行番号を指定して処理のできるコマンドがあれば、
教えてください。あと、シェルの勉強ができるいいサイトがあればおしえてい
ただけるとありがたいです。
よくわからんが、ファイルの10行目を編集したいとかいうこと?
それだとedを使って編集コマンドをheredocで与えるのが一般的。
例えばこんな感じで。
#!/bin/sh
# comment out the 10th line of file /omae/mona
ed /omae/mona <<END
10
s/^/#/
w
q
END
サイトは、せっかくテンプレがあるんでまずは見てやってくれ。
112 :
110:05/01/17 13:51:37
>>111 わかりにくくてすみません。
自分がやりたいのは例えば指定した複数の行のみで
cutなどを実行したいということなんです。
勉強不足でよくわからないのですが
例は10行目においてwをqに置換するというシェル
ということでいいんでしょうか?
>>112 行が連続してるなら
tail -20 | head -5 | cut ...
とか?
114 :
110:05/01/17 15:35:09
皆さんありがとうございます。目的を達成できました。
>>112 cat file | head -n 20 | tail -n 5 | cut -f'3-5' | sort
みたいなことかしらん
>・シェルスクリプトのことをシェルってゆーな
>>1ぐらい読めよ
117 :
98:05/01/18 01:03:03
>>108 >>109 情報ありがとうございます。そうですね、簡単にできるなら
あまり大がかりなビューアーとかは使いたくなかったんですが…。
xmltermは初耳!画像表示もほとんどイメージ通りです。
日本語がらみが厳しそうですがちょっと使ってみますね。
パス付きzipを判定して捨てるスクリプトってないですかね?
gunzip -t パス付き.zip とかやるとencyptファイルどうたらとかいうので
これを使ってできないかなぁと思うのですが・・・。
少なくとも*.zipとgunzipは関係ないでしょ。
>>119 何を以て関係ないと言うのかわからないけど、解凍はできなくていいのです。
いや、むしろしたくないです。
ヘタレなりに考えた結果gunzipで判定基準になるのかなぁと思ってあげました。
別にこの方法にはこだわってはなくて、*.zip(できればパス付き*.lzh,*.gcaにも対応したい)の
ファイルパスが書いてあるtxtから読み込んで、パス付き有無の識別ができて、
パス付きファイルがあったら捨てるってことができればそれでよしです。
俺は今
hoge.zip のファイルにパスワードが掛かっているかシェルスクリプトで鑑定したいのですが、
いい方法はないでしょうか?
と書くためにこのスレに来た。
ところが118が同じような事を書いている。これはどういうことだろうか?
運命を感じる。明日はいい日に違いない。
要するにエロが多いだけだな。
118>> encyptファイルどうたらとかいうので
そのメッセージ(stdoutだかstderrだか)を捕まえればいいのでは?
>>118 for f in *.zip; do unzip -q -t -P "" "$f" || echo "$f"; done | xargs rm
>>124 ありがとうございます。
stdoutっていうのしか僕は知らなかったみたいでメッセージをとらえられなくて
どうすればいいのだろう?とか思ってました。
stderrってのを使えばメッセージを捕まえられるのですね。
勉強になりました。
>>125 おお、なんかちゃんと判定してるみたいです?消えました。
しかし正直何してるのかまったくわからないのでひとつずつ調べないとだな。
ありがとうございます。
この $f ってのはどこでセットされるんですか?
( ゚д゚)ポカーン
>>127 ひとつずつ調べるってのはひとつずつ聞くってことかい?
いやいやそうではなく・・・スンマセン。
>>126 理解せずに2ちゃんに書いてあるコマンドを実行するのは危険
くだ質にいきなよ。いいかげんスレ違い。
ed に渡すコマンドって、必ず改行で区切らなきゃいけないんですか?
テキストファイルの行頭の #!/usr/local/bin を #!/usr/bin に
書き換えたいとき、覚えている方法だと
ed -s hoge.rb
1,s%/local%%
wq
スクリプトにする時、ヒアドキュメントを使うと3行かかりますよね。
正常な人は perl -e を使うみたいですが、ed では1行でできないんでしょうか。
echo 1,s%/local%%¥;wq | ed hoge.rb
っと、これもくだ質向けの質問だ。ごめんなさい、もしよければお答えください。
(echo 1,s%/local%%; echo wq) | ed hoge.rb
ありがとうございます…
あとは printf とか? くだらなくてすみませんでした
次の日曜日の日付を得たいのですが、なんか簡単な方法はありませんか?
今日実行すれば 2005-01-30 が得られて 2005年1月30日に実行すれば
2005-02-06 が得られるような方法のことです。
man date を読めば簡単にできることがわかりました。
つまらない質問をしてしまってゴメンナさい。
>>137 man date
曜日を%Aとかで出力させて
現在曜日にたいして1-7日後を判断すればいいじゃん
DATE: Monday
なら6日後とかね日曜なら7日後だ
%w と %j と -d を使えば出来そう。
date(1)とstrftime(3)のマニュアルをじっくり眺めてみる。
1. dateで曜日を表示させて次の日曜までの日を得る
2. 現在時間との差分を指定できるdateを使って表示:
date -v+<その日数>d (FreeBSDの場合)
という感じじゃない?
strftimeの指定子はOSによって違うかも知れないが、FreeBSDだと
expr \( $(date +%w) + 6 \) % 7
で日曜までの日数がとれるから、それを2にあてはめて
date -v$(expr 7 - \( $(date +%w) \) % 7)d
でできる。
あ、ごめん、日曜日には当日の日付を出すと勘違いしてた。
しかもなんか間違えたものをコピペしてしまってるし……(汗
> strftimeの指定子はOSによって違うかも知れないが、FreeBSDだと
> expr \( $(date +%w) + 6 \) % 7
計算式が嘘。なんか実験しながら書いたら間違ったものをコピペしちゃった。
> date -v$(expr 7 - \( $(date +%w) \) % 7)d
これも間違えてるし。あわてて書くとよくないですね。
今回の場合、modする必要ないので
date -v+$(expr 7 - $(date +%w) )d
ですかね。
あとは最終的に書式指定(dateのmanを見てね)をしてできあがり。
% date -v+$(expr 7 - $(date +%w) )d
2005年 1月30日 日曜日 16時33分59秒 JST
% date -v+$(expr 7 - $(date +%w) )d +ごにょごにょごにょ
2005-01-30
strftime(3)で%wが使えない場合は
>>139のように文字列で表示させて
パタンマッチすることになります。ただしロケールによって文字列は
変わる(特に%Aなどは national representation を出力する)ので、
LANG=Cを指定するかロケールによらない出力を行う指定子を使う必要が
あります。
>>143 > LANG=Cを指定するか
訂正。s/LANG/LC_ALL/
gnu date は...ダメだよね、きっと。
$ date --date='next sunday'
Sun Jan 30 00:00:00 JST 2005
>>145 > gnu date は...ダメだよね、きっと。
$ date --date 'next monday'
2005年 1月 24日 月曜日 00:00:00 JST
$ date --date 'last monday'
2005年 1月 17日 月曜日 00:00:00 JST
となってしまいます。
man を読んでこんな風にしました。
wday=0
add=$(expr $wday - $(date '+%w'))
if [ $add -eq 0 ]; then add=7; fi
if [ $add -lt 0 ]; then add=$(expr 7 + $add); fi
next_week=$(date -d "${add} days" '+%Y-%m-%d')
# レスを下さった方々どうもありがとうございました。
折角だからもっといかれた方法を考えよう
% cal -d1 | grep -w `date +%d` | cut -d' ' -f7
月またぐと上手くいかないけど、まあそこはそれ。
set `date --date '7 days ago' '+%y%m%d'`;echo $1
PHPで。
% php -r 'echo date("Y-m-d", strtotime("sunday"))."\n";'
>>149 この質問がくだ質で出たならその回答もいいが、
ここはシェルスクリプトスレなんで。
既に回答も出ているし、あまり発散しそうなのはやめた方がいいと思う。
151 :
名無しさん@お腹いっぱい。:05/01/30 04:51:01
シェルのベンチマークテストとかあるのかな?
ランチャー的な動作しかしないとしても、常時動いてるものだし。
>>151 > 常時動いてるものだし。
あんたのシステムがどういうものか凄く興味がある。
>>152 いや「常時動いてる」は言い間違いか。
とにかくconfigureとかああいうのが、もっと
軽快に動作するようになったらいいなあと思う。
configure が遅いのはシェルのせいじゃありません。
おとなしくccacheを使え。
ファイルの日付を切り出すコマンドを sh -c で渡してやりたいです[*1]。
とりあえず
LANG=C ls -l hoge | awk '{print $6, $7, $8}'
で切り出しているのですが、これを sh に渡すとなると
sh -c "LANG=C ls -l hoge|awk '{print $6, $7, $8}'"
awk: line 1: syntax error at or near ,
sh -c 'LANG=C ls -l hoge|awk '{print $6, $7, $8}''
awk: line 2: missing } near end of file
sh -c 'LANG=C ls -l hoge|awk \'{print $6, $7, $8}\''
quote>
sh -c 'LANG=C ls -l hoge|awk \\'{print $6, $7, $8}\\''
awk: 0: unexpected character '\'
awk: line 2: missing } near end of file
むう(´・ω・`)
1. 上記のようなコマンドを sh -c にうまく渡すにはどうすればいいでしょうか?
2. [*1] を満たすエレガントなコマンドがあるでしょうか?
sh -c 'ls -l hoge | awk "{print \$6,\$7,\$8}"'
でいけたよ。
ところでシェルはzsh?
漏れもzsh使ってるんだけど、シングルクォートの扱いだけがzshの嫌なところ。
>>157 鬼のような即レスどうもです。
> sh -c 'ls -l hoge | awk "{print \$6,\$7,\$8}"'
そうか、こうすりゃいいのか。多謝。
> ところでシェルはzsh?
ビンゴー。なんで判ったんざんしょ? quote> って出てるから?
> 漏れもzsh使ってるんだけど、シングルクォートの扱いだけがzshの嫌なところ。
bash とかとどっか違ったっけ? …ってちょっとスレ違いか。
>>158 157ではないけど、bashとかと同じだと思うよ。
シェルのクウォートとか$とか空白の扱いは腐ってるから、あんま
り深入りしないほうがいいと思う。
/usr/bin に a というスクリプトがあったとして、そこから同じく /usr/bin にある b という
プログラムを呼びたい場合、どうすればいいですか?
/usr/bin は固定ではなくて、a と b は常に同じディレクトリにあります。
./b だと、コマンドを呼び出しているパス/b という意味になってしまって、期待通りの挙動に
なってくれません。
$0を使う。$(dirname $0)とか。
でもaにsymlinkしてそれを使う場合など、期待するものがいつも得られるわけではない。
ま、UNIXではそういうことしないでフルパスでbに書くのが推奨される作法。
/usr/binとかの場所に置くものならするべきではないけど、
個人のスクリプトとかなら好きにして。
激しくFQAだが、いい方法がない。
FQAキター
>>161 どうもありがとうございます。
助かりました。
>>164 微妙に、ガイシュツですね。
スマソ。
166 :
名無しさん@お腹いっぱい。:05/01/31 17:03:21
shで連番を生成する定石ってありますか?
1 2 3 4 5 ... のタイプと 001 002 003 004 005 ... のタイプあたりで。
seq とか?
>>166 for i in `seq 10` ; do echo $i ; done
とか。jotとか。
まあ結局フォーマットするならawk使ってやったほうがいろいろ潰しが効きそう。
a=`awk 'BEGIN { for (i = 1; i <= 10; i++) printf("%03d ", i) }'`;
for i in $a; do echo $i; done
とか。
seq -f %03g 1 5
漏れの回りではseqよりzshの方が存在確率が高かったりする。
% zsh -c 'echo {1..5}'
1 2 3 4 5
% zsh -c 'echo {001..005}'
001 002 003 004 005
連番作成なんて飾りですよ
seq使ってる時点でLinux依存になるだろ。
jotならFreeBSD依存。
どうせ依存するならbashのfor ((;;))とか使っとけ。
前スレ?で既出。定番は
yes ' ' | cat -n | head -n 10
for((i=0;i<10;i++));do printf "%03d " $i;done
これならどこでだって使える
>>172 Linux 依存か?
GNU coreutils に依存するだけだが。
>>172 > seq使ってる時点でLinux依存になるだろ。
ということにしたいのですね。
GNU coreutilsをわざわざ入れてる*BSDやSolarisって
少数派だろうし、それが入っているって期待して
スクリプト書いちゃいかんだろ。
Linuxなら100%入っていると改定して良い。
Linux には 100% 入っている != Linux 依存
>>175 大きな勘違いしてた。shならこうか?
i=1;while test $i -le 10;do printf "%03d " $i;i=`expr $i + 1`;done
XXXがYYY依存とか言い出すとさ、
printf(1)が普通にあるのもLinuxや*BSDに限ったことなんじゃないの?
SunOSや商用OS(HP-UX、AIX...)だと怪しい気がする。あったらごめん。
182 :
名無しさん@お腹いっぱい。:05/01/31 19:18:53
awk 'BEGIN { for( i=1; i<=100; i++ ) print i }'
printf(1)はPOSIX準拠
>>181 そういうときは、テンプレにございます
UNIX系各種OSのman page検索
POSIX: Shell & Utilities (標準規格)
などのリンクを活用くださいませ。
>>181 (i=1;while [ ! ! $i -le 100 ];do case $i in [0-9])echo -n "00$i ";;[0-9][0-9])echo -n "0$i ";;[0-9][0-9][0-9])echo -n "$i ";;esac;i=`expr $i + 1`;done)
>>185 うーん力作だね。
でも、echo -nがSolarisだと動かないね。
ところで、whileのところのtestで ! ! で2重否定してるのはなぜ?
これが原因で動かない環境もありそうな気が・・
/bin/sh -c '(S="";i=1;while [ $i -le 100 ];do case $i in ?)S="$S 00$i";;??)S="$S 0$i";;???)S="$S $i";;esac;i=`expr $i + 1`;done;echo $S)'
ちょっと訂正
純粋なshの機能だけでsubstrやindexといった関数って書ける?
>>182 Solaris の /usr/bin/awk は極めて古いので、BEGIN だけのスクリプトは
/dev/null を食わせてやらないとダメ。/usr/bin/nawk ならば問題なし。
>>188 expr(1) を使わなきゃ難しいような気が。
たくさんの回答ありがとうございます。
とりあえず、
>>173がどんな環境でもまず問題なし、exprを使えば
もうちょっと凝ったものも出来る、もっとあっさり書きたい時は
環境依存になるということですね?
ありがとうございます。
>>186 > でも、echo -nがSolarisだと動かないね。
PATH=/usr/ucb:$PATH echo
>とりあえず、
>>173がどんな環境でもまず問題なし、exprを使えば
Solaris には yes はないよ。
あるんだなそれが。ってのもyesの代替スクリプトも過去スレで既出。
>>193 代替スクリプトが必要な時点で無いって言うのじゃないですか?
代替スクリプト用意しておいて"ある"って言うなら
gnu coreutils インストールしておけばその環境では"ある"って言えるわけで
while :; do echo yes; done | hoge
ぐらい書くのと、coreutils入れるのと、同じかよ
で、Solaris に yes はあるの?
うちの Solaris には無い
>>198 すくなくとも
Solaris 9 4/04 s9s_u6wos_08a SPARC
Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
Use is subject to license terms.
Assembled 22 March 2004
にはあるな。
SunOS 3.X の大昔から Solaris 7まで使ってたけど、
yesがないSunOSは見たことなかったぞ。
差し支えなければバージョン晒してみてくれないか?
>>198
>>200 思い込み激しいな。ほんとにSolaris7まで使ったの?
yesは、
Solaris7やSolaris8にはない。(/usr/binにも、/usr/ucbにさえも)
Solaris9で復活したみたい。
まあ、ucb系のコマンドということで嫌われて一回消されて
復活したというわけかな。
% uname -a
SunOS edu 5.8 Generic_108528-19 sun4u sparc SUNW,Ultra-Enterprise
% cat /etc/release
Solaris 8 2/02 s28s_u7wos_08a SPARC
Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
Assembled 18 December 2001
% print $path
/usr/local/j2sdk1.4.2_02/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /usr/openwin/bin /usr/ccs/bin /usr/ucb /opt/SUNWspro/bin /usr/local/java/bin /usr/bin/X11
% yes
zsh: command not found: yes
SolarisはGNUモノ入れないと使いものにならなかったからな。
coreutils(当時はsh-utilsか?)のyesが入ってたんでしょ。
ホントに移植性が大事なら
awk や perl で作った方が楽かもね。
$echo -e '#include<stdio.h>\nint main(){int i;for(i=1;i<=10;i++){printf("%03d ",i);}}' > foo.c; gcc foo.c -o foo && ./foo; rm -f foo.c foo
今度はそうするとビルドツールやlibcが問題になって泥沼化かw
で、perlを使えば、perlがベースから外されたFreeBSD 5.xで問題になる。
awkはSolarisで問題になり、かと言ってnawkを使うとSolaris以外で使えない。
じゃぁcshで。
>>207 NetBSDも昔っからperl入ってないし、pkg_addすると
/usr/pkg/binに入るんで、/use/binにperlのシンポリック
リンクを張った覚えがあるな。
NetBSD2.0はまだ触ってないから知らんが。
二つのファイルが同じときに、文字を表示するにはどうしたらいいのでしょうか?
diffやcmpだと違いがあったときにしか表示されません。
何かいいコマンドとか方法はありませんか?
cmpで黙らせた方が速そう
>>210 #!/bin/bash
cmp|diff "${1}" "$[2}"
if [ $? -ne 0 ]; then
hogehoge(eg. cat "${1}")
(eg. echo "identical")
fi
#################
#!/bin/sh
trap "echo hoge" INT
echo start
sleep 100
echo stop
#################
こんなスクリプトを書いています。
sleep 100 には実際には長たらしい処理をするプログラムが入ります。
ここで、外部から SIGINT を送り込んでも、
すぐに hoge が表示されるわけではありません。(最悪の場合100秒待ちます(藁))
SIGINT を送り込んだら hoge が即表示されるようにするにはどういう風に
スクリプトを書けばいいですか?
その例だと、コマンドがひとつしかないからじゃないの?
たとえば、sleep 1を100回繰り返してみるとか、にすれば結果も変わってくるんじゃないの?
SIGINTを誰に送ってる?
shだけに送ってたら、sleepが死なないから終了まで待つ。
shとsleep両方に送るには、shのpidがpgidだと思うから、
そこめがけてkill -INT -pgidとか、killpg(-pgid,SIGINT)とか。
219 :
名無しさん@お腹いっぱい。:05/02/04 16:22:35
bashでヒアドキュメントをシェル変数にいれようと思って
cat > $kiee <<EOF
munyamunya
EOF
とすると
-bash: $kiee: ambiguous redirect
とでます。なんでですか?
お前がやっているのは、EOFまでの標準入力を変数kieeに入っているファイルにリダイレクト、だよもん
$kieeにファイル名が入ってたら、とりあえずエラーにはならない
>>216 sleep 100
を
sleep 100 &
wait
の2行にすると、shだけにSIGINTを送っても即処理されるみたい。
何でかって?それがな、一晩考えたが俺も説明できん orz
>>225 考えてもわからんよ。マニュアルかソース嫁
>>226 何回も読んだけど、なお解らなかったの。OTZ
普通にsleep 100だけでも、shはsleepをfork+execして親側でwaitしてるじゃん。
wait中の親はSIGINT捕まえられて即処理できて当然じゃん?
これをsleep 100&waitに変えたからって、この親子の関係は変わってないでしょ?
だれか、俺を導いてちょ。
sleep 100 1行だけの場合、SIGINTでsleepが終了しない限り
シェルに戻らないので、trapも起きない。
sleep 100 & waitの場合、waitはシェルの内部コマンドなので、
SIGINTを送るとwaitが終了してtrapが起きる。
この時、waitが終了してもsleep 100 &はバックグラウンドで動き続ける。
>>227 単純なfork+exec+waitではないのでは?
このへんのことはマニュアルに書いてないのかな?
ソース読むしかないね。
プロセスグループだかセッションだかが関連するんではないだろうか、
と勝手な想像をふくらましてみる
>>228 sleep 100 1行だけの場合、SIGINTでsleepが終了しない限り
シェルに戻らないので、
これ違うよね?だってシェルのプロセスだって動き続けているでしょ?
fork&execしたsleepをwaitして待ってる最中というのが俺の理解っす。
だから、必要な処理があれば実行できる(例えばSIGINTの処理)。
「シェルに戻らないので」といういい方が曖昧だったかな。
sleep 100とフォアグラウンドで記述した以上、
シェルとしては文法上、sleepが終了するまでは次の処理を
することができない。(システムコールレベルでのfork() wait()は
この場合考えないこと)(あくまでシェル文法)
sleep 100 & waitなら、waitだけ終了して、
sleep 100だけバックグラウンドに残すことが文法上可能なので、
sleep 100 &したままtrapを実行できる。
あくまで文法解釈の問題。
あと、シグナルが届くのは、waitが内部コマンドだから、
シェルに送ってもwaitに届く。
>>231 225はシステムコールのこと知ってるくせに実際にプログラム書いたことは
あまりないだろ? ブロックするシステムコールを呼ぶときは、EINTRは
無視するループを組むことが多いのよ。
普通にforegroundで実行してるときはwaitの間はSIGINTが来ても無視するわけ。
だけどwaitビルトインを使うときはSIGINTが来たらさくっと抜けるように
shというのは書かれているわけだ。
詳しくはソース読め。これくらいなら簡単だからせいぜい2,3分で追える。
>>232 はなんかいいかげんな説明というかこじつけっぽい気が。本末転倒っつーか。
つまり、sleep 100の1行だけの場合、
内部的にシェルがwait()システムコールで待っている時に、
SIGINTでwait()が中断されたとしても、
フォアグラウンドのsleepが未完なので、
あえてtrapの処理をせずに、再度wait()を呼び出して、
あくまでもsleepを待つようにしている(それが仕様)ということかな?
うわ!! 直リンしちまった。。。m(__)m
勉強になったわ。
240 :
名無しさん@お腹いっぱい。:05/02/07 17:02:14
http://pc5.2ch.net/test/read.cgi/linux/1107692207/l50 ↑から誘導されてきました
親シェルから下記のようなシェルを起動させて動かしています。
下記シェルを単体で動かすとちゃんと動くのですが、他のシェルか
ら呼び出すとcase文を無視されてしまいます。
なぜなんでしょうか?ご教示下さい
#/bin/sh
WEEK=`date | awk '{print $4}'`
TIME=`date +%H%M`
case $WEEK in
月曜日)
if [ $TIME -gt 1200 ] && [ $TIME -lt 1300 ]; then
echo "お昼休み"
cronで動かしたときのみcase文を無視されてしまいます。
手動の場合は正常に動作します。
何が原因なのでしょうか?
・シェルスクリプトのことをシェルってゆーな by
>>1
ま、おおかた、cronの中では LANG が設定されてないとかそんなもんだろ。
echo $WEEK してみろ
>>240 直接の原因は、cronから起動した場合、
LANG=Cになっているから、dateの出力が英語表示になる、
しかも、順番も変わることだが、
そもそも、dateをawkしてprint $4などとするのは邪道。
WEEK=`date +%w`
としなさい。すると、WEEKには、0(日曜)〜6(土曜)が数字で入るから、
case文ではこの数字で場合分けする。
>>240 今Linくだ質に回答したよ。
6時間ぶりに2chに来て見た瞬間にわかったよ。
次スレからは
・テンプレ読まない奴禁止
ってのも
>>1に入れた方がいいんだろうか。
レス頂いた皆さん有難うございます。
今は帰宅して240の環境にいないので確認できないのですが、
>>244さんのご回答で
直りそうですね。それが理由だったら恥ずかしいこの上ないです。
それと
>>243さん勉強になりました。それに変更します。
初心者のスレ汚しすみませんでした。
皆さん有難う
>>244 その、Lin板の管質に回答したってやつ、違うと思うよ。
>>243 の答で合ってる。
#/bin/sh のところは単なるtypoだと思うし、
もし本当に #/bin/sh って書いてあっても、
デフォルトで /bin/sh スクリプトと解釈されて動くはず。
(chmod +x さえされてれば)
>>247 244だけど、多分その通りだろうね。
和紙はスレの流れのほんの一部しか読んでない状態だし、
和紙の言うとおりだとしたら、その際エラーも出てる筈
cronで生成しているファイル(日付.log)の1行目に
日付(2005/05/08)を挿入したいのですが書き方が分かりません。
ご教授願います。
>>251 日付を取り出すフォーマットじゃなくてさ、
日付.logという(日付に依存して決まる)ファイル名の方で悩んでるんじゃない?
>>250 today=`date ...`
echo $today > $today
とかしてみ。`date ...`の部分は、
>>251 の助言にしたがって自分で考えようね。
``の意味がわからないなら、そのときはman shだな。
あ、日付にスラッシュが入る形式なのか。
そのままじゃファイル名に使えんな。
orz
ともかく、質問のしかたが悪いということで。
もう、日付は、飽きた。
この手のスレのうちの確実に1割以上は date の話だろ。
ならば、リダイレクションの話。
freshclam > /home/update.log
freshclam 2>&1 > /home/update.log
freshclam 2>&1 | tee /home/update.log
どれも結果は同じ
cat /home/update.log | mail -s "`/bin/hostname` test" root
此れで、/home/update.logの内容をメールに受け渡し。
ダルゥ。。。
redirectionの代わりに何故catをかませるのかという議論で荒れたのって、
このスレだっけ?
sedで削除したり置換したりすることにしかシェルを使ったことがないので
質問の仕方に変な箇所があるかもしれませんがご了承ください。
ということで、やりたい事を書き直します。
1日に1度、wgetでデータをダウンロードして
日付.logというファイル名で保存しています。
このファイルの1行目に日付を挿入したいと考えて最初の質問をしました。
現在はダウンロードしているだけですが
このファイルの1行目に(date --date '1 days ago' +%Y/%m/%d)を
挿入する方法をご教授ください。
#!/bin/sh
log1=`date --date '1 days ago' +%y%m%d.log`
log2=`date --date '1 days ago' +%y%m%d.log2`
cd ログ保存ディレクトリ
wget
ttp://www.hogehoge.com/log/$log1 mv $log1 $log2
sed -e '/要らない文字/d' $log2 > $log1
rm $log2
cd
>>258 やってることがイマイチわからんが mv の後に
echo `date --date '1 days ago' +%Y/%m/%d` > $log1
sed -e '/要らない文字/d' $log2 >> $log1
じゃ駄目なのけ?
sed の行を↓
(date --date '1 days ago' +%Y/%m/%d; sed -e '/要らない文字/d' $log2) > $log1
$log2 って一時ファイルなのね、、、分かりにくい。。。
日付のみが書かれたファイルに>>するとかじゃだめか?
おう、遅かった
>>260見て気付いた、echo 要らないね(;´Д`)
264 :
名無しさん@お腹いっぱい。:05/02/09 00:09:21
質問です。born shで、
catした結果、grepした結果をstderrに吐く、ということはできるのでしょうか?
できるとしたらやり方を教えた下さい。
man読む
>>259-260 ありがとうございます。
期待通りの結果で出力されました。
今晩はぐっすり眠れそうです。
ごめんなさい、bourne shねんですね。
初めて知りました。
>>265 ネットではイロイロ探してみたのですが、
manでは何をキーに探せばいいのか見当がつきませんでした。
xxxの使い方、オプションとかならmanも見るのですが。
>>256 >どれも結果は同じ
freshclam がエラーメッセージも標準出力に出すのなら、
それでいいけど、
> /home/update.log
2>&1 > /home/update.log
と
2>&1 | tee /home/update.log
はちがうよ。
269 :
07041050335728_ac:05/02/09 00:36:57
>&2
>>267 man sh
あなたの見るのがどのOSの何語のmanかは知らないが、
redirectかredirection (日本語ならリダイレクト/リダイレクション)で
検索してそれっぽいところを読むといいでしょう。
でもリダイレクトはシェルの使い方の基本中の基本なので、
テンプレから適当な入門ページを見てみるのがいいと思います。
>>267 > ネットではイロイロ探してみたのですが、
次からは質問前にテンプレを見てみるというのも探し方に入れてください。
>>270 すみません、テンプレにあるサイトは一通り
流し見たのですが。。。正直、すべてのページを目が乾くまでは
じっとりと診てないです。
あと、私が質問している内容は、
「stderr を ファイルにリダイレクトする」のではなくて、
「ファイルの中身を、stderrに出力したい」のですが、ということなんですが。
("シェルの基本"の部類に入るのでしょうか?)
じゃあ諦めろ。
>>271 ちょっと確認してみました。
>>2 の先頭にある「Bourne Shell自習テキスト」の2.3とか、
2番目にある「シェルを使おう」の2.2.2などはどうでしたか?
全部を全部舐める必要はありませんが、入門テキストっぽいところで
ご自分にあってそうなところを一つ選んで、学習してみてください。
> 「ファイルの中身を、stderrに出力したい」のですが、ということなんですが。
> ("シェルの基本"の部類に入るのでしょうか?)
まごうことなき基本中の基本です。
>>273 ありがとうございます。
ヒントとしては、「シェルは標準入力・標準出力・標準エラー出力の
3つのファイルをオープンしており、それらはファイルディスクリプタ
「0 .. 3」として管理しています」
のところなのだろうか・・・というところまでは理解しました。
ここ1年ほどシェルを触りはじめましたが、まだわかっていないことが多すぎたようです。
ご丁寧にありがとうございました。
シェル言うな
シェルでも問題なかろう?
ていうか、274の文章に限っては
「シェルスクリプト」は標準入力...をオープンしており...管理しています
としてしまうと逆にヘンだろ。
個人的にはパイプとかリダイレクションが何をやってるのか分かったのは
APUEを読んでからだった
file descriptor って何だよってかんじで
APUEは最高のUNIX入門書
昔はUPEだったなぁ
UNIXプログラミング環境は紀伊國屋に売ってたなぁ
欲しかったけど Life with UNIX 買っちゃってお金がなかった
284 :
名無しさん@お腹いっぱい。:05/02/10 22:16:05
286 :
初心者:05/02/10 22:55:28
スレ違いでしたらごめんなさい。
alias でコマンドに別名をつけたとします。
.bashrc に 'ls -aF' を l で別名つけました。
この別名をシェルスクリプトから呼ぶことができないのは
なぜなんでしょうか?
よろしくお願いします
シェルスクリプトが.bashrcを読まないから。
288 :
名無しさん@お腹いっぱい。:05/02/10 23:02:29
.bashrcはログイン時に実行されてるのですが。
コマンドラインでalias設定してもスクリプトから
別名をよぶことができませんでした。
なんでですか??
ログインシェルが覚えてるalias定義は、そこから起動されるスクリプトには受け継がれません。
290 :
286:05/02/10 23:13:12
そーなんですか、そういうものなんですね。
レスサンクス!!
シェルスクリプトの中で自分のalias使いたきゃ、
シェルスクリプトの先頭で . ~/.bashrc とか書いとけばできるが、
そんなことをするのは超邪道。
どうしてもやりたければ代わりにシェル関数使え。
それ以前にプロセスというUNIXの基本を理解してない。
おれも邪道だと思うが、
Linuxのいくつかのディストロがデフォルトで . ~/.bashrc ってやっているのがあるなぁ。
せめて、
$grep alias ~/.bashrc|while read l;do eval $l;done
とするとか。
>>294 \ でつないで複数行になってたらどぉするよ
テキストファイルの各行で先頭5文字を削除したいのですが
どのように書けばよいか教えていただけませんか?
以下適当な文字列
aiueokakikukeko
sasisuseso
tachituteto
naninuneno
を
kakikukeko
useso
tuteto
uneno
のように、先頭5文字を削りたいのですがお願いします。
sed -e 's/.....//'
sed ':label;/\\$/{N;s/\\\n/ /;b label}' ~/.bashrc |grep alias |while read l;do eval $l;done
303 :
名無しさん@お腹いっぱい。:05/02/14 14:43:42
colrmはSolarisで使えないから避けるが吉。
Solarisってうざすぎ
307 :
名無しさん@お腹いっぱい。:05/02/14 15:06:35
>>296 sed -e "s/^.\{5\}//;"
308 :
名無しさん@お腹いっぱい。:05/02/14 15:41:38
文字列を区切文字で行に変換する方法を教えて下さい。
例えば
abc de fgh ijk
を
abc
de
fgh
ijk
にしたいのです。
sed 's/ /\n/g'
awk '{for(i=1;i<=NF;i++)print$i}'
311 :
名無しさん@お腹いっぱい。:05/02/14 16:03:02
>>309 全部くっつきました。
abcndenfghnijk
echo 'abc de fgh ijk' | xargs -n1
echo 'abc de fgh ijk' | tr ' ' '\n'
>>313 sed で \n は使えないよ。
sed 's/ /\
/g'
だな。シングルクォート中で改行するので、
B-shell系のコマンドラインで実行すること。
316 :
名無しさん@お腹いっぱい。:05/02/14 16:48:44
使えました。
$ sed --version
GNU sed 4.0.5版
sed の \n だけど、
GNU 3.x の sed では NG
FreeBSD 4.x の sed でも NG
試してないけど多分 Solaris の sed でも NGでは?
Linux 板じゃないから GNU 前提は避けた方がいいな
>>299とかも
48時間データを24時間データにしたいのですが良い方法はありませんか?
行数を指定して削除しようと考えていたのですがデータ欠損時に行数が狂ってしまうため
date --date 'today' +%y/%m/%d;に該当する行を削除したいのですがお願いします。
05/02/13 00:00 123 118
05/02/13 01:00 124 200
05/02/13 02:00 129 195
(中略)
05/02/13 18:00 124 210
05/02/13 19:00 124 210
05/02/13 20:00 118 194
(中略)
05/02/14 02:00 128 212
05/02/14 03:00 127 181
05/02/14 04:00 125 192
(中略)
05/02/14 18:00 121 172
05/02/14 19:00 125 183
05/02/14 20:00 126 182
少し前のレスにdateは・・・とありますがお願いします。
悪いが意味わからん
と思ったが、
sed /^`date '+%y\/%m\/%d'`/d
のことだろうか
323 :
名無しさん@お腹いっぱい。:05/02/14 22:41:53
>>320 TODAY=`date +%y\\\/%m\\\/%d`
sed /"^$TODAY"/d infile > outfile
↑でできます。
正規表現の中の/をエスケープするために\が要り、
さらに、` `で取り込むために\が\\に、\/が\\/になって、
結局\\\/という、禿げしく複雑なフォーマットになりますが、
これでできますよ。
>>321 わからない君は答えなくていいよ。
うはwwwwwwwzshでwwwwやってみたwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
#!/bin/zsh
typeset -r DATE=$(date --date 'today' +%y/%m/%d)
while read -r line; do
[[ "$line" != "$DATE"* ]] && print "$line"
done
うはwwwwwwwしかもwwwwwwwwwwwwwwwwかぶってwwwwwwるwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
>>296 ほほぉ。
eelsPBG4:~ sheel$ echo "1234567890" | colrm 6
12345
eelsPBG4:~ sheel$ echo "1234567890" | cut -c6-
67890
eelsPBG4:~ sheel$ echo "1234567890" | sed -e "s/^.\{5\}//;"
67890
>>308 ほほぉ。
eelsPBG4:~ sheel$ echo 'abc de fgh ijk' | xargs -n1
abc
de
fgh
ijk
eelsPBG4:~ sheel$ echo 'abc de fgh ijk' | tr ' ' '\n'
abc
de
fgh
ijk
>>323 ありがとうございます
3回もエスケープする必要があったんですね
質問させてくださいませ
bash で 関数内にヒアドキュメントって使えますか?
やりたいことは定時FTP転送で、中に変数も使いたいから
関数にしようとしたんだけど、ヒアドキュメントっていう
か「<<」がだめっぽくてエラーが出ちゃいます。
なんかいい方法ないでしょうか?
>>328 bashに限らず、シェル関数内でもヒアドキュメントは使える。
うまくいってないのは別の原因と思われ。
やったことをもう少し詳しく書け。
>>330 ごめんすぐわかった。
ftp -n >> _EOF
< COMMAND >
_EOF 2> xxx.log
ってやってたのがだめだったんですね。
COMMANDをファイルにまとめて書いていたときは、上記の感じで
エラー出力してFTPが成功したかどうかを判別してたのです。
シェルのftpコマンドでFTPが成功したかどうかを調べるいい方法
はありますか?
おい、顔出すのはMac版だけにしとけ。
>>326 Paperが相手してくれてんだろ?
334 :
328:05/02/15 00:37:44
>>332 うおお…ありがとう。
これでできます。ほんとにありがとう!
335 :
名無しさん@お腹いっぱい。:05/02/15 07:36:39
1行に不定個の文字列がありそれを逆順にする方法を教えて下さい。
例えば
abc de fgh ijk
ijk fgh de abc
にしたいのです。
(A=;for i in ab cd ef;do A="${i} $A";done;echo $A)
小出しに宿題をやらされている気がするのは猛霊だけだろうか
>>336 それじゃ標準入力から読めない。
↓にしとけ。
while read line
do
str=
for s in $line
do
str="$s $str"
done
echo "$str"
done
339 :
名無しさん@お腹いっぱい。:05/02/15 08:34:32
sedじゃ無理ですか?
perlならこうか?
perl -ane 'print join(" ",reverse @F),"\n"'
awkならどうやるんだろ。
341 :
名無しさん@お腹いっぱい。:05/02/15 09:27:22
>>339 sedでやるなら↓
ただし、
* 文字列中に%が含まれていないこと
* スペースは1個のみで区切られていること
Copyright by me.
sed '
:loop
/ /{
s/^\(.*\) \(.*\)/\2%\1/
s/%\(.*\) \(.*\)/%\2%\1/
b loop
}
s/%/ /g
'
awk ならこんな感じか。区切文字まで面倒みないが
awk '{for (i=NF; i>=1; i--) {if (i==1) print $i; else printf $i" "}}'
すまん。
>>341 は一部ミスってる。発想はこんな感じなのだが・・
宿題っぽいのであとはお前らへの宿題にしとく。
344 :
名無しさん@お腹いっぱい。:05/02/15 09:40:42
>>341 ありがとうございます。 すげー! 腰がぬけました。
sed,awkって人を幸せにしてくれるな
346 :
名無しさん@お腹いっぱい。:05/02/15 09:44:07
今度こそできた。
sed '
:loop
/ /{
/%/{
s/\(.*\)%\(.*\) \(.*\)/\1%\3%\2/
b loop
}
s/^\(.*\) \(.*\)/\2%\1/
b loop
}
s/%/ /g
'
もっと簡単になった。
sed '
:loop
/ /{
s/\([^%]*\) \(.*\)/\2%\1/
b loop
}
s/%/ /g
'
348 :
名無しさん@お腹いっぱい。:05/02/15 10:42:20
>>347 またまたありがとうございます。
ちょっと弄ってみました。
sed '
:loop
s/\([^%]*\) \(.*\)/\2%\1/
t loop
s/%/ /g
'
shだけ使って無駄に複雑に
foo () {
local s
case $# in
0) ;;
*) s=$1
shift
foo "$@"
echo -n "$1 "
;;
esac
}
while read line; do
foo $line
echo
done
>>349 「shだけ」というなら、
local使っちゃいかんだろ。
シェルスクリプトの中で
処理状況をログファイルに書き込む場合、
echo "状況" >> ログファイル
としていますが、
ファイルの末尾に追加していく方法ではなくて、
逆に先頭行に挿入していく方法を
ご教示下さい。
今はテンポラリファイルに最初状況を書いて、
今までのログをcatで入れていますが、
ログファイルが大きくなるにつれ、遅くなりそうです。
今のファイルシステムでは、
仮にシェルがそんな機能をサポートしていたとしても、
巨大なファイルを扱えば重くなる。
速い方法はない。どうやっても遅くなる。
そもそも先頭に挿入したいってのが変すぎる。
真の要求は別にあって、やり方を間違えてる
だけなんじゃないの?
>>352-353 早速の回答ありがとうございます。
分かりました。ないですか。
ファイルシステム関連で無理な話なら、
対象処理を優先させるのが常識なので、
ログファイル書き込みでは追記書込をし、
最終的にそのログをtacを使って
別の逆順ログファイルを作成することにしました。
>>353 仕様云々ではなくて、技術的な面から純粋に
書込時にファイルの先頭にデータを挿入するのに
(てっとり)早い方法があるかどうか聞いてみただけです。
もしあれば、データのみのファイルに
ヘッダーを付ける場合も、
自分でテンポラリファイルの作成なしに、
リダイレクト感覚で(内部ではテンポラリを使うかもしれないですが)
できると思いましたが、そうは問屋がってやつですね。
ページサイズごとにファイルくっつけると速くなるかも
てゆうか、なんで逆順ログファイルなんてものが
必要なのかしら? 普通不要。
実は tail コマンドを知らんとか、そういう落ち
だったりして。
>>357 なのに head だけは知ってる(笑)
>>356 そこまで逆順のログファイルが何故必要なのか
知りたいのなら、トータルで一番良い方法を
教えて下さい。
そのログをイントラ内でWebにより公開するのですが、
仕様決議で、(ブラウザのスクロールの操作無しに)
新しい情報であればあるほど、最初に見ることが出来た方が
良いから、逆順に表示されたものが見たい、とのことです。
要求がそうしたいとのことなので、どうしようもないです。
あと、ちょっとかけ離れますが、逆順のログということでは、
よくWebページの更新ログも逆順が多いですよね。
それが、変かどうかは人によって違うわけですしね。
Servlet内で正順のログを動的に逆順に読むと、
その処理で、Webページの表示が遅くなるので、
それなら元から逆順のデータがあれば、
コードも簡潔になるし、早く表示できるからです。
それか、DBでテーブル化しちゃうかかな...
そこまでのことでもないのだけどな。
>>357-358 念のため、tailを使わなかった。
-rオプション可能なtailとtacを調べてみたら
何故tailを使わないかが分かるよ。
>そこまで逆順のログファイルが何故必要なのか
>知りたいのなら、トータルで一番良い方法を
>教えて下さい。
俺なら、ブラウザの1ページに収まる程度の内容だけ
tail -40 くらいで切りとって、それを servlet で
逆順に表示するね。ログが長い場合、この方が tac
を使うよりも計算量がはるかに少なくて済む。
全ログを見たい場合には、逆順じゃなくて正順のまま
で表示。最後にアンカーを置いておいて、そこに飛ぶ
ようにはしておいてもいいかもしれん。
>>359 ログは追記しか考えられないな。
表示は1画面分(当然仕様で決まってるよね?)を
tailしてきて表示時にひっくり返す。
なぜファイルレベルでひっくり返さなきゃならんのか不明。
要求する人は中の人がファイルの尻に追記してたって、
頭に挿入してたって関係ないわけで、詳細設計や実装する人は
要求定義をそのままコーディングするんじゃなくてコンピューターが
やりやすいようにやんなきゃダメよん。
>>362 お、被ってる。
ふつうこうするよなぁ。
ま、要求が変というのもあるがな。
ログなんて時間順に上から下に並ぶのが一番自然なわけで、
たまたま今のブラウザが、ページを開いたときに一番上を
最初に見せることしかできないからといって、
そっちに合わせてログを逆順にしなきゃという発想がそもそもいかん。
一番下が最初に現れるようにするのが正統。
>>359 正順で記録しといて、rotate の際に逆にするとか。
rotate されてない分は表示するときに逆順にする。
それかがんばって逆順で記録。
何がトータルで一番良いかは状況によるのでなんとも。
>>365 そんなに変でもないと思うよ。
はじめまして、「悩める20代」です。
Kシェルの初心者ですが、皆様のお知恵をお借りしたく投稿しました。
Kornシェルのスクリプトでログを出力するシェルを作成しました。
しかし、ログが改行されて出力されてしまいます。
原因はスクリプト内でdateコマンドを実行しているのですが、最後に改行文字が負荷されてしまうようです。
調べているのですが、何か良い方法をご存知ありませんか?
<実際のスクリプト>
#!/bin/ksh
# 日付を出力
date "+%Y-%M-%d %H:%M:%S" >> a.txt
# ログメッセージを出力
echo " [INFO ] : 〔GQE1001I〕 テーブル名 TTTTT のリフレッシュが正常に終了しました。" >> a.txt
<出力結果>
2005-58-15 16:58:30
[INFO ] : 〔GQE1001I〕 テーブル名 TTTTT のリフレッシュが正常に終了しました。
<本当は以下のようにしたいです>
2005-58-15 16:58:30 [INFO ] : 〔GQE1001I〕 テーブル名 TTTTT のリフレッシュが正常に終了しました。
変とかそういうあいまいな話じゃなくて、
逆順に記録するならたかがログにファイルロックとかせなあかん。
ちょーマンドクセ
表示の時にちょいと工夫すりゃいい話。
極端な話、表示順を逆順にする程度のことは
javascript等(=クライアント側)にやらせてもいいわけで。
・シェルスクリプトのことをシェルってゆーな by
>>1
>>367 echo -n `date hogehoge`
>>361-366 どうもありがとうございます。
説明がまずかったです。
スクロール無しというのは、
最新データを見たい場合のことです。
イントラ内なので、転送速度は問題なく、
別ページに遷移は面倒だから、
1回の処理=1ファイルでを
全部表示させる仕様です。
(ファイルはrotateします。)
関係ないかもしれませんが、
私も2chはかちゅだけど、全部表示ですしね。
それはそれでユーザに同意してます。
あと、最初の文章は煽っているわけでも
ありません。
すみません後から見るとそう見えますね。
処理を洗い出すので、どこか良い改善策が
あれば教えて下さいと言う意味でした。
リンクで(逆順の)ファイルを表示させる
のが一番シンプルで効率的なので、
今のところその方向でいきます。
正順で表示し、javascriptで最後尾にスクロールも
試してみます。(要件としては最初に最新のものを
見たいということなので)
それで、昇順、降順をどっちも実装します。
いろいろありがとうございました。
そもそもtacで重くなるようなサイズのログをwebで出されても
>>367 echo には
>>370さん がかいてるように -n がある。
そういったオプションが無いコマンド(date など)は
コマンド | tr -d "\n"
で \n を削除。
とりあえず、man tr を。
>>367 # 日付けとログメッセージを出力
echo `date "+%Y-%M-%d %H:%M:%S"` " [INFO ] : 〔GQE1001I〕 テーブル名 TTTTT のリフレッシュが正常に終了しました。" >> a.txt
date '+%Y-%M-%d %H:%M:%S [INFO ] : 〔GQE1001I〕 テーブル名 TTTTT のリフレッシュが正常に終了しました。' >>a.txt
cp $FILES $DIR
ってかくと$FILESが空の時にエラーになってしまい
Makefile等など途中で終了してしまうのですが、
どう回避するのが手軽でよいしょうか。
よろしくお願いします。
>>376 空にならないようにする
空の時に実行しないようにする
test -z "$FILES" || cp $FILES $DIR
>よろしくお願いします。
何を?
っつか、ウェブで閲覧するっていうんなら、
そんなぐだぐだリネームしなくっても、
Options Indexes
で即解決なんじゃないの?
ソートできるよね?
Makefile でそこでエラーが出ても後続の処理に問題がないのなら、
頭に-を付けて無視すればいい
-cp $FILES $DIR
既存のCシェルスクリプトに対して、
trapにより、 trap 'exit 3' 15
して、kill信号のみをtrapしたいんですけど、
使うと、そのコマンドはないです。 と怒られます。
しかし、Cシェル用のonintr で、goto先指定すると、
全ての割り込みに対して、gotoしてしまうので、×です。
できれば、既存のCシェルスクリプトをあまり変えることなく
trap 'exit 3' 15 したいんですけど、 いい案はないでしょうか?
>>383 いい案はない。
cshは捨てろ!
以上。
だとすると逝ってよい
awkで困ってます。
n.datの中身
----------------------------------------
a,0,A,AAAAA,BBBBBBBB,wait,,,,
a,0,A+0217,AAAAA,BBBBBBBB,wait,,,,
a,0,A=0217,AAAAA,BBBBBBBB,wait,,,,
a,0,A+0218,CCCCC,BBBBBBBB,disable,,,,
a,0,A+0219,AAAAA,BBBBBBBB,hold,,,,
a,0,B+0217,BBBBB,BBBBBBBB,disable,,,,
ここから、+0217が含まれる行を取り出して。。。と考え、
awk -F, '$3~\+0217 {print $4,$6}' n.dat
としたのですが、エラーでうまくいきません。
ご教授いただけますでしょうか。
リダイレクトに関する質問です。
メッセージを標準出力とファイルの両方に出力するにはどうすればいいでしょうか。
Makefileの生成コマンドに記述したいのですがエレガントな方法が思いつきません。
具体的には、次のようなことがしたいのです。
cc -c hoge.c 2> err; cat err; cat err >> error
エラーを標準出力に表示しつつも、errorファイルに記録したいのですが、
なんかかっこ悪いし、makeを-jオプション付で実行したときの一時ファイルerrの
排他なんかも気になります。
特別なコマンドを使う等の環境依存はないようにしたいのですが、よい方法はないでしょうか。
>>387 awk -F, '$3~/\+0217/ {print $4,$6}'
>>388 標準出力も標準エラー出力も、画面とファイルに出力するなら、
cc -c hoge.c 2>&1 | tee err
>>389 ありがとうございます。うまくいきました。
で、今度は応用として、変数も使いたいと思いまして、
MMDD=+0217
nawk -F, -v TDAY=$MMDD '$3 ~TDAY{print $4,$6}' n.dat
としたのですが、エラーになります。。。
+がネックになるみたいです。
教えて君で申し訳ありません。ご教授いただけるとありがたいです。。。
>>391 そういう場合は、awk側の変数を使わずに、
シェル変数として展開させる。
MMDD=+0217
awk -F, '$3 ~/'$MMDD'/ {print $4,$6}' n.dat
シングルクォートを一回閉じてから $MMDD を挟み込んでいることに注意。
>>390 うを、teeなんてコマンドが。
ありがとうございます。抜群でした。
>>392 MMDD="\+0218"
awk -F, '$3 ~/'$MMDD'/ {print $4,$6}' n.dat
これでいけました。
ありがとうございます!ほんとうに助かりました!
1つのファイルを2つに別けたいのですが
その方法をご教授ください。
[test.txt]
AAAAhogeBBBBB
ABCDEFGhogeHIJKL
12345hoge67890
maehogeusiro
1行にhogeが1回しかないことを前程にして
[mae.txt]
AAAA
ABCDEFG
12345
mae
[usiro.txt]
BBBBB
HIJKL
67890
usiro
mae.txtとusiro.txtに別けたいのですがお願いします。
スクリプトと関係ない話が続く。
シェルスクリプト書くための要素技術なんだからいいんじゃない?
>>395 sed 's/hoge.*//' test.txt
sed 's/.*hoge//' test.txt
>>395 awk -F hoge '{print $1}' test.txt > mae.txt
awk -F hoge '{print $2}' test.txt > ushiro.txt
おや、このスレはえらい親切モードだね。
400 :
名無しさん@お腹いっぱい。:05/02/18 17:06:53
教えない君は何ごとにも小さい奴。職人に多い。
シェルスクリプトに関する質問なら俺様がいくらでも答えてやる。
どんどんかかってこい。
ていうかさ、いろんなコマンドを組み合わせるglueとして働くのが
シェルスクリプトの便利なところ強力な所で、
>>395などは適切な質問だろ。
(もし)それをわからないというなら、スクリプトの便利さ強力さを理解してない。
(もし)それをわかってて
>>396みたいなレスしたなら、人に誤解を植えつける意地悪。
あーそうか、簡単すぎてスクリプトにならんだろ(glueいらんだろ)という話か。
それはそうだったかもな...
404 :
名無しさん@お腹いっぱい。:05/02/18 17:25:33
では、
10進数を2から16進数各々に変換する、
また、逆を行うスクリプトでかなりイケてる
ものを教えて下さい。
>>404 別にイケてないけど、漏れの.bashrcに↓こう書いてある。
function 2to8 () { dc -e "8o 2i $1 p"; }
function 2to10 () { dc -e "2i $1 p"; }
function 2to16 () { dc -e "16o 2i $1 p"; }
function 8to2 () { dc -e "2o 8i $1 p"; }
function 8to10 () { dc -e "8i $1 p"; }
function 8to16 () { dc -e "16o 8i $1 p"; }
function 10to2 () { dc -e "2o $1 p"; }
function 10to8 () { dc -e "8o $1 p"; }
function 10to16 () { dc -e "16o $1 p"; }
function 16to2 () { x=`echo $1|tr '[a-z]' '[A-Z]'`; dc -e "2o 16i $x p"; }
function 16to8 () { x=`echo $1|tr '[a-z]' '[A-Z]'`; dc -e "8o 16i $x p"; }
function 16to10 () { x=`echo $1|tr '[a-z]' '[A-Z]'`; dc -e "16i $x p"; }
406 :
名無しさん@お腹いっぱい。:05/02/18 17:35:38
たぶん、最強
echo "obase = $ot; ibase = $in; print $un, \"\n\"" |bc;
% cat calc.sh
#!/bin/sh
num=$1
base=$2
w3m '
http://www.google.com/search?q='${num:=10}'+in+'${base:=binary}
% ./cals.sh 10
% ./cals.sh 10 octal
% ./cals.sh 10 hexadecimal
% ./cals.sh 0x10 decimal
% ./cals.sh 0b10 decimal
...
>>407 面白いな
翻訳機能板とかも持ってるだろ?それも出せ
>>404 何をイケてるというかによるが、適材適所なら
>>406のbc使うのがいいだろうな。
expr使って桁ごとにがんばるのは馬鹿げてるし、
ましてやテーブル作ってexprの真似ごとをshでやるのはもっと馬鹿げてる。
馬鹿げてるから楽しい。
>>408 いや、持ってない(w。でも、普段はコマンドラインや w3m では使ってるから、手抜きの
スクリプトを作ってみた。
% cat ./tarns.sh
#!/bin/sh
TMPFILE=/tmp/trans.$$
trap 'rm -f $TMPFILE' 0 1 2 15
w3m='w3m -no-proxy -o use_history=0 -o confirm_qq=1'
t_or_u=$1
from=$2
to=$3
if echo $t_or_u | grep '^http' >/dev/null 2>&1; then
$w3m
http://translate.google.com/translate_c'?u='${t_or_u}'&langpair='${from:=en}%7C${to:=ja}
else
echo -n 'text='${t_or_u:=text}'&langpair='${from:=en}%7C${to:=ja}'&ie=EUC-JP' > $TMPFILE
$w3m
http://translate.google.com/translate_t -post $TMPFILE
fi
% ./trans.sh test
% ./trans.sh 'My name is unknown' en ja
% ./trans.sh 'Ich liebe dich' de en
% ./trans.sh 名無しさん@お腹いっぱい ja en
% ./trans.sh
http://www.yahoo.com % ./trans.sh
http://www.yahoo.de de en
...
ごめん、confirm_qq=0 の間違い
>>411-412 thanx!すごく楽しめそう
漏れの環境のw3m 3.22ではuse_history=0はエラーになった。
礼として漏れが使ってるのをうpする。
X上の端末でhtmlファイルを見つけた時に、mozillaで開く為のスクリプト
#!/bin/sh
if [ $# -gt 0 ]; then
ARG1=${1}
if [ ! -f "${ARG1}" ]; then
echo "${ARG1} was not found."
exit 1
fi
PATH1=`echo "${ARG1}"|cut -b 1`
if [ ${PATH1} = '/' ]; then
mozilla "file://${ARG1}"
else
PWD=`pwd`
mozilla "file://${PWD}/${ARG1}"
fi
else
mozilla
fi
exit 0
質問です。
以下のスクリプトを動かそうとすると、[: -le: unary operator expected と怒られます。
ぐぐったら、UNLIMITをどうのこうのと書いてありましたが、良くわかりません。
ちゃんと自分の考えた通りに動くのですが、このエラーメッセージを消すためにはどのような
ことをすればよろしいでしょうか。よろしくお願いします。
#! /usr/bin/bash
ulimit -c 0 #これをするとcoreファイルを作らない。
byeps(){ #選択したプロセスの番号が正しいかチェックする関数
read BYE
if [ $BYE -le $NUM ]; then
GO=1
elif [ $BYE -le $NUM ]; then
GO=0
echo -n "Please type the number you want kill,not ps number."
elif [ "$BYE" = "exit" ]; then
echo done
exit
else
GO=0
echo -n "Please type the number you want kill,not ps number."
fi
}
yn(){ #yかnかを聞く関数。
echo -n "${KILL[$BYE]} ${PROC[$BYE]} OK?(y/n)"
read REP
if [ "$REP" = "y" ]; then
PASS=1
kill -HUP ${KILL[$BYE]}
echo -n ${PROC[$BYE]} "is killed"
echo -e \\t
#elif [ !$REP ]; then
elif [ "$REP" = "n" ]; then
PASS=1
echo "Good bye."
else
PASS=0
echo -n "Please type y/n"
fi
}
###############メイン###################
NUM=`ps auwx | grep $USER | sort | wc | awk '{print $1}'` #自分のプロセスをwcした行の数字
ps auwx|grep $USER > $HOME/proccess.dat #proccess.datにpsの結果を代入
KILL=(`cat $HOME/proccess.dat|awk '{print $2}'`) #killするプロセス番号をkill[]に入れる
PROC=(`cat $HOME/proccess.dat|awk '{print $11 $12 $13 $14}'`) #パスをある程度分までPROC[]に入れる
echo -n "your ps auwx|grep" $USER "are ...."
echo -e \\v
for i in `seq 1 $NUM`; #C言語ふうのfor
do
echo -n "$i"
echo -e -n \\t
echo -n "${KILL[$i]}"
echo -e -n \\t
echo "${PROC[$i]}"
done
echo -n "Please enter the number you want to kill:"
GO=0
while [ $GO -eq 0 ];do
byeps #関数byeps
done
PASS=0
while [ $PASS -eq 0 ];do
yn #関数yn
done
rm -rf proccess.dat
exit
これは、kill プロセス番号とやるのにpsしてプロセス番号を調べないといけないのを億劫に思って、
スクリプトの勉強も兼ねて作ったスクリプトです。つたないですが、よろしくおねがいします。
すいません。さっき見てたときに412でレスがストップしていたので、413とかいてしまいましたが、
>>413さんとは
別の人です。ごめんなさい。
>>418 今、抗議しようと思ってたところだ
確かめずに番号書くなよ
416では
> if [ "$REP" = "y" ]; then
って書いてるのに、どうして415では
> if [ $BYE -le $NUM ]; then
にしちゃうんだよもん?。
>>420 頭がこんがらがってひとつにまとめることができませんでした。
ってか、こんな小さなプログラムなのに関数を作るなんてわたしはなにを考えているのでしょう。
ごめんなさい。少し時間を下さい。
seqをjotに変えて動かしてみたけど、エラー出ないぞ
ところでtopって知ってるかい
>>423 はうあ!!! topでk押したら大変なことが起きました。
ありがとうございますだ。m(_ _)m
>>378,381
ありがとー^^おかげで解決しました。
427 :
名無しさん@お腹いっぱい。:05/02/19 17:52:39
aはb,c...から作られていることを表すリストa: b, c, ...から
aからxまでのパスを見付けたい。
例えば
c: a, b
d: a, c
e: b, c
f: d, e
aからfまでのパスは
c: a,b
d: a, c
f: d, e
となるスクリプトを教えて下さい。
シェルスクリプトでやる意味あんの?
ム板のお好きな言語のスレへ行くのが適切では。
>>427 うはwwwwwwwwwww何をww言ってるかwwwwwwwww分からないwwwwwwwwwwwwwwwwwwwwwwwwwww
>>427 後半の意味がわからないが、make使えばできそう。
>>427 最終端から逆に辿っていけば楽にできるっしょ。
まぁ shell script で書く気にゃなれんがw
たぶん隣接リストでグラフ探索かなと予想
435 :
名無しさん@お腹いっぱい。:05/02/19 18:39:39
>>427 すみません、例題のパス指定を間違えました。
例えば
c: a, b
d: a, c
e: b, c
f: d, e
aからdまでのパスは
c: a,b
d: a, c
を表示するスクリプトを教えて下さい。
436 :
名無しさん@お腹いっぱい。:05/02/19 18:47:53
>>435 #!/bin/sh
echo "c: a,b"
echo "d: a, c"
なんか元の問題を推測するスレになってるw
> aからdまでのパスは
> c: a,b
> d: a, c
d: a,c だけでいいんじゃねーの? c: a,b が必要になる理由がわからん。
それとも b: a というルールがあるか a,b ともに初期条件なのか。
でもどう考えてもシェルスクリプト関係ねーし、
質問者の説明能力がchallengedだし、
ム板の宿題スレに行った方がいいと思うよ。
439 :
名無しさん@お腹いっぱい。:05/02/19 20:04:55
>>432 最終的にはクリティカルパスを求めたいのです。
440 :
名無しさん@お腹いっぱい。:05/02/19 20:14:52
#!/bin/sh
line1=________
line2=________
line3=________
line4=___OX___
line5=___XO___
line6=________
line7=________
line8=________
というシェルスクリプトで、
オセロの次の一手を求めるにはどう書けばいいでしょうか?
とりあえず、以下のスクリプトで、
現在の番面表示はできています。
echo \
"$line1
$line2
$line3
$line4
$line5
$line6
$line7
$line8"
すみません、2つの引数をとるシェルプログラムでその引数を四則演算するにはどうしたらいいですか?
書き忘れました、環境はRed Hat Linux release 7.1です
>>441 まさか、
expr $1 + $2
とか、
echo "$1 + $2" | bc -l
とか、そんな基本中の基本を聞いてるんじゃないよな?
>>439 一行で書けるが宿題っぽいので教えない(AA略
>>440 echo -n "次の手を入力してください: "
read itte
このところいい感じだったのに、今日はひでぇな
>>440 ネタだろうけどマジレスするぞ。
. next_hand.sh
line1=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 1`
line2=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 2`
line3=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 3`
line4=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 4`
line5=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 5`
line6=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 6`
line7=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 7`
line8=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 8`
と、書けば、原理的には桶のはず。
あとは、シェル関数の定義が入ったnext_hand.sh の作り方次第だ。がんがれ。
>>450 それだと、シェル関数 next_handがidempotentでなかった場合、
lineごとに矛盾が起きる。
それに、そもそも8回も呼んでコマンド置換するのは無駄。
そもそもシェル関数の変数はグローバルなんだから、
内部で全変数に代入して終り。
よって、
. next_hand.sh
next_hand
でOK。あとはシェル関数次第w
>449
宿題君を甘やかすとどこでも必ずこーゆー流れになるな
ちうか、最初の呼び出しでline1壊しちゃうからダメじゃん。
マジレスといいつつ
>>450 自体もネタだな。
454 :
名無しさん@お腹いっぱい。:05/02/19 22:20:52
まぁこのスレもネタなんだけどな
455 :
名無しさん@お腹いっぱい。:05/02/19 22:58:08
シェルスクリプトとスクリプト言語(perl, ruby, python等)をどう
使い分けていますか?
シェルでできることなら、シェルスクリプト。
できなかったら、awk, perl 等のスクリプト。(ruby は嫌いじゃ。python は使ったことない。)
それでもだめなら、C とかで組む。
ちょっとだけのつもりだったシェルスクリプトが
肥大化して複雑怪奇になってから
こんなことなら最初からperlあたりで書けばよかったorzと後悔することも多い
460 :
名無しさん@お腹いっぱい。:05/02/19 23:37:43
>>455 Mac板に割にはえらい機能してるスレだな。
Paperとやらのレベルは低そうだが。
461 :
名無しさん@お腹いっぱい。:05/02/19 23:40:54
>>461 そいつは向こうでも馬鹿で嫌われてる奴だろう。
例えるなら n=(ry か?
464 :
名無しさん@お腹いっぱい。:05/02/20 00:25:58
ここで良いのか分かりませんが、
sedのコマンドファイルは30行ぐらいしか書けないとの制限がある
と聞いたのですが本当でしょうか?
試してみれば?
特定の文字列と文字列の間の文字列を抽出するスクリプトって無いですか?
'abcdefghijklmn' に対して 'abc' と 'gh' を指定すると 'def' を返すような。
それくらいsed使えば楽勝かと思って取り掛かったら、なんか全然難しくて orz
それくらい楽勝。正規表現を勉強するよろし。
sed だと最小マッチがないから単体だとやりにくいかもね。
echo "$1" | sed 's/^.*'"$2"'\(.*\)'"$3"'.*$/\1/'
じゃだめなの?
$ cat hoge.sh
#!/bin/sh
sed -e "s/^.*$1//" -e "s/$2.*$//" "$3"
$ echo 'abcdefghijklmn' | ./hoge.sh abc gh
def
条件にマッチしない行のことを考えると
sed -n "s/...../p"
じゃないとダメだと思う。
マッチするものが一行に複数ある場合も考えてみた
#!/bin/sh
sed -n "/$1/s/[^$1]*$1\([^$2]*\)$2[^$1]*/\1:/gp" "$3"
補足。
引数の$1,$2はそれぞれ1文字じゃないとダメ。
九九を表示するシェルプログラムをwhileを使って作成するにはどうしたらいいですか?
1 2
2 4
3 6
4 8
5 10
6 12
7 14
8 16
9 18 ・・・・
#! /bin/sh
cat 9x9table.txt | while read tmp
do echo $tmp
done
#!/bin/zsh
for ((i = 1; i <= 9; i++)) {
for ((j = 1; j <= 9; j++)) {
printf "%3d" "$((i * j))"
}
print
}
うはwwwwwwwwwwwwwwwwhile使ってwwwwwwないやwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
最後に#whileって付け加えりゃいいだろ
>478
>479
逝ってよし
#!/bin/sh
a=1
while [ $a -le "9" ]
do
b=1
while [ $b -le "9" ]
do
echo $a "x" $b "=" `expr $a \* $b`
b=`expr $b + 1`
done
a=`expr $a + 1`
done
yes ""|head -9|cat -n|while read a; do yes ""|head -9|cat -n|while read b; do echo $a x $b = $(($a*$b)); done; done
二つの引数の間の数を表示するシェルプログラムを作成してみよう。
回答例
test3.sh 3 5
3
4
5
お願いします
>>484 #!/bin/zsh
print -l {$1..$2}
>>484 echo -n $1 . ; while true; do echo -n 0; done ; echo 1
490 :
名無しさん@お腹いっぱい。:05/02/20 23:02:06
>>484 #!/bin/sh
seq $1 $2
ファイルサイズが0とそれ以外の場合で
実行結果を変えたいのですが、その方法を教えてください。
現状では
ファイルの編集 $ORIGINALFILE > $TMPFILE
cat < $TMPFILE >> $SAVEFILE
と、なっています。
これを、一時ファイルのサイズが0の場合に
$TMPFILEではなく$NODATAを実行するようにしたいのですが
どのように書き加えたらよいでしょうか?
[ -s
man test
man test
495 :
名無しさん@お腹いっぱい。:05/02/21 03:29:04
縦読み文章を作れるシェルスクリプトの書き方が分かりません。
どなたかご教授願います。
実行例
./aaa.sh "ゆにっくす"
ゆるぎない
にこちん
っつーのは
くそまみれの
するめいか
やなこった
たとえば"ゆ"で始まる文がたくさん欲しいよね
それはどうするの?
$ cat aaa.sh
cat <<EOF
ゆるぎない
にこちん
っつーのは
くそまみれの
するめいか
EOF
お題を出して、それに答えが返って来るのを見て喜んでる香具師がいるな
おまいら遊ばれてんじゃね?
501 :
名無しさん@お腹いっぱい。:05/02/21 11:26:08
それはそれで良いんじゃない?
catしただけの答えとか、
本人はそれで気の効いた回答だと思っているのかどうか、気になる。
気を効かせる必要はないので気にするな。
> それはそれで良いんじゃない?
予想外の反応だった…
何か自分の心の狭さを思い知らされたみたいで鬱だ… orz
しばらく消えます
有用でもなく、笑えるわけでもないレスを
なぜわざわざ書くのかは気になるなぁ。
>>493-494 man test 読んでもわかんね・・・・orz
週末にでも本屋に行って
>>3の本を探して立ち読みしないとだめかな
個人的には入門bashがおすすめ
Learning the bash shellを買った。
なかなか進まんw
>>507 >>2 のサイトを読んでみるといいと思う。本屋まで行かなくても読めるし。
とりあえず、一番上のBourne Shell自習テキストあたりを。
あとは man sh とか man bash とかやって
if list とかで検索すれば、if 文の説明があるはず。
512 :
名無しさん@お腹いっぱい。:05/02/22 10:24:53
イケてる小町算を見せて下さい。
513 :
名無しさん@お腹いっぱい。:05/02/23 10:37:26
>>512 ふつうの
#!/bin/bash
function koma () {
if [ $1 -eq 10 ]; then
if [ $(($2)) -eq 100 ]; then
echo $2 = $(($2));
fi;
return;
fi;
for aa in "" + -; do
koma $(($1 + 1)) $2$aa$1;
done;
}
koma 2 1;
linux板かと思った
質問です。(ここで良いか分かりませんが…)
PHPとか使ってブラウザから特定のシェルを実行させたいのですが、
どこかにサンプルや解説サイトってありませんか?
>>515 >>1 >・シェルスクリプトのことをシェルってゆーな
PHP でやりたいってのならスレ違いor板違いじゃないか?
>>515 「php exec」でググってくれ。
あとは、WebProg板で質問してね。
最近、シェルスクリプトの本を読み始めたんだけど「^」ってどういう意味?
ググってもいまいちズバって答えてるサイトが見つからなくて(´・ω・`)
優しくてエロい方、教えてください。
>>520 まじまじまじで?
では「learning the bash shell」のP106から引用します。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーー
function lsd
{
date=$1
ls -l | grep -i "^.\{42\}$date" | cut -c55-
}
ーーーーーーーーーーーーーーーーーーーーーーーーーーーー
↑
ここ
ちょっとずれたがご勘弁。優しくてエロい方、お願い!!
エロくないので自粛しよう。
正規表現
文頭
>>521 grep -i "^.\{42\}$date"が^を解釈すべき文脈。
というわけで、grepの引数に^がどう解釈されるか調べるといいよ。
まずはmanだね。
正規表現という話に行き当たるはず。
つか、その関数、期待どおりに動くか?
昔のshは ^ がパイプだったなぁ
>>523 (`・ω・´)
>>524,525
ありがとうございます。実はmanも読んだし、正規表現や文頭というキーワードも
掴んでいるんですが。
man grepから引用。
ーーーーーーーーーーーーーーーーーーーーーーーー
The caret ^ and the dollar sign $ are metacharacters that respectively
match the empty string at the beginning and end of a line.
ーーーーーーーーーーーーーーーーーーーーーーーー
この「the empty string at the beginning」という表現が分からないんです(´・ω・`)
the empty stringってのがなんの為にあるのか。
これは標準出力の文頭には必ず存在するものっていう解釈でいいんですかね?
>>526 動きますよ。
一応、「learning the bash shell」からさらに引用します。
ーーーーーーーーーーーーーーーーーーーーーーーーー
If this isn't the case in your version of UNIX, you will need to adjust the column numbers.
ーーーーーーーーーーーーーーーーーーーーーーーーー
>>528 「行頭」という特定の文字は存在しないよ
ってことを言っているのでわ。
"$" で言えば,
"$" は改行コードにマッチするわけじゃなく,
行末という概念的な(?)位置にマッチするんだよ,と。
>>529 なるほど。
grep -i "^.\{42\}$date"
の場合の^は、「行頭から数えて」という意味のようですね。
もやもやが晴れました。ありがとうございました。
#読むとほのぼのするスレだなぁ
>>527 エラク昔の話だねw
>>528 >この「the empty string at the beginning」という表現が分からないんです(´・ω・`)
'^' や '$' にマッチした部分文字列をあとで参照した時,空文字列になるということを
明示的に表現している。
極端な例だと,sedで「s/¥(^¥).*/¥1/」とか。
...って,余計分かりにくいか。要するに
>>529の理解で実用上問題ない。
^は、cshだと文字列痴漢だな。
^痴漢^置喚
534 :
名無しさん@お腹いっぱい。:05/02/25 16:03:49
アナルは性器表現?
卑猥な表現
あるファイルの特定の場所に特定の文字を記入するシェルスクリプトをかこうとしています。
自分で考えた方法は、
食事.shというファイルがあるとすると
echo "食べ物「/""$1"」を食べる
飲み物「/""$2"」を飲む" > menu.txt
とリダイレクションを利用し、
$ ./食事.sh カレー 水
で
$ cat menu.txt
食べ物「カレー」を食べる
飲み物「水」を飲む
として成功しました。
でもこれは、menu.txtをまるまる上書きしているだけです。
どうにか$1、$2の変数代入値を、直接menu.txtの「」内のみ
更新できるようなスクリプトを組みたいなと思い悩んでいます。
cutコマンドやgrepコマンドを使えばいいのかといろいろ考えてみたのですが、
どうもうまくいかないのです。
参考ページやアドバイスなどがありましたら、どうぞよろしくお願いします。
>>536 もしmenu.txtの「」内の変更で長さが変わったらそれ以降をすべてずらさないといけないので
"直接menu.txtの「」内のみ更新"は無理では?
叩き台ぐらいにはならないかな…
#!/bin/sh
ed menu.txt <<EOF
/「[^」]*」/s/「[^」]*」/「$1」/
/「[^」]*」/s/「[^」]*」/「$2」/
w
q
EOF
perl
540 :
名無しさん@お腹いっぱい。:05/02/25 21:30:52
ruby
いろいろ調べてみたのですが、シェルスクリプトで別ファイルの
文字列を編集するのは少々手間がかかるみたいですね。
perlかrubyか、何か言語を勉強してみようと思います。
まず正規表現の勉強をしろや
>>541 こんなのは?
##shokuji.sh
#!/bin/sh
INPUT=menu.txt
OUTPUT=menu.out
export TABE=$1
export NOMI=$2
sh -c "cat <<EOF > $OUTPUT
`cat $INPUT`
EOF
"
##menu.txt
食べ物「$TABE」を食べる
飲み物「$NOMI」を飲む
m4という選択肢もあるぞ。
546 :
名無しさん@お腹いっぱい。:05/02/27 23:40:54
Xwindow GUIプログラムをシェルスクリプトで制御する
やり方を教えて下さい。
killとか
>>3にも出ている『UNIXシェルプログラミング徹底解説』 p145
「whileとuntilの違いは、いつ条件が評価されるか、という点です。whileでは、ループを繰り返すかどうかが
最初に評価されます。そしてtestやコマンドの結果が真であればループのなかの処理が実行されます。
これに対して、untilでは、ループの中の処理が実行された後で、条件が評価されます。つまり、untilの
なかの処理は、最低でも必ず1回は実行されるわけです」
信じてたよ、4,800円も出したから(今は5,200円するらしいけど)… orz
危うく恥かくところだった…
正誤表探したけどないみたいだったので、ここに書き留めておきます
>>548 俺もそう思ってたけど違うみたいだね
user's guide to the z-shell にそう書いてあった記憶がある
ファイル名を一括して変更するのに
#!/bin/sh
for i in `ls *.dat` ; do
j=`echo $i | sed s/2004/H16/`
mv $i $j
done
こんな感じで書いたのですが、ファイル名にスペースが入ってると正常に動きません
でした。shからcshやtcsh、bashに変えて(shell依存部分はちゃんと書き換えて)みて
もやっぱりスペースがあると誤動作します。
forとかforeachでこんな感じでファイル名を一括部分変更するのは無理?
for i in *.dat でどうよ
あああとmv
>>550 j="`echo 略`" のように " " で囲んで、
mv のところの $i $j もそれぞれ "$i" "$j" と。
スペースで問題がでるときは " " で。
>551, 553
アドバイスありがとうございます。
両方の修正を行う事で期待通りの挙動になりました。
氏名と得点の表tokuten.txtがあります。
---- tokuten.txt ----
波田陽区 23
青木さやか 35
---- tokuten.txt ----
別途、氏名と学籍番号の対応表gakuseki.txtがあります。
---- gakuseki.txt ----
青木さやか 4001
波田陽区 4002
---- gakuseki.txt ----
やりたいことは、氏名に対応する学籍番号でソートして得点表を表示することです。
例で言えば、青木さやか 23、波田陽区 35、という順に表示したいのです。
学籍番号のように、ソートのキーが外部への参照になっている場合、
単純にsortコマンドを使うことができないと思います。
どうすれば外部のキーでソートして、青木さやか、波田陽区の順に出るでしょう?
なお、氏名が同一の者はいないという仕様でお答えいただいて結構です。
青木さやかの得点ちごうとる、35点やんか>自分
青木さやか 35
波田陽区 23
のような出力が得られればと思います。
宿題だろう。少しは自分で考えろよ。
join(1)ってコマンドがあるから、それ使えばできるよ。
555じゃないが初心者なので考えてみました。
下のようなのじゃ美しくない?
#!/bin/sh
for i in `awk '{ print $1 }' gakuseki.txt`
do
grep $i tokuten.txt
done
558じゃないが初心者なので考えてみました。
下のようなのじゃ美しくない?
sort -n -k 2 gakuseki.txt | \
sed "s/[ \t]\+[0-9]\+$//;s/.*/& &/;`sed 's|[ \t]\+\([0-9]\+\)$|$/\1/|;s|^|s/|' tokuten.txt`"
557で答が出てるのに558-559のようなのじゃ美しくない。
join(1)ってさ、natural join(RDB用語)じゃないんだよ。
natural joinしたい時には自分でバンバンしなきゃならんと思う。
ここでいうnatural joinとは、例えば青木さやかに関する得点行が
2つ以上あるときに、両方とも学籍番号4001を結び付けてくれることね。
join(1)は1つの行だけ4001を結びつけて、他の青木さやか行は捨てちゃうぞ。
555に関しては氏名が同一の者がいないからいいんだが、
一般にはnatural joinしたい場合の方が多くて(当社比)、とても困る。
例挙げると、得点表じゃなく、顧客への部品配送表だった時なんかだな。
joinってソートしたファイルでないとあかんのでないの?
>>561 当然氏名が同一じゃないっていう仮定を踏まえてるわけだが。
つーかああいう場合普通は学籍番号をユニークキーとして使うんであって、
同姓同名がありえる場合に氏名なぞキーとして使うわけない。
今気付いたけど「お答えいただいて結構です」てな凄い言いぐさだな。
>>564 すみません。「---という仕様でお教えください」と書けばよかったです。
557さんを始めとするみなさん、join勉強になりました。
確かにnatural joinもあるといいと思いました。
566 :
名無しさん@お腹いっぱい。:05/03/06 07:59:07
zshを使ってるんですが、cdした後にlsするのが面倒なのでいっそのこと
$alias cd='cd $1;ls'
としたのですが
$cd hoge
するとhogeには移動せずにhogeの中身をlsしやがります。ちなみに
$alias cd='cd $1;ls;'
して
$cd hoge
するとhogeに移動するけど ~/の中身をlsしやがります。
なんでですか。
>>566 なら初めから zsh のスレに書きたまえ
csh 系とは違って alias に引数を取れないよ。そういうときは関数を使う。
cd () { builtin cd $1; ls }
でも、この場合は関数 chpwd を定義するのが流儀にかなう。
568 :
566:05/03/06 16:27:07
>>567 スレ違いにも関わらずレスありがとうございます。
もしかしたらスクリプトではなくaliasの問題かなとうすうす思ってたんですが。
勉強になりました。
ディレクトリをfindつかって消すスクリプトってどう書いたら簡潔に書けるの?
find . -mtime +4 -type d -exec rm -rf {} \;
で消えてくれないのは仕様?
4日以前のバックアップのディレクトリを消したいんだけど。
shか bashでやれ。
-mtime +4
ここが間違ってるから。man 1 findしる。
-depth つけろというのが根本だろ
>>571 -mtime +4 は間違ってないよ。
GNU findなら。
いやそういう問題じゃないな、これ
非GNU findでも-mtime +4は使える。
多分、ファイルシステムががNFSマウントと思われ。
NFSの場合、あるディレクトリ以下のファイルを消しても、
それがオープン中だと、本当には消えず、
.nfsXXXX みたいなファイルが残り、
親ディレクトリが消せない。
たとえ rm -rf {} \; しても消えないよ。
>>573 ごめん、素で勘違いしてた。
GNU findでもBSD findでも同じ。
>>571=576ですが、読み返したら誤解を招きそうだったので補足。
-mtime +4は正しいです。
>>569ごめん。
パーミッションだったりして。
みなさんありがとう。
環境はSolaris9でUFSです。
rmでなくってlsにしたらちゃんと目的のディレクトリを表示できたんですけ
どrmにしたら消えてくれないんですよね・・・なんでだろ?
ファイルの整理は問題無くできてるけど、ディレクトリが消えてくれないから
tarにして纏めちゃおうかと思ってみたりもしてますw
ディレクトリ以下が2G以上あるんですけどね。
if 今いるディレクトリにあるファイル($FOO)が存在したら
rm $FOO
の if の箇所はどう書けばいいのでしょうか?
よろしくお願いします。
>>580 if [ -f "$FOO" ]; then
rm "$FOO"
fi
ただし、
rm -f "$FOO"
にすればそもそもif文は要らない。
どうもありがとうございます。
両方で確認しました。
>>579 find . -mtime +4 -type d -print | xargs rm -rf
でどう?変わらんかな?
# これでOKなら、
>>572の-depthでもOKなはずだが...。
> # これでOKなら、
>>572の-depthでもOKなはずだが...。
でもないや。この部分だけ前言撤回で。スレ汚しすまそ
>>583 本題には関係ないけど、
find (略) | xargs rm -rf
すると、
findで見つかったファイル名の中に、
「hoge . hoge」みたいに、
<space>.<space>を含むファイル名があると、
rm -rf . が実行されてしまうのでvery危険。
なので、おれはxargsは使わない派。
-print0
% man xargs
OPTIONS
--null, -0
Input filenames are terminated by a null character
instead of by whitespace, and the quotes and back-
slash are not special (every character is taken
literally). Disables the end of file string, which
is treated like any other argument. Useful when
arguments might contain white space, quote marks,
or backslashes. The GNU find -print0 option pro-
duces input suitable for this mode.
findの-print0や、
xargsの-0は、
GNU find, GNU xargsでしか使えないんだよ。
589 :
名無しさん@お腹いっぱい。:05/03/09 09:21:18
GNUマンセー
>>588 FreeBSD の man だと以下なので, posix 準拠な OS の場合は
xargs -0 は使えそうだが...
man xargs
-0 Change xargs to expect NUL (``\0'') characters as separators,
instead of spaces and newlines. This is expected to be used in
concert with the -print0 function in find(1).
STANDARDS
The xargs utility is expected to be IEEE Std 1003.2 (``POSIX.2'') compli-
ant. The -J, -o, -P and -R options are non-standard FreeBSD extensions
which may not be available on other operating systems.
man find
-print0
This primary always evaluates to true. It prints the pathname of
the current file to standard output, followed by an ASCII NUL
character (character code 0).
STANDARDS
The find utility syntax is a superset of the syntax specified by the IEEE
Std 1003.1-2001 (``POSIX.1'') standard.
All the single character options except -H and -L as well as the -iname,
-inum, -iregex, -print0, -delete, -ls, and -regex primaries are exten-
sions to IEEE Std 1003.1-2001 (``POSIX.1'').
少なくとも{Free,Open,Net}BSDでは使えるな
592 :
名無しさん@お腹いっぱい。:05/03/09 13:10:15
質問元です。Solarisは該当するオプションはなさそうです。Installしてもいいんですけど、もうちょっと考えてみますね。
素直に xargs -i rm -rf {} すればイイんじゃないのかね。
問題になりそうなファイル名のファイルがなかったら
気にしなくてもよいかと。
シェルスクリプトのことをシェルってゆー人が多いのが不思議です。
携帯電話をケータイって言うようなもんだ
携帯電話を電話って言うようなもんだ
JavaScriptをJavaって言うようなもんだ
シェルスクリプトはシェルが実行するが、
JavaScriptはJava(VM)が実行するわけじゃない。
PerlスクリプトをPerlって言うようなもんだ。
rubyスクリプトをrubyって言うようなもんだ。
もういいから。
ポストスクリプトをポストって言うようなもんだ。
ポストスクリプトをポストって言うようだなもん。
ポストスクリプトをポストって言ううなだよもん。
NullPointerExceptionをヌル(ry
ガッを力"(ry
608 :
名無しさん@お腹いっぱい。:05/03/11 08:36:32
send + more = money
を解いてください。
>>608 ググった方が早い。答えどころか、解くためのプログラムもでてるし。
611 :
名無しさん@お腹いっぱい。:05/03/11 16:46:53
シェル変数に入れてexprしまくればできるんじゃない?
bash限定なら (( 算術式 )) 使いまくれば高速かも。
613 :
名無しさん@お腹いっぱい。:05/03/11 18:19:36
/home/test以下にある幾つかのシェルスクリプトから文字列1・文字列2・文字列3を削除
したく思い、下記のようなスクリプトを作成したのですが、何故か文字列3しか削除されま
せん。
文字列1・2・3ごとにそれぞれ3つのスクリプトを作成し、順番に実行すると文字列1が削除
できた後に文字列2を削除するスクリプトを流すと文字列1が復活して文字列2が削除され
てしまいます。
何が悪いのでしょうか?教えて下さい
#!/bin/sh
for i in *.sh
do
sed -e "s/文字列1//g" $i > /home/test/$i
done
for i in *.sh
do
sed -e "s/文字列2//g" $i > /home/test/$i
done
for i in *.sh
do
sed -e "s/文字列3//g" $i > /home/test/$i
done
$iから読んでいながら、$i(/home/test/$i)に書いてもいるのが悪いと思う。
>>614 レス有難うございます。
何となくそれが理由っぽいですね。
このように、ある文字列を複数のファイルから削除したい場合はどんな方法が良いので
しょうか?
ファイルを加工する時は、別のファイルに出力して最後にファイル名を付け替えるのが常道。
テンポラリファイルの名前を作るのに$$(=シェルのプロセスID)を使ったりとか。
>>614 同じファイルだと空っぽになるだろう。
>>613は
> /home/test以下にある幾つかのシェルスクリプトから
といいながら別のディレクトリで作業してると思われ。
>>615 言ってることとやってることが違うようだが、
sed のスクリプトをまとめれば欲しい結果になるんじゃないのか?
sed 's/文字列1//g;s/文字列2//g;s/文字列3//g' $i > /home/test/$i
>>615 まあ常套手段としては、読み込み元を〜.origとか付加してリネームしてから、
オリジナルのファイル名に書き出すな。
丁寧にやるなら、〜.newとかに書き出して、書き出し成功(-fなどで存在確認)
したら、オリジナルを〜.origにリネームするなり削除するなりしてから
〜.newを元のファイル名に戻すとか。
#!/bin/sh
fl=/home/test/*.sh
for i in $*
do
for j in $fl
do
sed -e "s/$i//g" $j > $j.new
if [ -f $j.new ]
then
#オリジナルを残す場合
mv $j $j.orig
# オリジナルを削除する場合
# rm $j
mv $j.new $j
fi
done
done
で、sh hoge 文字列1 文字列2 文字列3・・・ とか。
あとは/tmpとかに書き出して上書きして戻すとか。
最近思い付いた技だがどうよ
shar * | sed '/^X/s/hoge/moge/g/' | sh
>>611 できたよ。m=1,o=0はとりあえず決め打ちで $(( )) だと30秒、exprだと4分かかるのが。
shar って初めて知ったよ。なかなか面白いね。
/bin/shellのソースってどこらへんから落とせばよいでしょうか。
プロセス制御まわりを読みたいだけなのでbashとかじゃなくて
簡単・短いやつを探しています。
どっかでcvswebとかで公開してないでしょうか。
>
>>624 半分寝ながら書いてたのでボケてました。
アリガトです。
626 :
名無しさん@お腹いっぱい。:05/03/12 13:20:16
>>623 の言う「プロセス制御」が、ジョブコントロールのことなら、
元祖Bourne Shellにはジョブコントロールは無い。
ashにはジョブコントロールがあるので、手頃に小さいソースなら、
ashが適してるかな。
>>628 ジョブコントロール元祖の csh の方が(ry
script コマンドをスクリプト内で使って
そのまま処理するのって無理?
script
script コマンドをスクリプト内で使って
そのまま処理するのって無理?
#!/bin/sh
script
#保存中
echo 処理結果
#保存抜ける
XXX
630-632 連投ゴメン
こんな処理は可能ですか?
XXXは scriptコマンド終わらせる何かを…
find の -exec に関数を使いたいんですけど,実行すると
find: ff: No such file or directory
というエラーになります。できればスクリプトファイルを
分けずに処理したいのですが,良い方法があったら教えて
くださいませ。
#!/usr/bin/bash
#GNU bash, version 2.05b.0(1)-release (i686-pc-cygwin)
function ff ()
{
echo $1
}
export -f ff
find . -true -exec ff {} \;
上記は記述例です。echo したい訳ではないです。
>>633 本質的に-execにシェルの関数は使えません。
findからさらに子プロセスを起こすわけだから。
find -printした結果のパス群をwhile readで受け、そのループ内で
関数を呼び出すというのは解法の一つかと思います。
-exec 内で function 定義するという愚直な方法もあるね。
list=`find . -true`
for i in $list
do
ff $i
done
とか
>>637は間違い。正しくは
SHELL=hoge script
識者のみなさん質問させてください。
csh でワイルドカードを認識して処理させるにはどうしたら良いでしょうか?
たとえば
> ls
AAA/ AA7/ AAA/ AAC/
AB9/ BGS/ BBF/ DDD/
DEF/ EEE/ EEG/ GGG/
というフォルダがあったとします。
ここでhogehoge というスクリプトを作って
hogehoge A* で
AAA/ AA7/ AAA/ AAC/ AB9/
hogehoge A?A で
AAA/ AAA/ AAC/
の配下に存在するファイルを編集するといった事が目的です。
------hogehoge.csh
#!/bin/csh -f
set folder = "`ls $1`"
echo $folder
-------
> hogehobe.csh A?A
> AAA/ AAA/ AAC/
となってくれれば良いのですが、
no match
となってしまいます。お知恵をお貸しくださいませm(*-*)m
すいなせん。思いっきりまちがえました
> ls
AAA/ AA7/ AA9/ AC9/
AB9/ BGS/ BBF/ DDD/
DEF/ EEE/ EEG/ GGG/
てフォルダがあって
> hogehobe.csh A?9
> AA9/ AC9/ AB9/
といったことがやりたいです。説明下手ですいません。
フォルダか…
おれおれ。
>>643 ん?直訳するとC-SHELLでは不可能ということなのですか?
すいません知識不足なもので。
>>640 >>645 #!/bin/csh
echo $#
ってスクリプトを実行してみるといいと思う。
#!/bin/csh
echo $#argv
>>643-648 みなさん短時間に沢山のレスありがとうございます!
#!/bin/csh
echo $#argv
hogehoge.c A?9
とやってみたら
> 3
だと!そして
#!/bin/csh
echo $#argv
echo $argv[1]
echo $argv[2]
echo $argv[3]
echo $1
echo $2
echo $3
だと
hogehoge.c A?9
> 3
> AA9
> AB9
> AC9
> AA9
> AB9
> AC9
!!おお!!勝手にむちゃくちゃ感動してますw
ありがとうごさいました!m(*-*)m
特定の文字列がある行から文字列までを表示するいい方法はありませんでしょうか?
例えばfoo、barの間
foo
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
bar
というファイルの aaaaaaaaaa を表示したいのです。
sgrep
awk '/foo/{p=1;next} /bar/{p=0} /.*/{if(p==1){print $0}}' file
とか。
この場合再びfooが現れたらまた表示し始めるが、一回で終わらせたければ
awk '/foo/{p=1;next} /bar/{exit} /.*/{if(p==1){print $0}}' file
fooの行を表示に含めたい場合はnextを外す。
barの行を表示に含めたい場合は/bar/のルールを一番後ろに持ってくる。
sgrepがあればいいんだけど、漏れは次のようなスクリプトを $HOME/bin に投げ込んでいる。
#例外処理と拡張機能は省略
start=$1
end=$2
read_flag=0
while read line; do
if [ "$read_flag" = 1 -a "$end" = "$line" ]; then
read_flag=0
break
fi
if [ "$read_flag" = 1 ]; then
echo $line
fi
if [ "$start" = "$line" ]; then
read_flag=1
fi
done
sed '/^foo$/,/^bar$/p;d' <file> | sed '/^foo$/d' | sed '/^bar$/d'
あ、表示したい文字列の中に開始文字列が含まれてたらダメだな。
シェルスクリプト修行中の身なのですが、
時々、${1+"$@"} というのを見掛けますが、これって何でしょうか?
何故単に "$@" と書かずにこう書くのでしょう?
そもそも { } の中の「1+」って?そんな書き方があるのでしょうか?
(エラーにならないということはあるのでしょうが…)
Google先生は記号の検索はできないみたいで困ってます。
ヒントを頂けないでしょうか?
常識も無いのかよ、クズが
>>656 ${parameter:+word} で parameter が 1,2,... の時の省略形
あとは man sh すれば書いてあるはず.
>>657 すみません。もっと勉強します
>>658 > parameter が 1,2,... の時の省略形
ありがとうございます。すっきりしました。
聞いてみてよかったです
連番ファイル (A.000 A.001 A.002〜A.023) を結合して A.DAT にしたいんですが
foreachなりforって必ずファイル名の若い順に処理されると決まってるんでしょうか?
それともファイル名のソートは自分でちゃんと行わないとダメですか?
foreachで (a*.dat) で引っかかるファイルをcatで結合させるスクリプトを
cat $(ls -1 A.0??|sort) > A.DAT
ありがとう。参考にさせていただきます。 sgrepなんて初めて聞きました
>>650 別解として
printf '/foo/+;/bar/-p' | ex -sR file
あ、ごめん。最後に\nがいるわ。
乱数を発生させる方法ってある?
いい加減なのでいい。
zsh 不可。
666 :
665:2005/03/21(月) 10:41:29
www.faqs.org/faqs/unix-faq/
で
echo $RANDOM
を見つけたけど、range を指定できると嬉しいんだけどなぁ…
>>665 /dev/urandomを使う。ddで読んでmd5にでも渡す。
なんで/dev/にあるんだろう
理解不能
/dev/random は環境ノイズのみで
/dev/urandom は数学的に計算した乱数も返すことがある
だっけ?
>>669 他に適任な場所がなかった
ぶっちゃけ何処でも良かった
今は反省している
672 :
名無しさん@お腹いっぱい。:2005/03/21(月) 19:36:26
>>656 ${1+"$@"}と書く必要はない。
"$@"でじゅうぶん。
${1+"$@"}の意図は、パラメータの個数がゼロの場合に、
空文字列にすら展開させないようにするためと思われるが、
"$@"と書いても、空文字列には展開されず、
何もなかったものと同じになる。
${1+"$@"}と書くのは恐らく、超古いシェルのバグかその辺に対応するためと思われる。
"$@"
でよろし。
673 :
656:2005/03/21(月) 21:24:06
ところで、${1+"$@"}と書かなければならない(引数なしの時、空文字列が残る)
シェルのバージョンってどの辺?
でも csh で動かされると、${1 + "$@"} って動かねぇよな。
>>669 (仮想的に) デバイスだから。
汎用機なら仮想じゃないやつもある。
PC 用の USB な乱数発生器もあるよ。
真にランダムとはなんですか?
例えば、ps aux | cut -d ' ' -f1 とかした後、
root プロセスが何個とか、統計を取りたい場合、いい方法って無いですか?
man uniq
682 :
680:2005/03/23(水) 07:59:56
683 :
http://www.geocities.com/tokyufubai/:2005/03/23(水) 11:31:17
ページングとは、主記憶の容量より大きいプログラムを実行する場合に
用いられる処理方式です。
ページング方式では、プログラムをページ(page) という固定長の単位に
分解して、ハードディスク(補助記憶装置)に置いておきます。
サブシェル内で変数フラグを立てて、while文が終了したあとに
そのフラグの値を参照したい場合はどうすればスマートでしょうか?
例えば、while文中で
flag=0
echo "hogefuga" | while read line; do flag=1; done
としたとき、サブシェルが終了したあとに、
$flagが1になっていることを確認したいのです。
サブシェルの変数を参照したいというのは喉の奥に手を突っ込みたいというような
無理な話。
サブシェルの戻り値をみるか、サブシェルの最後で文字列を出力させて
それをみる。
686 :
名無しさん@お腹いっぱい。:2005/03/23(水) 18:10:33
シェルじゃなくてsedの質問。連続する2つの行が同じ場合それらを削除する
にはどうしたらいいですか?例えば
1
2
2
3
という入力の場合
1
3
と出力させたい。
sed -E 's/^(.+)$\n\1//'
としたら全然だめでした。改行文字はどうやればいいんですかい?
uniq -c して、^ *1 でなければ消す、だとどーよ?
こういう質問って uniq とか他のコマンドを使わないで
sed だけでやる方法が知りたいのか
たまたま sed でやろうとしているだけで目的が達成できれば
どんな方法でもいいのかはっきり言うべきだと思う
689 :
686:2005/03/23(水) 18:35:06
> ^ *1 でなければ消す
あほなんでこの部分が理解できませんが,man uniq で調べてみます。
後学のために聞きたいんですが,sed や grep で改行文字を扱うのは
無理?複数行の正規表現はperlかawkじゃないとできないんですか?
690 :
686:2005/03/23(水) 18:36:17
>> 688
できればsedだけでやりたいです。
「なぜ」sedだけでやりたいのかを言わないと。
sed だけでやりたい理由。
今までこのような処理はperlかあるいはemacsに読み込んでやっていた。
今たまたまperlもemacsも入ってないマシンを使っている。awkは詳しく
ない。sedでやろうと思ったがうまくできないので質問しました。
ちなみにいちばん聞きたいことは,正規表現の中に改行文字を入れるには
どうしたらいいのか,あるいは不可能なのか,ということです。複数行
にまたがる正規表現はsedで可能なのかということです。だから上に書いた
入力を処理したいということではありません。上の例は問題を単純化して
分かりやすいように例を出しただけです。
>>692 > 正規表現の中に改行文字
\n
> 複数行にまたがる正規表現はsedで可能
可能
これだけの質問に
>>686は複雑過ぎ
あ,普通に \n でいいんですか?さっき \n でやって
うまくいかなかったので質問してしまいました。俺の勘違いか。
スレ汚し失礼。
>>694 s しか知らない奴は \n を使えない
sedによっては\nは解釈できないかも。
その場合、逆に改行文字をそのまま入れればよい。
s/xxx/
/
みたいな感じ。
昔はこの方が普通だった。
ま、改行を含めた正規表現を扱うには、あらかじめ、
N コマンドで次の行を読み込むとか、
パターンスペースの概念が要るわけだな。
それより、sed/awkとかは別スレにしないか?
シェルスクリプト自体の話から外れてくるから。
uniq なら uniq -u (3行以上連続してても消していいんだよね?)
sed なら...難しいけど、現実逃避で考えてみる。
> それより、sed/awkとかは別スレにしないか?
> シェルスクリプト自体の話から外れてくるから。
別にここでいいと思う
>>675 cshじゃ、${1+"$@"}以前に、"$@"自体が使えねぇだろ。
csh厨うぜぇ。
>>686 作ってみた
#n
H
g
s/\n//g
1!{
/\(.\)\1/!{
s/\(.\)./\1/p
g
s/\n//g
s/.\(.\)/\1/
h
}
/^\(.\)\1*$/!{
s/.*\(.\)$/\1/
h
}
}
${
/^.$/p
}
703 :
名無しさん@お腹いっぱい。:2005/03/23(水) 23:06:43
bsh糞
>>702 短くしてみた
#n
H
1!{
x
s/\n//g
/\(.\)\1/!{
s/\(.\)./\1/p
ba
}
/^\(.\)\1\{1,\}$/{
h
}
}
:a
${
/^.$/p
}
707 :
706:2005/03/24(木) 00:35:46
ミスってた
#n
H
x
s/\n//g
/\(.\)\1/!{
s/\(.\)./\1/p
ba
}
/^\(.\)\1\{1,\}$/{
h
}
:a
${
g
/^.$/p
}
709 :
名無しさん@お腹いっぱい。:2005/03/24(木) 23:21:09
ファイルからスペース区切りの行を1行ずつ読み込み、変数に格納し、
ファイルエンドまで繰り返すという処理をさせたいのですが、
どう記述すればいいですか?
Cシェルで教えてくれたら嬉しいのですが、それ以外でも構いません。
>>709です
言葉足りないかもしれないので、イメージで補足します。
【入力ファイル(スペース区切り)】
SUN 5
HP 10
IBM 9
【処理イメージ】
ループ
ファイルより1行読み込んで変数Aと変数Bに格納
ECHO 変数A 変数B
エンド
【画面出力】
SUN 5
HP 10
IBM 9
ちょー基本だから、その辺のスクリプト解説本には大抵載っているはずだ。
例題がくだらなさ過ぎ
cat しろって言いたくなったが我慢した
すいません(>_<)
Cシェルに関する良いサイトがあったら教えて下さい。
ぐぐってもなかなか見つからなかったもので。。
>>715 ファイルの中身を表示するのが聞きたいわけではないんです。
すいません。
CシェルはC言語ライクを謳っているのに何故readがないんすか?
>719
Cにもreadはない。
>>709です
これでいいのかな?
foreach $* (INPUTFILE)
ECHO $1 $2
end
Cにread関数はあるけどソケットからの一行読み込みでファイルリードではないけどね。
>>722 Unix 系 OS では read はシステムコール.
ファイルからでもソケットからでもデバイスからでも
読める.
確に「一行読み込み」ではないけどね.
>>709 #! /bin/bash
for i in $(seq 1 $(cat file | wc -l)); do
set $(cat file | head -n $i | tail -n 1)
echo $1 $2
done
使用言語の仕様を満たしていませんが。
標準入力から読み込まれたファイルを、行をランダムにシャッフルして、
標準出力に出すコマンドはありますか?
a
b
c
↓
c
a
b
727 :
726:2005/03/26(土) 21:32:53
とりあえず、
cat file | while read line; do echo $RANDOM $line; done | sort -n | cut -f 2- -d " "
というのを考えたのですけれども、これだと先頭のスペースが消えてしまう(行頭に
複数のスペースが入っていても無視されてしまう)ので、困ってしまいました。
728 :
726:2005/03/26(土) 21:36:52
すいません。
cat file | while read line; do echo "$RANDOM $line"; done | sort -n | cut -f 2- -d " "
でした。
729 :
名無しさん@お腹いっぱい。:2005/03/26(土) 21:55:55
OSを書かんとあるかどうかは分からんわな。
うわageてしまった
>>728 入力がテキストファイルなら、
cat file | while read line; do echo "$RANDOM^A$line"; done | sort -n | cut -f 2- -d "^A"
とかにしとけばいいじゃん。(^AはCTRL-A)
しかし、$RANDOMって一般的じゃないような気がするぞ。
732 :
726:2005/03/26(土) 22:36:23
>>731 アドバイスありがとうございます。while read で読み込むと、変数lineがマッチするのは
各行の空白文字列(スペースやタブなど)以外の文字以降になるようです。
各行の先頭に空白文字列がある場合(そしてその空白を維持する必要がある場合)は、
どうしたらよいのでしょう?
a
b
c
↓
c
a
b
>>732 echo $line と echo "$line" は同じじゃないぞ。
734 :
726:2005/03/26(土) 22:45:19
>>733 test.txtに
a
b
c
と記述したとき、
cat test.txt | while read line; do echo $line; done
と
cat test.txt | while read line; do echo "$line"; done
は同じ結果になりませんか?
735 :
731:2005/03/26(土) 22:52:39
>>734 んじゃ、その行頭にIFS=''つけてみて。
このスレは awk はいかんのかいのう
awk 'BEGIN{srand()}{print rand()" "$0}' file | sort -n | sed 's/[^ ]* \(.*\)/\1/'
737 :
726:2005/03/26(土) 23:09:48
>>735 できましたっ!!
IFSを''にするという発想がありませんでした。
感謝しきりです。
>>736 ありがとうございます。
awkは自分にはまだ暗号なものでして。。。
本を読んで出直してきます。
738 :
726:2005/03/26(土) 23:18:20
報告を兼ねて。結果的にこうなりました。
cat file | while IFS='' read line; do echo "$RANDOM $line"; done | sort -n | cut -f 2- -d " "
でも、$RANDOMが使えるのは、bashかtcshのようですが。。。
$ cat File
# comment
A:1:0
B:2:10
C:1:5
# comment
というようなファイルがあったとき、各列を代入するのにうまいやり方ないでしょうか?
for i in `grep "^[^#]" File`;do
X=`echo $i | awk -F: '{print $1}'`
Y=`echo $i | awk -F: '{print $2}'`
Z=`echo $i | awk -F: '{print $3}'`
done
このやり方だと、列が増えたときに面倒になるので。
変数名にカウンタを使うという方法もあるけど、変数名は別にリストを作っておくなどして、
わかりやすいものにしたい。
>>740 すなおに他の言語で書いたほうがよさげ。
何に使うのか気になる
>>740 こんなんどう?
自分も勉強中なんでもっとかっこいい方法があるなら知りたい。
VARS="X Y Z"
setup_vars() {
for i in $VARS
do
eval $i=$1
shift
done
}
sed '/^[ ]*#/d;s/:/ /g' File | while read line
do
setup_vars $line
done
>>740 これできるのbashだけかな?
#!/bin/sh
declare -a XXX
for i in `grep '^[^#]' testfile`; do
IFS=':' XXX=($i)
echo ${XXX[0]}
echo ${XXX[1]}
echo ${XXX[2]}
done
grep -v "^#" File | tr ":" " " | while read x y z; do echo $x; echo $y; echo $z; done
746 :
名無しさん@お腹いっぱい。:2005/03/29(火) 17:48:06
directory ディレクトリィより下層にある
すべてのライブラリに対して symbol シンボルを
nm で検索する方法はありますか?
きっとあります
748 :
>>746:2005/03/29(火) 18:02:15
てーかエレガントな方法はありますか?
749 :
726:2005/03/29(火) 18:03:07
rpmを使う。
750 :
726:2005/03/29(火) 18:04:23
find directory -type f | while read file; do
echo $file
nm $file | grep symbol
done
とか言うこと?
751 :
名無しさん@お腹いっぱい。:2005/03/29(火) 18:14:47
>>750 そうそう
それです
シェルスクリプトは魔法のようですね
高度に発達したシェルスクリプトは魔法と区別がつかない
753 :
名無しさん@お腹いっぱい。:2005/03/29(火) 20:52:06
awkはダメせいぜいsedまでで
>>751 それはシェルスクリプトではありません。
755 :
名無しさん@お腹いっぱい。:2005/03/29(火) 21:13:05
nm directory/**/*.a
とか?
directory/**/*.a(.)
のほうがいいよ
zsh 厨ウザイ。
>>756 >>1 □みんなのお約束:
・特記なき場合はbourne shがデフォルトです。
bash/csh/zsh/kshなどに依存する場合は明示しましょう。
759 :
名無しさん@お腹いっぱい。:2005/03/30(水) 23:22:18
てゆーかみんななんでzsh使わないの?
zsh厨=LD堀江
761 :
名無しさん@お腹いっぱい。:2005/03/30(水) 23:41:16
性能的には
zsh>bash>tcsh>csh>sh
かな?kshとかashとか知らない
ぜっとしぇる
ぜっしゅ って言ってる人もいるけど
絶対にぜっとしぇるって言う
zsh ぜっとしぇる
bash ばっしゅ
tcsh てぃーしーしぇる
csh しーしぇる
ksh けーしぇる
ash あっしゅ
sh えすえいち
がーん。ティッシュちゃうんや。
>>759 私が使い始めた環境では、デフォルトが bash でした。
とくに考えること無く使ってきて、だいぶ慣れたし、特別困るようなこともない。
他のシェルを使おうと思うようなきっかけがなかったし、
変えなきゃいけないって状況にもなったことがないから、
bash を使ってます。
なんで zsh 使いはじめたのですか?
zsh 関係でテンプレにいれるようなページがあったら、
次スレたてるころに紹介してください。
好きなの使えばいいと思うよ。だけど
ろくに使ったことないのに他のシェルをおとしめちゃ駄目だよ。
>>766 > zsh 関係でテンプレにいれるようなページがあったら、
> 次スレたてるころに紹介してください。
別にいらんだろ。シェルの使い方のスレじゃねーんだから。
> sh 関係でテンプレにいれるようなページがあったら、
> 次スレたてるころに紹介してください。
だと問題なさそう
それとも
>>768はシェルといえばzsh?
花と言えば桜みたいな
春は曙みたいな
それはそれでいいけど
shの使い方はあっても良いと思う?
入門Kornシェルが紹介されてるならzshもOK?
けど csh & tcsh が無いのは何故?
for i in ` seq 1 40 ` ; do echo $i ; done
だと桁が揃いません。
出力を、01 02 03 04 05 06 07 08 09 10 ... にする方法はありますか?
ループの中でcaseで処理を分ければできますが、もっと簡単な方法で。
>>771 for i in `seq 1 40`; do j=`printf "%02d" $i`; echo $j; done
とかじゃだめ?
>>771 seq を使っていいのなら、
for i in `seq -f %02g 1 40`; do echo $i; done
で一発だよ。
ただ、seq はLinux以外では標準じゃないので、
いつも使えるとは限らないのが難点。
774 :
名無しさん@お腹いっぱい。:2005/03/31(木) 07:26:23
>>771 zsh を使っていいのなら、
echo {01..40}
で一発だよ。
ただ、zsh は標準じゃないので、
いつも使えるとは限らないのが難点。
775 :
名無しさん@お腹いっぱい。:2005/03/31(木) 07:41:39
zsh始めたのは長老が使っていたからかな
seq -w
とすれば勝手に桁が揃うよ。
>>772-774 ありがとうございました。
j=`printf "%02d" $i`
こんな使い方ができるなんてWinと違って奥が深いですね。
>>773-774 こちらの環境では動作しました。
echo {01..40} は
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
と出力されました。
778 :
名無しさん@お腹いっぱい。:2005/03/31(木) 10:16:15
( ´,_ゝ`)プッ
>こんな使い方ができるなんてWinと違って奥が深いですね。
バッククォートは知ってたようだが…今さらどこが深かったんだろう。
感心する前に基本からやれって。
>>779 バッククォートはどっかのサイトで見つけてコピペで使ってただけです。
>>777 WindowsのForとSetのヘルプも見てみな(自分も覚えてないけど)
|for /F "usebackq delims==" %i IN (`set`) DO @echo %i
|この例は、現在の環境の環境変数名を列挙します。
まあ、このVMS式のオプション指定方法とUNIXから持ってきた構文の
混ざり具合が気持ち悪いのは確かだが。
ほんとモイキーな書式だ
>>770 s/pc5/pc8/
次スレ立てるときはテンプレ修正忘れないようにしないと。
こういうときって過去スレのURLも一括して変えるものなのかな? そのままですか?
>>765 オナニーばっかしてる君にはその読み方がぴったりだね!!
と無意味に煽ってみる。
いや、悪意はないんだがなんとなく煽ってみたかったんだ。
2ch初煽り記念あげ
785 :
名無しさん@お腹いっぱい。:2005/03/31(木) 20:29:21
ちくしゅ
シェルスクリプトを使って、文字列を標準出力に出しているとき、
スクリプトの途中でEOFをおくることはできますか?具体的には
1. echo hoge
2. sleep 5
3. echo fuga > foo
というスクリプトにて、echo hogeを実行した直後に標準出力は
閉じて(←この表現が適切かどうか不安ですが、プログラムが
自動的にバックグラウンドに回る、という感じのことを言いたい
のです)、sleep 5から先は標準出力に出すような作業は一切ない
ので、自動的に残りの処理がバックグラウンドに回るように
したいのです。
1. echo hoge
2. sleep 5 && echo fuga > foo &
とすれば、一応は解決しますが、&& でつなぐ処理は、途中で
終了コード0以外になるプログラムがあるとそこから先が実行
されません。なので、
1. echo hoge
2. (標準出力を閉じる何かの動作)
3. sleep 5
4. echo fuga > foo
という形で書ける書式があれば教えてください。
春だな
> 標準出力を閉じる何かの動作
exec >&-
>>786 標準出力のことは、質問に無関係なようにに読めます。
sleep 5
echo fuga > foo
と書いたらこれらが自動的にバックグラウンドに回って欲しい
ということじゃないんですか?()を使ってGroupingでOK、かな。
here documentで並べたコマンド列をshにパイプで渡しても
いいんだろうけど。
いずれにせよ、これと標準出力との関係がよくわからなかったヨ。
>>788で満たされるんじゃないかな。
バックグラウンドに回っても標準出力に出力あったら意味なさそう
>>784 偽者だな。本物のウサチャソはいつも煽ってるぞ。
792 :
790:2005/03/31(木) 21:22:40
と思ったけどやっぱりわかんないや。
閉じようが閉じまいが出力はないって言ったはるし。
標準出力が端末に出ちゃうってのを気にしてるんじゃないのか?
シェルスクリプト中からstat
を取るのになにかよい方法ってありますか?
単に「sleep 5」以降は(出力を確認する必要はないから?)
プロンプトが返ってきてほしい
ってだけなんじゃ…
>>786 ろくに読まないで答えるとnohupでいいんちゃうか
つーか全部そのままで
&で実行させたらいいんじゃないの?
>>792 echo foo
(
echo bar
echo baz
) > output-file &
って, ことか?
目的が不明だ
>>794 何が知りたいの?
とりあえずFreeBSDやNetBSDにはstat(1)があるけど、
汎用的にはperlなんかのonelinerにファイルを渡すのがいいんじゃないかな。
ここにおる奴には常識なんだろうが、
bshの場合、
while〜do〜done 文と while read LINE;do〜;done < FILE 文
とでは、whileループの外の変数の見え方が変わるんだね。
いや〜今まで全く気がつかなかった。
客に嘘教えてもうた(藁
$ cat test1
#!/bin/sh
CNT=0
while read LINE
do
CNT=`expr $CNT + 1`
echo "$n: $LINE"
done < FILE
echo $CNT
$ ./test1
0
$ cat test2
#!/bin/ksh (bash、zshでも)
CNT=0
while read LINE
do
CNT=`expr $CNT + 1`
echo "$CNT: $LINE"
done < FILE
echo $CNT
$ ./test2
5 ・・・FILEの行数
余分な行が入ったので、訂正
$ cat test1
#!/bin/sh
CNT=0
while read LINE
do
CNT=`expr $CNT + 1`
done < FILE
echo $CNT
$ ./test1
0
$ cat test2
#!/bin/ksh
CNT=0
while read LINE
do
CNT=`expr $CNT + 1`
done < FILE
echo $CNT
$ ./test2
5 ・・・FILEの行数(bash、zshでも同じ結果)
えー?サブシェルになるの?そうじゃなけりゃローカルな変数なんて変ジャン
なんだよ、その日付(w
どうせ今日だけじゃないか?
>>804 FreeBSDのashだとちゃんと行数カウントしてくれるけど、そいつはどこのsh?
solaris2.6と9で確認。
いろいろ調べた結果、bshの大昔からのバグだったものが、
長い間使われてきているので、現在では仕様として扱われているらしい。
ただ url を抜き出すだけなら
http:// にマッチさせれば良さそうだけど
リンクを抜き出したいとかだと
相対url も絶対url で出力したいだろうし
wget とか w3m で何かあるのかな?
lynx -dump hoge.html
で、下の方に References でリンクURL一覧が出るので、
これを利用すればいい。
lynx -dumpは相対リンクがイヤンなことになるので
やっぱりそれなりのスクリプト言語のライブラリを使うのが早くて確実。
>>813 lynx -dump で、相対パスはちゃんと絶対パスに直してくれるけど、
それでは不満なのか?
あと、lynx -image_links -dump にすると、
<img src="..."> とかのタグ内の画像リンクとかもすべて
リストしてくれるから便利だけど。
>>814 >>809 は
> htmlファイルから
って書いてるから、たぶん、HD に保存してあるファイルが対象なんじゃないかな?
それだと、相対リンクだと、
http://foo/ が file://localhost/ になっちゃうから、
書き換える必要がでてくる。
>>813 はそのことを言ってるのだと思う。
特殊な例:
$ cat test.html
<a href="../index.html">foo</a>
<a href="/index.html">bar</a>
$ lynx -dump -force_html /dev/stdin < test.html | grep file
1. file://localhost/index.html
2. file://localhost/index.html
すんまそん。別スクリプトを読み込むのてどうやるんですか?
よくわからないので、必ず ; をつけるようにしたやつを
eval `cat /${HOME}/.hoge`
って読みこませとるのですが、なんかエレガントなかんじがしません。
”. ${HOME}/.hoge”・・・サブシェルとして実行
”exec ${HOME}/.hoge”・・・現シェルの一部として実行
>>818 違う
"${HOME}/.hoge"・・・サブシェルで実行
”. ${HOME}/.hoge”・・・現シェルとして実行
”exec ${HOME}/.hoge”・・・現シェルの引継ぎとして実行
エレガントとかほざく前にman読め
lynx -image_links -dump
809ではないが便利だ。サンクス
823 :
名無しさん@お腹いっぱい。:UNIX時間(+0900)35年,2005/04/02(土) 16:37:20
sourceは?
クローラの動きを把握するためにgoogleでの検索結果を保存したいのですが
どのように書けばいいのかご教授願います。
例えばsite:www.2ch.netで検索した結果を取得するには、どのように書けばいいですか?
wget とか?
シェルの変数の命名慣習について聞きたいんですが、
大文字にするのは環境変数で、
スクリプト内や関数内での変数は小文字、
という使い方が普通ですか?
そんな感じ。
どうもです。
rc の設定に引きずられて、
実はつい最近まで何も考えずに
スクリプトの変数にまで大文字使ってました。
834 :
名無しさん@お腹いっぱい。:2005/04/06(水) 00:39:29
シェルを実行しようとしたところ、下記のエラーが出て実行できません。
「The fork function failed. Too many processes already exist.」
最初は同じシェルを実行できたのですが。。
何度か応答が帰ってこないので、×でセッションを落としましたがそれが原因でしょうか?
どなたか解決作のわかる方教えて下さい。
テキストデータの整形で困っています。
0404 AAA 111
0404 BBB 222
0404 CCC 333
0405 DDD 111
0405 EEE 777
0405 FFF 222
↑これらを
0404 AAA 111 BBB 222 CCC 333
0405 DDD 111 EEE 777 FFF 222
↑このように整形したいのですが、うまくいきません。
もしよかったら、どなたかご教授お願いします。
毎年恒例の宿題か
840 :
836:2005/04/06(水) 10:38:28
一番左の日付をキーとして、AAAはいくつ、BBBはいくつ、という感じで1レコードにしたいのです。
恥ずかしながら、やり方が見当もつかない状態でして。。。すみません。
ルールがわからないというのは、同じキーは必ず連続するのかそうでないのか
とか、同じキーは三つなのかどうかとか、典型的な状況説明だけでありうるす
べての状況を説明していないということ。
ともかく、シェルでなんとかするというより、awk なり perl なり使っとけと。
>>836 #!/usr/bin/awk -f
{
if (r[$1]=="")
r[$1] = $0;
else
r[$1] = r[$1]" "$2" "$3;
}
END{
for ( i in r )
print r[i];
}
# あとで sort しないとだめかも
844 :
836:2005/04/06(水) 12:40:02
>>842、皆さん
ありがとうございました!何とかなりそうです。
ディレクトリ内のファイル(ログ)が現在から一ヶ月以上
アクセスしていないファイルを削除するようなシェルを
作成しようと考えてます。
簡単にできますか?
>>845 シェルごと自作するのは難しいが
シェルスクリプトならそれほど難しくない。
logrotate 使えば?
find 使うのが定石?
私は zsh だけど
>>847 logrotateを考えたのですがアプリが勝手に毎日、日付をつけてログを
残してしまいます。
>>846 難しくないシェルスクリプトでお願いします。
>>848 findでやってみます。
find log_dir/ -atime +30 -a -type f -exec rm {} \;
find $DIR -mtime +30 | xargs rm で出来ました。
>>849 > 難しくないシェルスクリプトでお願いします。
シェルとシェルスクリプトの区別はついているか
DDD 7
AAA 1
AA 10
DD 35
DDDD 34
AAA 11
AAAA 7
DDD 4
という内容のファイルがあって
AAA 1
AAAA 7
AA 10
AAA 11
DDD 4
DDD 7
DDDD 34
DD 35
とソートしたいです。どうすればよいでしょうか?
要は$2でlsのようなソートをしたいです
手で並び替える
>>854 いやいや、確かに現状はそうなんだけどね。
そこをなんとかw
>>853 一文字目だけで sort する -> 文字を選ぶ
選んだ文字で grep する -> 数字で sort する
for CHAR in `cut -b 1 file | sort -u` ; do grep "$CHAR" file | sort -n -k 2 ; done
おれなら perl でやっちゃうな。
sort でやるとしたら何段階か処理しないといけなさそう。
>>856 そう、これです!ありがとうございます。
$1は問題ないのですが$2がどうしても
1
10
11
7
とソートされて困ってました ← 手作業の手間が
今後、私の中で
>>856 ”神”となりましたw
>>857 perlとか Cで作るならできるんですよ。
ただ、客先とか自分で作業する環境が限られているところで
どんなWSでも実行できるsort でやりたかったんです
客先…
これ、第一フィールドの整列の方が実はキモだろ。
数字順はsortのオプションで何とかなるとすぐわかる。
担当される客が可哀想になる
aaa 1
aab 11
aba 3
abb 2
baa 3
bab 1
こんなのだとどうする?
>>853 cat file | sort -k 1.1,1.1 -k 2,2n
>>864 おいらも便乗させてください
C<4>
BB4BBB<5>
AAA<14>
AAA<1>
DDD
BB4BBB<52>
EE<3>
C<41>
EE<30>
↓
AAA<1>
AAA<14>
BB4BBB<5>
BB4BBB<52>
C<4>
C<41>
DDD
EE<3>
EE<30>
できればsortだけでなんとか出来ればベストなんですけどね。
こういうこと?
sort -t '<' -k 1,1 -k 2,2n
867 :
865:2005/04/08(金) 20:04:38
>>866 サンクスですこれでばっちりです。
ちなみに < > が無くても簡単にできるものでしょうか?
仕切りさえあればいい、んじゃないか?
log 05.4.8
log 05.4.9
log 05.4.10
という感じの間に空白のあるファイルがあります。
これを古いのから順にcatでつなげたいのですが、どうすればいいでしょうか?
>>869 cat `ls | sort -n -k 2`
みたいなかんじでがんばって
cat `ls -tr`でやってたんですが、空白があってだめなんですよ。
がんばって
#!/bin/sh
IFS='
'
for f in `ls -tr`; do cat $f; done
>>873 おー、IFSなんていう環境変数があったんですね。これで何とかなりそうです。
変数ではあるが環境変数ではない。
空白が1個だけと確定してるなら
ls -tr | xargs -n2 cat
そうでないなら
ls -tr | sed 's/^/cat /' | sh
こうじゃないとダメかorz
ls -tr | sed 's/.*/cat "&"/' | sh
ls -tr|tr '\n' '\0'|xargs -0 cat
シェルスプリプト相談室 スレより誘導されて着ました。
ファイルを読み込んで、各行の先頭文字を判定し、コメント文でなければ表示
をするというものを作っています。現在、以下のようにして判定しているので
すが、これでは、「空行があるとファイルはそこで終わり」だと判断されてし
まい、最後までいってくれません。全行を見るためには、どう書けば良いので
しょうか?bsh使いです。
while read KEY
do
#判定
done < test.dat
お願いします。
>>878 スクリプトにしなくても grep でいいじゃん。
880 :
878:2005/04/11(月) 19:08:06
>>879 それを言われると辛いのですが…。
シェルスクリプトを勉強を始めたばかりで、力をつけるためにやっているものです。
1行1行判定させて、その都度出力するというものは出来ないのでしょうか?
誘導元の美味しんぼワロタ
882 :
名無しさん@お腹いっぱい。:2005/04/11(月) 19:21:43
>>878 判定の書き方が間違っているんじゃないの?
変数をクォートしていないため、そこでtest文がエラー起こしていたり。
884 :
632:2005/04/11(月) 21:19:55
>>639 亀レスで失礼します。
hogeは/bin/sh とかですか?
>>880 > 1行1行判定させて、
こんなこと実際のシェルスクリプトでもしないと思うなあ。
練習にしても練習内容の方向が間違ってる希ガス。
awkとか使っちゃダメなんだろうなぁ
IFSと言ってみる
>>878 やってみたけど、空行あっても終わんないよ。
readは空行でもtrue返すので当たり前な気がする。
(GNU bash, version 3.00.14(1)-releaseだけど、こんな基本的な
挙動はshによって変わったりするようなもんじゃないと思う)
890 :
878:2005/04/12(火) 08:18:34
>>883,
>>885,
>>886,
>>889氏、レスありがとうございます。
中身を替えずに再実行したところ、
>>878氏の言う通り、空行があっても終わりませんでした。
でも、確かにあのときは空行で終わってしまったのですが…。
お騒がせしました。
Bourneシェルです。
特定文字列をファイル名に含むファイルの中身を、連続表示するものを作りたいです。
拡張子がtxtのもののみの中身を見たいのですが、どう記述すれば良いのでしょうか?
ファイル名昇順の順番で読むことにしています。
ls *.txt | sort
とすれば、ファイル名昇順で表示はされるのですが、この順にファイルを読むには…。
おながいします。
>>892 for i in `ls *.txt | sort`
とかそういう話?
単に全部表示するだけなら cat `ls *.txt | sort`
普通globの展開は辞書順に並べられるので何も考えずに cat *.txt でも
いいように思うのだが。
あと、ファイルのリストをとるためにlsを安易に使う人がいるけど、
あまり望ましくはない。使うなら、せめて
名前に空白等が含まれる可能性やglobにディレクトリが引っ掛かる可能性を
考慮しような。
今時の ls は空白や改行が入ったファイル名でも問題無いよ。
ファイル名に / を入れたいです。
それがshell script とどういう関係が?
ちなみにKDEでfoo/barという名前のDirectoryをDesktop
に作成してlsしたらfoo%2fbarって名前になってた。
ファイル名に / があるとシェルスクリプトで動かないです。
シェルスクリプト以前にそんな文字入れるな。
エスケープすりゃええだけじゃないのか
903 :
名無しさん@お腹いっぱい。:2005/04/13(水) 16:06:39
シェルで、ファイルから1行づつ読み込んで、
それを区切りごとに分けてそれぞれを配列に代入する、
ということはできるのでしょうか?
Perlを使えればいいのですがそれができない状況でして困っています。
どなたか知恵をお貸しください。
Bシェルには配列がない
906 :
名無しさん@お腹いっぱい。:2005/04/13(水) 16:21:16
>>904 やりたいことというのは、
今手元に'ls -l'の出力を記録したファイルがあるのですが、
このファイルから1行づつ内容を読み出して、
タブで区切られたフィールドごとにその内容をそれぞれ別の変数に入れて、
(必ずしも配列である必要はありません
>>905さん)
その変数の内容に基づいて処理を行った後、
次の行を読み込んで同様に・・・
ということです。
perlだったら<>で読み込んでsplitすれば一発なのですが、
同様のことをシェルではどうやればいいのかわからなくて
質問に来ました。
>>902 ネタにマジレス+スレ違いだが、dd か何かで無理矢理ディレクトリ
エントリ中のファイル名に "/" を突っ込んだら、やっぱりうまく
動かなかったとかって、fj.unixか何かの話しであったよ。
あたりめえじゃん。
カーネル様が/のとこでぶったぎってから、ディレクトリ検索するんだから
DOSまたはWindowsを使う。
911 :
名無しさん@お腹いっぱい。:2005/04/13(水) 20:51:10
質問できそうなところがここしかないので質問させてください。
syslogを日時を指定して吐き出すようなシェルスクリプトはどのような記述ですか。
また、変数でエラーlogとそうでないlogを分けて吐き出したいです。
よろしくおねがいします。
>>910 DOSやWindowsでもファイル名に/は使えない。
DOSやWindowsでも、カーネルレベルでは
ディレクトリの区切り文字に/を使っている。
\を使うのは、おもにcommand.comが/をオプション記号として
使うために、\をディレクトリ区切り文字の代用として
使っているに過ぎず、実はディレクトリは/で区切られているのだ。
その証拠に、Shift-JISの漢字の2バイト目は、
決して/にならないようにコードがちゃんと避けられている。
一方、\の方は避けられておらず、Shift-JISの2バイト目が
\になる漢字があって、シェルスクリプトやC言語で時々問題になる。
なぜシェルスクリプトでそれをできると思ったのかが疑問だが、
自分ならめんどうなことを考えずに syslog-ng に乗り換える。
表\示
でもさ「05/4/13 21:58:24」とかいうファイル名を使いたいときってない?
「050413215824」でおk
05ディレクトリの下の4ディレクトリの下に、
'13 21:58:24'というファイルを作成すれば無問題。
ちゃんと「05/4/13 21:58:24」というパス名でアクセスできる。
スペースが含まれるので、ちゃんとクォートすること。
なぜ、その程度でperlが出てくる・・・。
perlが使えない環境って書いてあるやん。
なのでawk
>>907 がすでに答え書いてるじゃん。
read perm block user group size date filename
みたいに書けば、$perm とかで変数参照できる。
これをwhileループで回せば良い。
タブを区切り文字にするなら、
IFS=' ' ←この中はタブ
にすればいい。
ここってさシェルでひとまとめにしてるのが良くない
shでなら出来るけどcshなら出来ないんだよねとか。
shはcshより高機能?だと思うけど使いずらいからCライクなcshとか
俺はlinuxだからbashがいいとかなる。
でもsolariaとかだとシステム管理者を丸め込まないとtcsh止まり。
>>922 solaria なんて無名OSを使ってるのが悪い。solaris使え。
>>922 スクリプト書きに csh を使うのがそもそもの間違いなので
別に問題ない。
それに Solaris は、いまでは最初から bash も zsh も
tcsh もついてくるので、管理者をまるめこむまでもなく
最初から使えるだろ。