【sed】シェルスクリプト総合@LINUX Part2【awk】
1 :
ミスターバッシュ :
2006/08/03(木) 13:10:00 ID:5dVnjkpT
2 :
ミスターバッシュ :2006/08/03(木) 13:12:11 ID:5dVnjkpT
3 :
ミスターバッシュ :2006/08/03(木) 13:13:16 ID:5dVnjkpT
前スレで one two three の改行を「,」に置換してつなげたいと質問したものです。 結果として、sedではなく、pasteを使って解決致しました。 $ paste -s -d , file > newfile sedでやる方法については、結構むずかしそう(Nとか駆使)なので、 時間をかけて勉強していきたいと思います。アドバイスして下さった 方々、ありがとうございました。これからもよろしくお願い致します。
>4 からかって悪いけど、前スレで「tree 」を見たとき笑ってしもうた。
>>5 (*・∀・)あわてて、何事もなかったように直しましたとも。
>>7 ありがとうございます。今、テストしたら完璧でした!
原理はこれから学びます。胸のモヤモヤがとれました。
関係ない話だけど、 「原理」とか「摂理」とかいう比較的重い意味を持つ概念が 怖いものの代名詞というか、近づいてはならぬものに 使われる言葉となってしまったことは悲しいことだ。 なんかbashのスクリプト一発でドカンと世界中の破壊的カルトを消滅させられればいいのに・・・
>>9 つ find 世界中 -name カルト -exec rm {}\;
どんなに自分(達)だけは違うとか言い張っても スクリプト書いてる時点で所詮はハッカー夷的カルトだろ。 つか何で又とつぜん???
>11 んにゃ、単に「原理」→「統一協会(統一=原理)」→ 「破壊的カルト」と連想が行ったので、急に 「ビンラディンとか文鮮明とかおかしな連中を一斉に消せないかしら」 と思っただけで深い意味はないわ。 スレ汚し失礼。
rm -f /bin/ladin
$ gen-riken > /dev/null
ははは。皆さんノリが良いですねえ。
16 :
login:Penguin :2006/08/04(金) 21:29:56 ID:YSnXFLrG
質問です。 カレントに apple orange pine etc というディレクトリがあり、これに 次々とログインして(出来ればetc以外)、 $ myprog と実行したいのですが、どこから手をつけて良いのやらまったくわかりません。 わかる方、ヒントだけでも結構ですので、ご教授頂けませんでしょうか?
17 :
login:Penguin :2006/08/04(金) 22:03:09 ID:YSnXFLrG
微妙に自己解決 ls -1 | sed '/^etc/d' | xargs myprog で出来たくさいけど、美しくないです。 出来れば、これを $ myprog 一発でやれたらなと思ってます。
たびたびすいません。訂正です。
>>16 誤 次々とログインして
正 次々と移動して
でした。すいません。
>>16 for workingdir in apple orange pine etc # 「etc」がいらなきゃ削れ
do
cd $workingdir
myprog
cd ..
done
ま、cd .. という流儀が気に入らないという奴がこのスレにはいるかも。
そういう奴は適当にレスつけろや。
sedじゃないからレス付けないわよ
sedのスレじゃないんじゃない?スレタイの【sed】はpart1の継承と思われ。
>>19 >17はlsしてるから、こういうことのような気がする。
for workingdir in !(etc) # bashのみ
myprog一発の意味は良くわからないままだが。
24 :
login:Penguin :2006/08/05(土) 14:47:48 ID:9HX9xiOs
{}\ の意味を教えてください! GoogleやYahooで出ないよ!!!!なんでー
>>24 正確にいうと、
{}\ でなく、{} \
スペース空けないとエラーになります。
>>24 話が見えないんだが…
find の引数ってことで良いの?
まずman読もうよ.... >引き数は、 `;' を含む引き数にいたるまで、すべて command の引き数と >みなされる。文字列 `{}' は現在処理しているファイル名に置き換えられる。
30 :
login:Penguin :2006/08/07(月) 19:15:39 ID:C6inuQl7
>>19 >>22 亀レスですいません。アドバイスありがとうございます。
諸事情でネットに繋ぐことが出来ませんでした。
具体的にやりたいことを説明しますと、/var/spool/ml の下に100個程のディレク
トリがあります。etc他、数ディレクトリは無視して、任意のディレクトリ配下の
activeファイルからコメント行(#)を削除。その後、$ cp members actives を実行、
という感じです。
どういう用途かと言いますと、メーリングリストのユーザ設定ファイルのゴミ行を
整理する目的です。で、現在、次の様なmyprogというスクリプトを書き
#/bin/sh
PROGRAM=`basename $0`
HOME=/var/spool/ml/
for x in "$@"
do
if [ -d $x ]; then
if [ -f $x/actives ]; then
cd $x
sed '/^#/d' actives | sort | uniq > members;
cp members actives;
echo "done... $x"
else
echo "actives not found... $x"
fi
cd $HOME
else
echo "not direcotory... $x"
fi
done
31 :
login:Penguin :2006/08/07(月) 19:16:14 ID:C6inuQl7
下記コマンドでやりたいことは出来るのですが $ ls -1 | sed -e '/^bin/d' -e '/^etc/d' -e '/^@/d' -e '/^doc/d' | xargs myprog 出来れば、ls -1 の結果を配列(あるのかな?)に入れて、myprog内で実行したいと 思っています。また、こうすればもっと美しくなるというアドバイスもあれば、とても うれしく思います。
少し短くなりました。後は、ls -1 の結果を forに渡せれば完璧 なんですが(´・ω・`) #/bin/sh PROGRAM=`basename $0` HOME=/var/spool/ml/t/ for x in "$@" do if [ -f $x/actives ]; then sed '/^#/d' $x/actives | sort | uniq > $x/members; cp $x/members $x/actives; echo "done... $x" else echo "actives not found... $x" fi done
やりたいことできてるならそれでいいじゃん。 きれいに書きたいとか配列使いたいとかなら もっとまともなスクリプト言語使った方がいいよ。 そういうのをシェルに求めちゃいかん。
やきもそ?
TOPDIR=/var/spool/ml/t/ cd "${TOPDIR}" for x in * do case "$x" in bin|etc|doc|@*) continue ;; esac ${PROGRAM}はいらないのでは? ${HOME}を書き換えるのも気持ち悪いかと
>>33-36 アドバイスありがとうございます。
勉強になります。
>>35 PROGRAMは慣習でつけてます。拡張していった時に
echo "usage: $PROGRAM filename"
とかって使ったりするので。たしかにHOMEは気持ち悪いですね。直しました!
>>36 for x in `find hoge`
これは使えるかも!ありがとうございます!コマンド結果をxに渡せるとは
知りませんでした。
39 :
login:Penguin :2006/08/11(金) 19:52:52 ID:c1dCdFjO
Cutlist: 0-2731,19014-21714,37651-41262,64752-68382,80903-84503,95557-98910, という出力を 0 2731 0 19014 21714 0 37651 41262 0 64752 68382 0 80903 84503 0 95557 98910 0 このように整形することはできました。(最後の0は定数) さらにこの個々の値を全て29.97で割って倍精度出力したいのですが シェルスクリプトでそこまで出来るでしょうか? できるという方、その方法を教えてください。お願いします。 今のところのコマンド mythcommflag --getcutlist -f /mpeg/rec/1007_20060609005300.mpg | grep Cutlist | sed -e 's/Cutlist: //' -e 's/-/\t/g' -e 's/,/\t0\n/g' | sed -e '$,$d'
>>39 最終結果(倍精度出力)はawkあたりを使うと良いと思われ。
>>40 #!/usr/bin/gawk -f
/^Cutlist/ {
sub(/^Cutlist: */, "", $0);
sub(/,$/, "", $0);
n = split($0, a, ",");
for(i = 1; i <= n; i ++){
split(a[i], j, "-");
printf("%f %f 0\n", j[1] / 29.97, j[2] / 29.97);
}
}
42 :
39 :2006/08/11(金) 22:27:22 ID:c1dCdFjO
>>40-41 ありがとうございます。神です。
今から自分で一行ずつ理解していくつもりです。
# ちょっと複雑な物はawkのがいいのかな
ありがとうございました。
基本的な質問ですが、このスレって、sed、awk限定ですか? それとも、「シェルスクリプト総合」とある様に、他の質問などしても大丈夫 なんでしょうか?
【】はアホが付けたゴミなので無視すべし。
>39 bcの有無次第という経験がある。 perlの方がawkの実装違いに悩むよりはいい鴨試練。 >43 expectあたりもおk
wish もシェルの内?
仮にそうだとしても、このスレに書いても反応ないと思う。
大げさでも遠慮する必要もない、どんどん使え。 どうせperlは必須科目、読み書きできてあたりまえ。 pythonも必須科目になりつつある。 ruby、どうかな。 bashのスクリプトをpythonで書き直すとかはいい訓練になるよ。 古代象形文字を英語に翻訳する感じ。
50 :
login:Penguin :2006/08/17(木) 14:26:19 ID:NdJCZwC6
正規表現について質問です。 dir dir1 dir10 dir.tar file.php とあり、dir、dir1、dir10という風にdir[数字0桁〜2桁]へマッチさせたい のですが、 "^dir[0-9][^\.]" だと、dir自体にマッチしてくれません。どう書けばいいんでしょうか? 昨日からやってます。アドバイスお願い致します。 ちなみに、PHPのereg()です。
>>50 grep -e "^dir[0-9]*$"
?
数字は2桁までだそうですよ、センセ
なるほど。
>>52 は俺じゃないけど
grep -e "^dir[0-9]$" -e "^dir[0-9][0-9]$"
これでいいんか?
grep じゃなくて PHP だそうですよ、センセ。
だったらお前が書いてやれ、センセ
(^dir$|^dir\d{1,2}$)
dir\D+ともマッチしそうだけど、まいーか
あ、大丈夫だな
テキストファイルの中から、 "\b[a-zA-Z]{10}\b" にヒットする単語 (スペース+アルファベット10文字+スペース)を抽出して一覧で出 したいんですが、手も足も出ません。 awkかsedで実現する方法を教えていただけませんでしょうか。
>>63 (step 1)1行複数単語→1行1単語の形式にまず直す。
これは\bを改行にtrすることでほぼ実現できる(余計な空行とか多少入るけど)。
(step 2)grep '^[a-zA-Z]{10}$' のようなことをする。
(grepの実装によっては{}をサポートしてたりしてなかったりするだろう)
65 :
63 :2006/08/19(土) 21:41:31 ID:CKH2sw8O
>>64 貴殿、頭いいな。方向性は見えた。Thanks。
きのうやっとsedとかawkの勉強を始めたOSX使いの俺はお断りですかそうですか。 断られないようにきっちり勉強してくると汁。 でもさあ、 いまいち練習のいいネタが見つからないんだよなあ。 みなさま正規表現の練習とかするときのネタは、どこから仕込んでるんですか?
>>66 俺は初めはviの置換で練習した。sedと同じ表記が可能。
awkは言語としてとらえたほうがいいかも。
69 :
66 :2006/08/20(日) 15:46:43 ID:8BT2kJaV
>>66 BlogのHTMLの解析をして、それをRSSにでっち上げるとか面白そうだからやってみようと思いますた。
さっきからdatを解析してました。HTMLに吐き出すもの。
この1行で処理するというのには正直感動。
$ cat dat1.dat | awk -F"<>" '{print "<h1>" $3 "</h1><p>" $4 "</p>"}' | sed -e 's/\(
http:\/\/.*\/l50\ )/<a href=\"\1\">\1<\a>/g' > test.html
こんな具合だけれど…。文章中にリンクがあったときに、自動でタグをくっつけるやり方がいまいちぱっとしない。
sed -e 's/\(
http:\/\/[^/]*\ )/<a href=\"\1\">\1<\a>/g'
ホストのトップディレクトリにリンクがはれる('A`)。
いわゆる | をつけて処理しようとすると、うちのsedは何も吐き出さないんだけれど、これはバージョンが古いってことかな。
1行で実現するより、複数行になってもawkオンリーあるいはsedオンリーで実現した方が美しいだろ。
xmlawkつかうといいよ。
それで練習になるのか?
>>69 いわゆる | って正規表現の選択のやつ?
だとしたら、BREには選択はないのでそもそも使えない。
ただし、GNU sed だと \| という表記で使える。
75 :
login:Penguin :2006/08/22(火) 21:07:59 ID:+v8xeAHC
初歩的な質問で恐縮です。 user1:AAAAAAAA user2:BBBBBBBB user3:CCCCCCCC という中身のファイルがあったとします。で、user3の行があれば、第2カラムを DDDDDDDDに変更。無ければ、user3:DDDDDDDDの行を追加したいのですが、何の コマンドを使えばよろしいんでしょうか?希望としては、コマンド一発で出来る 方法を探っています。※Perlなどでスクリプトを組まない お知恵をお借り出来ればと思います。宜しくお願い致します。
>>75 (grep -v '^user3:' srcfile ; echo user3:DDDDDD) > tmpfile ; mv tmpfile srcfile
77 :
login:Penguin :2006/08/22(火) 21:29:52 ID:+v8xeAHC
>>76 ありがとうございます。
でも、これだと、user1,user2が上書きされて消えてしまいます(T.T)
ぇー
79 :
login:Penguin :2006/08/22(火) 21:39:31 ID:+v8xeAHC
なんか例がわかりずらかったですね。 もっと細かく説明します。 adminファイル admin:AAAAAAAA power:CCCCCCCC userファイル user:DDDDDDDD とあり、userファイルに、adminファイルの内容を追加したいのです。 追加だけなら $ cat admin >> user で済むのですが、既に追加済みの場合は、新しく、adminとpowerの行を 上書きしたいのです。わかりずらくてすみません。
細かくも何もぜんぜん要求仕様ちがうやん。 いつのまにかファイル2個あるし。
joinつうコマンドでできるような気がするが、オプション覚えるのがめんどくさいから、 俺はその手の処理にはawkを使うようにしている。
すいません。m(__)m 説明不足でごめんなさい。
join 微妙だなぁ。cat してワンライナー組んじゃった方が早い感じ。
>>75 を無理矢理一行で書いてみた。sed -iを使ったので反則気味。
#!/bin/sh
grep -q -c "user3:" userfile \
&& sed -i 's/^user3:.*$/user3:DDDDDDDD/' userfile \
|| echo "user3:DDDDDDDD" >> userfile
Linuxをインストールする時のパッケージや設定とかをシェルスクリプトにまとめたことある人いますか? シェルスクリプトはやったことがないので、こんな感じでまとめていいものか、 途方にくれています。 「スクリプト前」 # cd /etc # mv -i logrotate.conf logrotate.conf.org # cp -i -p logrotate.conf.org logrotate.conf # vi logrotate.conf # ci -u -zLT logrotate.conf 「スクリプト後」 if [ cd /etc]; then mv -i logrotate.conf logrotate.conf.org && cp -i -p logrotate.conf.org logrotate.conf && cp -p /home/SHELL/logrotate.conf logrotate.conf && ci -u -zLT logrotate.conf else echo"logrotate Error!!!" fi
>85 行動の成否で判定したいだけなら[]は余計。
引数に特定の文字列があるかどうか grep で確かめたい場合、 どういう書き方が一番いいでしょうか? 今は if echo "$1" | grep 'h[ao]ge' > /dev/null ;then こんな感じでやってるんですけど、 echo と /dev/null へのリダイレクトが冗長に思えるので、 もっと簡潔なやり方があれば教えてください。
>>87 case $1 in h[ao]ge) echo found ;; *) echo notfound ; esac
正規表現じゃなくてパス名展開なので注意
>>89 grep -s な環境もあるので、>/dev/null の方がポータブル。
91 :
login:Penguin :2006/08/29(火) 10:44:29 ID:LacrCZoW
>>86 の補足。
シェルスクリプトの文法では、if文は、
if コマンド; ...
なので、if cd ...; と書くという意味ね。
[ はif文の括弧じゃなくてtestコマンドへのリンク。
if [ ... ]; then は if test ...; then と等価。
test ではなく [ という名前で実行した場合は最後に ] という引数が
ないとエラーになるという作りになっている。
あぁ、]は引数なのか。どうりでスペースが。。。
勉強になった。ありがと。
>>85 じゃないけど
bashで、ファイルAとファイルBの タイムスタンプの同一性が確認したいのですが、 どーやればいいのでしょうか。 内容の同一性ではなく、あくまでタイムスタンプの同一性です。 Cでかけば、多分こんな感じ。 struct stat stat1=fstat(file1); struct stat stat2=fstat(file2); if( stat1.mtime==stat2.mtime){....} bash ではどうするのでしょうか?
test ! tstest1 -nt tstest2 -a ! tstest1 -ot tstest2 && echo hoge
96 :
login:Penguin :2006/09/03(日) 02:05:43 ID:F8zNeDUy
ディレクトリを755 ファイルを644で一括して変換したいんですが、 $ chmod -R 755 dir だと、ファイルも755になってしまします。何か良い方法かコマンドがあったら 教えて下さい。chmodのman見たけど、ないっぽいのでこちらで質問します。
find -type
>>96 find tmp \( -type d -exec chmod 0755 {} \; \) -o \( -type f -exec chmod 0644 {} \; \)
findってキモいなぁ
chmod -R a+r,u+w
101 :
96 :2006/09/03(日) 12:49:17 ID:F8zNeDUy
zshでしあわせになろうと、 chmod 755 **/*(/) chmod 644 **/*(.) を試みたらディレクトリが深すぎて怒られることもある。 一発でやらないなら find -type d -print0 | xargs -0 chmod 755 find -type f -print0 | xargs -0 chmod 644 が一番汎用性が高くてすっきりしているか。 Darwinの非GNU find/xargsにも-print0や-0あるようだし。
find . 以下略にすべきでした。
そういえばここLinux板だった。GNU find/xargs前提でいいんだな、きっと。
mkdir でディレクトリを作成してそのディレクトリに移動するスクリプトを書きたいと思っています。 #!/bin/sh mkdir $1 && cd $1 だと、子プロセスが移動するだけで親がcdしてくれません。いい方法はないでしょうか。
いまいち、意味がよくわからんけど、 呼び出すときに、 $ . /hoge.sh とするということか?
>>106 意味が分かりにくくてスミマセン。
パスが通ったところに例えばmkdircdという名前で置いておいて
$ mkdircd $(date +%Y%d%m)-1
とすると、$(date +%Y%d%m)-1というディレクトリを作成して
そこにcdするという意味です。言い換えると、
$ mkdir $(date +%Y%d%m)-1
$ cd $(date +%Y%d%m)-1
を一度にするという意味です。mkdirのワラッパーを作成してalisasで置き換え、
例えば--cdというオプションがあれば、mkdirした後にそこへcdするというもの
でも構いません。
# 単に打鍵数を減らして横着したいだけなのですが。。
ふふふ
「ワラッパー」ってのが何だかわからんけど、 関数じゃだめなん?
110 :
105 :2006/09/04(月) 16:52:20 ID:N5MHYTmG
>>109 ありがとうございます。解決しました。
mkdircd () { /bin/mkdir $1 && cd $1; }
>>102 find -type d -exec chmod 755 {} \;
find -type f -exec chmod 644 {} \;
wrap = ラップ (サランラップとかラッピングとか)
113 :
105 :2006/09/04(月) 23:17:00 ID:N5MHYTmG
chmod -R 644 /
115 :
login:Penguin :2006/09/05(火) 10:08:07 ID:5E+/nWTh
シェルスクリプトの中で変数中の "`" を "\`" に escape したいんですができません #!/bin/sh S='a`b' S2=`echo "${S}" | sed 's/\`/\\\`/g'` echo "${S2}" a`b 外部に sed script をおけばできるんですが shell script の中だけではむりでしょうか
そらそだ
S2=`echo "$S" | sed 's/\`/\\\\\`/g'`
118 :
115 :2006/09/05(火) 22:33:00 ID:pCLRKlZc
>>117 なるほど、できました
しっかし、これは難しかった
#!/bin/sh が `----` を解釈するとき
sed 's/\`/\\\\\`/g' が sed 's/`/\\`/' になって、
sub shell が '----' を解釈して
sed に $1==s/`/\`/ を渡すということですか!!
>>118 なんかああー!もうだめー!ブリブリぶりー!!って言うコピペに見えた。
>>119 脳外科池。
2chの見過ぎには注意しよう。
122 :
login:Penguin :2006/09/07(木) 17:27:40 ID:iCRx2SWb
dir以下を再帰的に掘っていって、全てのファイル(.txt)の中の文字列 SAM001P (SAM+三桁数字+英1桁〜2桁) のSAMを削除をしたいんですけど、どんな感じでスクリプトを作れば良いか アドバイス頂けますでしょうか? めんどくさいことに、SAM001P/SAM002PX/SAM003B ってのもあれば、 これについてはSAM004NNを参照。 と言う風に文に埋まってしまってるものもあります。なんとかshとsedとawkで やり遂げたいと思ってます。
>>122 find と sed -i で行けそうじゃない?
>>123 いけそうな気がして来ました!
がんばってみます(*・∀・)=3
例えば P1-5 P3-12 P2-9 を P1-05 P3-12 P2-09 というようにマイナスのあとを2桁にしたい のですが、 echo P1-5 P3-12 P2-9 | sed -e 's/P\([123]\)-\([0-9]\{1\}\)/P\1-0\2/g' P1-05 P3-012 P2-09 うまくいきません。この場合はどのように正規表現を書いたらよいのでしょうか。
126 :
125 :2006/09/14(木) 01:40:51 ID:p/dn3po+
自己解決しました cho P1-5 P3-12 P2-9 | sed -e 's/P\([123]\)-\([0-9]\)\([^0-9]\|$\)/P\1-0\2\3/g' P1-05 P3-12 P2-09
ちょw
128 :
login:Penguin :2006/09/22(金) 16:32:09 ID:Gi/VKmOp
簡単にお金稼ぎ!!!
以下の手順でやれば、無料でお金稼ぎができます。
企業も広告の宣伝になるから、お金をくれるわけです。
最初の1日目で 2000 円〜3000 円 は確実に稼げます。
実際の作業は数十分程度、1時間はかかりません。
@
http://www.gendama.jp/invitation.php?frid=470908 ↑このアドレスからサイトに行く。
Aそこのサイトで無料会員登録(応募)します。
(その時点で 500 ポイントが貰えます。)
※事前に新規でヤフーなどのフリーメールアドレス
を取っておくといいですね。
Bポイントを稼ぎます。
懸賞の応募や無料会員登録などをする事によって
1日目で約 20000 ポイントは GET できます。
C 3000 ポイントから、現金や WEB マネーに交換できます。
Dトップの右上に「交換」という所がありますので、
そこから交換をしましょう。
その月に初めてポイントバンクにポイントを移行した時、
さらに別途として 1000 ポイント貰えます。
これで現金や WEB マネーを稼ぐといいですよ!!!
129 :
login:Penguin :2006/09/25(月) 14:04:16 ID:ENWvwHb8
シェルはbashで、 MySQLのデータを元に自動でユーザを作るシェルを 作りたいのですが、参考になりそうなサイトを教えて 下さい。 ぐぐったけどそういう参考になるサイトが出てこないです。
常套手段だったらすまん。 #!/bin/busybox ash とかやると結構早くなるかな? それとも各種コマンドの表現力のなさに絶望するかな。
へぇー(x3)、busybox ashでシェルスクリプト実行させると 該当する外部コマンド呼び出しはシェルコマンド的呼び出しになるんだ。 $?とか使えるからてっきりバイナリ実体の共通化だけが目的で、 コマンド実行自体は普通にfork&execしてるのかと思ってた。 それはともかく、インストーラだとかでは結果的にそれやってる訳だから、 それなりに使えるんじゃない?逆にGNU拡張とかに依存しない移植性の 高いシェルスクリプトを書けるようになるかも。 速度は・・・速くなるだろうけど、シェルスクリプトで気にするかというか。
133 :
129 :2006/09/26(火) 10:54:20 ID:/kN9yJk7
シェルでMySQLの起動までは出来るんですけど、その続きを自動で処理してくれません。 (MySQLにログインした後、入力待ち状態になってしまって、起動後にDBを変更してくれない)。 mysql -u mofu -pmofumofu use mohe select * from moeneko; としたところログイン後の処理をしてくれずにMySQLを終わらせた時点でuseって何だゴルァと 怒られます(以降の処理も怒られます)。
>>133 echo 'use mohe; use select * from moeneko;' | mysql -u mofu -pmofumofu
135 :
129 :2006/09/26(火) 15:05:32 ID:/kN9yJk7
>>134 そんなスマートな方法が・・・。
mysql -u mofu -pmofumofu mohe <mofu.sql
[mofu.sql]
use mohe
select * from moeneko;
って2つのファイルにしてやってた。
問題はこのクエリを発行後、戻ってきた奴を変数に入れる方法だね。
//MySQLのレストア作業で読み込ませるファイルがCreate文とか普通に
手打ちで出来ることをテキストに纏めて順次実行してるだけなんだから、
select文とかも実行できるんじゃね?と思って試してみました。
シェル(使ってるのは主にbash)って、ちょっと複雑な処理をさせると、 すぐに動作が重くなるね(多重にループさせたときとか)。 同じ処理でも、Cの方が圧倒的に早い。 最適化しないのがおおきいのかな?
シェルは真のインタプリタ Tcl、Perlなどはランタイムコンパイル
>>136 具体的にどういう処理?
そもそもCで書かれたbash上の実行内容をCで書いたら負けるわけないだろ。
書く時間がかかるからフツーshellでやるけど。
>>139 >そもそもCで書かれたbash上の実行内容をCで書いたら負けるわけないだろ。
そうか?Cでアセンブラを書くことも出来るわけでな。
shellscriptだってバイトコードべた書きできるよ
原点に戻ろう。ケースバイケースで使い分ければ済む事。 用途に合ってれば、バイナリをゲロする言語で結構。 そこまですることない、ってーならシェルスクリプトでいいジャマイカ
>>139 遅レスだが、あるファイル内のすべてのの10進を16進に変換する処理。
(bashって、16進形式ないよね?)
アルゴリズムは16の何乗かで割っていくというよくある方法。
変換する文字が10個以上くらいになると、途端に遅くなる。
>>143 それシェルでやるか?
普通はbcやら計算用の他のプログラムを呼ぶと思うんだが。
そもそもシェルスクリプトは、単機能なプログラム群(test,expr,sed,awk,etc.)
のグルーとして機能して、複雑な機能の9割を短期間で構成できる所が強みだろ。
プログラミング言語としてのシェル自体の能力を語ってみてもなあ。
145 :
144 :2006/10/01(日) 19:21:28 ID:7VdKxRNj
16進変換自体は、bcでobase指定してもいいけど、今の時代ならprintfの方が簡単か。
>>143 みたいなジョークはおいといてw
必要ならperlやcで書いてそれをbashから使えばいいだけの事。
bashもいっぱしの言語なので他の言語で書けるアルゴリズムならbashでも書けるが
効率的にナンセンスなモノは書く前に気づけよ。
ちょいとbashで済ませる程度の事をcで書くのも効率的にナンセンス。
今のCPUの性能なら、基数変換程度の計算ならシェルで動かしても そんなに時間かからないと思ったんだけど、そうでもないのね。
敢えてbashismを犯してまでヤル作業でもないなぁ。と言う印象。
>>148 適材適所なので自分ではやらないいけど、
無茶する香具師がshellを改良するとか、
別のソフト作ることを期待して止めはしない。
そこでzshですよ
bashコンパイラを書けば解決さw bashってのは完全にプログラマの為の道具。 プログラマって人種が極度のキータイプ嫌いでものぐさな事を如実に示しているのがbash。 通常は最も手軽に動かせる言語で、だから初心者も使うんだけど非常に迷路じみて無愛想な言語。 適材適所で言うなら初心者には最も不適な部類の言語だと思う。
rcがいちばん。
inittabインタプリタが切に欲しい。
csh
氏ね
158 :
login:Penguin :2006/10/09(月) 23:35:33 ID:9KuWHWOZ
二つのsort,uniqされたファイル file1 a b c file2 c があったとして、file1-file2>file3 file3 a b みたいことやりたいんですが、何てコマンド使えば良いんでしょうか?
>>158 grep -v -f file2 file1 > file3
>>159 ありがとうございます!
すごく助かりました。
そういえばgrepで除外を意味する-vの由来は何だろう。 校正記号の「トル」?
--invert-matchのvじゃね。
163 :
login:Penguin :2006/10/10(火) 04:16:52 ID:j7TWTFqG
2000バイト以上のファイルを削除したい場合、どうしたら良いでしょうか? findと組み合わせればよいのは分かるのですが、-sizeの使い方が良くわかり ません。宜しくお願い致します。
すいません。 自己解決しました。 find . -size -2000c
ちょっと不親切でしたので、再投稿します。 find . -size +2000c -exec rm {} \; で解決出来ました。お騒がせしました。
vetoジャマイカ
>>155 cでしょうに。
ただcから入るとc++で頭切替えるのが大変になる。
c++てcを書いてる人が多い。
>>168 あえてネイティブで動かす必要のあるものを作る場合を除けば、いまどきCやる必要なんてないでしょ。
Rubyとかのスクリプト言語でサッと書いてサッと使ってサッと捨てる。
>>169 初心者向けの言語って意味だから。
プログラミング入門はcが王道でしょ。
いきなりrubyは高級すぎて何がすごいのかも理解できないと思うし。
まず単純で質素なcで学んでからの方がいい。
ちなみにおじさんはアッセンブラからやらされた。
その時はくだらないと思ったがcの過程でポインタや配列を即理解できてやっててよかったと思ったよ。
スレ違いの話はその辺で切り上げてくれないかな。
ついでに言えばアッセンブラとcは極論すれば書き方が違うだけで同じだった。 だがcとc++は根底が違う、見た目が一緒だから厄介。 >c++てcを書いてる人が多い。 の一人だったよ。 rubyの根底を理解するには基準としてcをやっておいて損はないと思う。 命令や文法だけ暗記しても無意味だから。 ちなみにperlはおおげさなものは何もない。 cの次にperlを初心者向け言語の候補に上げよう。 だらしないコードを書くようになる危険があるが。
>だがcとc++は根底が違う、見た目が一緒だから厄介。 マルチパラダイム言語という名の元、構造化プログラミングと言う枯れた手法を用いることもまた合法。
【sed】シェルスクリプト総合@LINUX Part2【awk】
tccでスクリプト書けば最強ということでFA? いや実際ツールコマンド化されてないシステムコール叩けて便利だけど。
「○○しますか?[Yes]/[No]」 と言うダイアログを表示させて、その後の処理を選択したとおりに分岐させたいのですが コマンド一覧などでは見つかりませんでした。 参考になるサイトなどがあれば教えて下さいm(_ _)m
>>176 gnomeならzenityってのがある。
>>177 ありがとうございます。早速逝って来ます
180 :
塩水 ◆1FrMT.vzQQ :2006/10/14(土) 20:07:07 ID:alqqP7TT
おもに計算はfortranでやって、ファイルの処理をシェルスクリプトとかでやってる。 計算終わってはかれたログを整理したりgnuplotで描画できるようにデータを変換したりする。 だいたいシェルスクリトプトとsedとawkで処理できるかなと思ってたけど、ちょっとした 計算に不都合があった。シェルスクリプトだと少数が含まれる計算や割算のやりかたが よくわからない。awkは引数としてファイルを指定して、そのファイルの中身をいじくるのは スムーズなんだけど、第一引数と第二引数に直接値を指定して、その引数同士で 計算させるというのが案外難しい。引数の定義をawk側でごにょごにょしないといけないみたい。 その点perlはARGVで直接ひっぱってきてささっと計算できた事をもってして、 ああ、perlも便利なものだったんだなって思えた。 これからperlも勉強してみようと思うんだけど、Rubyのああ、やってて便利だなと 実感できる強みみたいなモノってあるのかな。オブジェクト指向になってて、開発してて 楽しいスクリプトだという概観みたいなモノは把握したんだけど、まだいまいち実感がわかない。 まずオブジェクト指向なるものがそれほど理解できてないからかもしれないけど。 だんだんスレタイからずれてきた… るびらーの人がいたらおもしろそうな魅力をちょこっと教えてほしいな。
182 :
塩水 ◆1FrMT.vzQQ :2006/10/14(土) 20:38:03 ID:alqqP7TT
ごめん。 スクリプトは遅いって言われてるけど、そこまで動作速度に不満を感じることなんて ほとんどと言っていいほど無いんですよね。コンパイルという作業をかましてまで 速度を向上したいというようなプログラムは私的な状況の改善くらいでは特に感じない。 商品開発したり、いろんなマシンでも動くようなプログラム作ったりするのに コンパイルするようなプログラムが必要なのかな?でもperlなら大概のマシンで動くし。 科学技術計算はさすがにスクリプトじゃ無理だけど、身近な問題の改善なら スクリプト言語でじゅうぶんだと思った。と、懲りずに長文感想文。
>>182 2行だけ読んだ。それに関しては激しく同意。
>>179 ありがとうございます。
早速これも調べてみます
>>176 gtkというアプローチも。XでGUIプログラミングに便利かも。
手早い選択肢としては、179のdialogに同意。
dtkshとか。
187 :
login:Penguin :2006/10/19(木) 20:47:24 ID:FQ6Ui9I8
すいませんが教えてください /old の全ファイルを /new にコピーを行いたいのですが、 もし /new に同名のファイルがあれば、そのファイルはコピーしない というのをやりたいです 教えてスレではないと思うのですがよろしくお願いいたします
188 :
187 :2006/10/19(木) 20:48:09 ID:FQ6Ui9I8
あ、すいません bash です
>>188 cp をうまく使えばできないかい。
$ man cp
cp -u とか
>>191 .bashrc に alias で指定してあると思うが、じゃあ
cp でいいな。
rsync が一番適切なんじゃないの?
yes no | cp -ia ...
tar -C old -cf - . | tar -C new --keep-old-files -xvf -
197 :
login:Penguin :2006/10/20(金) 14:30:44 ID:lljI9Z8i
すみません。findコマンドで find ~ -name '*.sh' -exec rm -f {} \; みたいなコマンドを良く見掛けるんですけど、後ろの「{} \;」って どういう意味があるのでしょうか?
>>197 まず、findの-execスイッチは、「-exec command ;」という形式をとるの。
というところまではわかってる?まずこの点findのman読んで復習して。
{}の意味については、やっぱりfindのmanの-exec...の項を読むとみつかるはず
だから探してみて。
\;は、元々は-exec...;の最後の;。
なんだけど、シェルが;をコマンドの区切りとみなしちゃう(findの-execスイッチの
一部分だとはシェルには解釈しない&できない)から、それを防止するために
エスケープして\;と書くの。
>>198 あ、エスケープの「\」だったんですね。
manを読んでみます。
検索しても使いかただけとか、{}で検索しても良いページがでなかったもので。
'*.sh'でヒットしたファイルをカウンターにして forのようにまわして、{}にその引数の中身を展開して実行してるみたいですね。 for i in (ファイルのあるPATH)/*.sh ; do rm -f $i done みたい。
201 :
login:Penguin :2006/10/20(金) 20:51:18 ID:sPhZqjis
あるディレクトリを作成、その下にディレクトリツリー(movieとかaudio、更にそのmovieやらaudioディレクトリの 下に01、02〜の様な)を 作成してツリーの大元に戻って大本のフォルダをリネームをしたいのですが 最後の対話式でリネームする部分が難しくてうまい事作動してくれません。どなたか救いの手を…
204 :
login:Penguin :2006/11/04(土) 14:41:24 ID:8GhdlUfe
質問です 通常シェルスクリプトを書くとき,シグナルを受け取った時の 処理をシグナル毎に書くと思うのですが,逆に どのシグナルが送られてきたか調べる方法はありますでしょうか?
ないんじゃない。 myhandler () { local sig="$1" ... } trap "myhandler 1" 1 trap "myhandler 15" 15 とかじゃだめ?
>>205 やっぱりひとつひとつ調べないと無理ですか...(´・ω・`)ショボーン
あざーす
207 :
login:Penguin :2006/11/05(日) 13:28:09 ID:RXI70RMP
誰か暇な人解いて 引数付(1〜5)で実行したshellが何を引数として入力 したかを,switch文を使って表示させたい。 【その1】引数無し、もしくは引数が1〜5以外の場合 % ./test.sh Invalid number. % 【その2】引数が1〜5の場合 (5を入力した場合) % ./test.sh 5 You have imput 5.
switch文なんてないから不可能だな。
揚足取り乙
宿題は自分で。
マルチかよ…
お勉強中の素人です。 rsh 許されていないサーバとのやりとりを絡めた処理を やらせる為 , 一部 expect を使おうと思っています。 で , expect の send は実行したいコマンドを " で括りますが " 自体をコマンドで使いたい場合はどうすればいいのか ワカランです。 教えてくだされ。
お舞らちょっと漏れの愚痴を聞いて下さいませんか。 今GNU findを使ってディレクトリツリーのファイル一覧を出力したんだが、 日本語(EUC-JP)の名前が付いたファイルが上手く表示されねぇ。 以前は同じ $ find . -ls なんかで、ちゃんと表示されてたのに。 仕方ねーから、man findをじっくり読んでみた訳よ。 UNUSUAL FILENAMES : -ls, -fls Unusual characters are always escaped. White space, backslash, and double quote characters are printed using C-style escaping (for example '\f', '\"'). Other unusual characters are printed using an octal escape. Other printable characters (for -ls and -fls these are the characters between octal 041 and 0176) are printed as-is. 非ASCII圏は無視ですか。そーですか。 version 4.2からこんな仕様になっていたとわ… orz
>>213 find . | nkf -e
でもしとけ。
less なら文字化けしないんだけどね。
>>214 いや、だからfindが出力するファイル名自体が、既にASCIIで
\213\245\216\270...
になってるんですって。UNUSUALにされてしまうのです。
愚痴るだけではあれなので…
>>212 expectって結局はtclだから、\でエスケープ出来ない?
"command" なら "\"command\"" みたいに。
217 :
213 :2006/11/07(火) 18:32:30 ID:uIiz0qVx
上レス番号付け忘れますた。
>>214 >>215 確かに-print系では、出力が端末以外なら、そのまま表示できますが、
-lsで一気に詳細情報まで得ようとすると、どうやっても勝手に変換と。
一々-exec ls -l {} \;とか-printfで指定してやらにゃならんのか… o...rz
>>216 find に文句がいいたのですね。
「find でリストを作るのに nkf 噛ませないと行けないなんて find は使えねーな。」
ってことでしょうか。
>>218 nkf噛ませてもダメだから困ってるんじゃないの?
>>217 ああ -ls option の問題なのか。
いつも省略してた(-print が使われる)から分からなかった。
確かにASCIIになっちまうな。
これpatchないのかな?
patchつーかバグレポ対象だろ、これ。 少なくともlocale見て動けYO!位はいっていいんじゃない
>>222 >patchつーかバグレポ対象だろ、これ。
バグレポートだけよりパッチつきで報告してくれるほうがはるかに有意義だ。
シェル変数$tstvar1がwhileループ内で局所されて?しまいます。 ループの外で参照するにはどうしたらいいですか? ちなみにforループで違う感じにまわしてみたのですが$tstvar2は 局所されなかったとです。んん? $ cat tst.sh #!/usr/bin/env bash seq 1 $1 | while read line ;do tstvar1=$line done for i in $(seq 1 $1);do tstvar2=$i done echo while loop last num is $tstvar1 echo for loop last num is $tstvar2 #===================================== $ ./tst.sh 5 while loop last num is for loop last num is 5
225 :
224 :2006/11/18(土) 17:32:22 ID:IVoEU4qc
m(_ _ )m × 局所 ○ 局所化
zsh使え
227 :
224 :2006/11/18(土) 18:20:24 ID:IVoEU4qc
bashでおねがいしますm(_ _)m
$ cat test.sh #!/usr/bin/env bash seq 1 $1 > /tmp/hogehoge.tmp exec 3<&0 </tmp/hogehoge.tmp while read line; do tstvar1=$line done exec 0<&3 3<&- echo while loop last num is $tstvar1 $ ./test.sh 5 while loop last num is 5 リダイレクト or パイプだとサブシェルが起きちゃうからファイルに落とさないとむりぽ.
229 :
224 :2006/11/18(土) 22:28:24 ID:IVoEU4qc
そかー、サブシェルになっちゃってたんですねえ。 すっきり&たすかりましたm(_ _)m
ど初心者の質問で申し訳無いんだけど、単語を2列ずつにする のってどうすればいいんですか?↓こんなファイルを apple but chance data e-mail funny ↓このようなファイルに変えたいんだけど、、、 apple but chance data e-mail funny
>>230 sed -ne 'N;s/\n/ /;p'
>>230 column -c 16 ファイル
はだめなんだろな。。。
paste - -
>>224 bsh系で挙動が違うものの代表格だな。
kshだと、局所化されない。
bsh(V7やSolarisなど)は、局所化される。
bashも局所化される。
一方↓の場合、
while read hoge
do
〜
done < fugafile
bsh(V7やSolarisなど)は、局所化される。
ksh、bashだと、局所化されない。
>>231 >>233 ありがとうございます!めっちゃ感動しました
>>232 実はCygwinでやってるのだけれどcolumnコマンドが入ってなくて・・・
シェル関数について質問なのですが、シェル関数実行時に標準出力をファイル等にリダイレクトした場合には、 その関数はサブシェルで動作するとなっているのですが、何度試してもカレントシェルでの動作になります。 これは正常な動作なのでしょうか? それともシェル関数をサブシェルで動作させるには他に何か条件があるのでしょうか? 因みにシェルはbashを使っています。
238 :
あほ初心者 :2006/11/22(水) 00:12:00 ID:IxrPWlIp
すいません while文を使用したループで[条件1]もしくは[条件2]の場合ループを抜けるという or条件を指定したいんですけど、 やり方が判らないです。。。。 どなたか教えてください。 ↓↓↓の条件の[ $a -lt 3 ]に[&b_flg = "OFF"]というor条件を追加したい感じです。 ----------------- #!/usr/bin/ a=1 while [ $a -lt 3 ] do a=`expr $a + 1` done
while [ $a -lt 3 -o b_flg = "OFF" ] man test
whileで指定するのは、ループを「続ける」条件。
単に訂正しただけっしょ。
243 :
login:Penguin :2006/11/22(水) 00:32:08 ID:JDMO7VWz
初めまして。突然失礼します。 学校の課題なのですが・・・ 「ディレクトリ、/usr/binにある全ての実行可能ファイルのman一行出力をテキストファイルに書き出す。ファイルの数は膨大なので、スクリプトを書いて処理すること。」 このシェルをつくらないといけないんですけど どなたか教えてください><
そりゃいかんだろ。しかも、何にも知らない学生に出すような課題じゃないし、せいぜい悪あがきすることだ。
245 :
あほ初心者 :2006/11/22(水) 00:49:03 ID:IxrPWlIp
レス有難うございます。
>>239 これやってみたら無限ループしちゃいました(泣)
>>240 カウンターが3未満の場合、かつフラグが"OFF"の間ループさせたいのです・・・・。
>>243 その課題、前にどっかのスレで見たな。
過去に同じ質問をしたおバカな先輩がいるみたいだな。w
>>243 ls /usr/bin | (while read f ; do whatis $f ; done) > shell_tte_iuna_baka.txt
>>239 ×b_flg = "OFF"
◯$b_flg = "OFF"
でしょ。
>>245 >かつフラグが"OFF"の間
"かつ"ならor条件じゃなくand条件でしょ。
while [ $a -lt 3 -a $b_flg = "OFF" ]
250 :
login:Penguin :2006/11/22(水) 09:55:53 ID:V6McRbrX
自分がスクリプト書くときは、繰り返す場合いっつもforつかいます。 それは、なんらかのバグがあったときにforならあるところまでで必ず止まるという 安心感があるからです。 ところが、このスレではwhileを使っている人を結構見掛けるのですが、 どういう時に繰り返し処理をwhileで書こうと考えているのでしょうか?
>>250 なんだなんだ?確認するが「シェル」スクリプトの話でいいんだよね?
forとwhileじゃ意味がずいぶん違うじゃん。whileは変数を束縛しないでしょ。
それと、実行前に範囲が決まらない処理なんていくらでもある。
252 :
login:Penguin :2006/11/22(水) 10:27:53 ID:V6McRbrX
>>251 例えばtest1、test2...みたいなファイルを消す場合は
for i in `seq 1 1 9`; do rm test$i ; done
rm -f test??
みたいな感じでシェルスクリプト書いてるんですよ。
なんかバグってwhileで意図しないファイルまで消されてしまうような気がして、
あんまりwhileを使いたくないんです。気分的に。
ただ、whileならではの利点みたいなものが見えれば、whileを勉強する意欲が
湧くかなって思ったので、そのwhileの魅力みたいなモノがあれば教えていただければ
と思いました。
>>250 for(i = 0; i < MAX; i++) {
printf("infinite loop\n");
$i = 0; /* this code is fatal bug */
}
上記の通り、バグで止まるかどうかという意味ではforも同じです。
使い分けは、ループの意味で分けるのが可読性の観点で好ましいかと。
一定回数カウント、もしくはイテレータで繰り返してループするものにforを、
回数不定で特定の条件を満たすまでループするものにwhileを、というのが
一般的かと思われ。
ごめんCのこと書いた。
255 :
login:Penguin :2006/11/22(水) 10:40:40 ID:V6McRbrX
>>253-254 なるほど、whileの使い分けとしては回数で止めるか、条件で止めるかということですか。
でもなんだろう、この自分の中の漠然としたwhileに対する不安感は、やっぱり
使ったことが無いからなのかもしれないですね…
whileの練習もかねて意識して使うようにしてみます。
ありがとうございましたm(_ _)m
256 :
login:Penguin :2006/11/22(水) 14:15:34 ID:pcMmUayC
変数に"/"が入っている文字列を"/"部分だけ "\/"にしたいのですが、 sedでできません。 誰か良い方法をご存知でしょうか? test=test1/test2 sed "s/\//$test/g" 【実行結果】 sed: 1: "s/\//test1/test2/g": bad flag in substitute command: 't'
一番手っ取り早いのは、 sed "s|/|$test|g"
誰も突っ込まないのは…釣り?
しまった。つられた。 test=$(echo $test | sed "s/\\//\\\\\//g") バッククォートなら、 test=`echo \$test | sed "s/\\\\//\\\\\\\\\\//g"`
折角のLinux板なので ${test//\//\\/} なんつーbash限定の方法は如何?
sugeeeeee
ぜんぜんすごくない。 典型的なキモい拡張の代表格じゃん。
>>263 別にお前がすごいと思おうが思わないだろうが関係ないよ。
俺がすごいと思っただけだから。
>>264 そして、そんなお前を俺はダセェと思ったんだ。
bash 限定なら便利だよね。
267 :
login:Penguin :2006/11/24(金) 15:37:53 ID:QetvQUTA
こんにちは。 19/Nov/2006 19/Nov/2006 20/Nov/2006 21/Nov/2006 21/Nov/2006 22/Nov/2006 なファイルがあり、それぞれ数えて 19/Nov/2006 2 20/Nov/2006 1 21/Nov/2006 2 22/Nov/2006 1 としたいのですが、どすればいいでしょうか?ヒントでも良いので お願いします!
uniq -c
>>268 こんなに早く解答を頂いて、本当にありがとうございます!
とても助かりました。
270 :
login:Penguin :2006/11/24(金) 18:24:46 ID:oYJh4kFu
test="A<タブ>B<タブ>C" echo "$test" | while read in line do echo "$line" done を実行すると、 B<タブ>C となってしまいます。 A<タブ>B<タブ>C と得るにはどうしたらよいでしょうか?
>>270 1. while read line
2. echo "$in<タブ>$line"
3. IFS='
'
好きなの使え
272 :
あほ初心者 :2006/11/25(土) 00:30:44 ID:PS7K2G+h
>>249 返事遅れてスイマセン。。。。
書いてある条件でやったらできました。-aや-oの指定方法理解できました。
有難うございました
sedはignorecaseでのマッチングはできないんでしたっけ?
>>273 /regexp/I
とか
s/regexp/replacement/I
とか
>>274 どうも。GNU拡張だったみたいですね。
sed、awk、tar、cpioはgnu版が一番。
GNU 版以外になんかあったっけ。
awkはgawkだよね < 正式名称(?) tarもgtarだ sedとcpioは?
ggrep …ぐぐれっぷ。
BSD系はGPL汚染を避けるために独自のunix toolそろってるよね。 今でも完璧にGPLフリーなの?
>>282 C コンパイラは gcc 使ってなかったっけ。
まぁ、詳細は UNIX 板で聞いてくれ。
GPL 汚染を避けるためってより 元からあるのを使い続けてるだけ。
285 :
login:Penguin :2006/11/27(月) 02:46:22 ID:cP0Kjc7q
sedでもなんでもいいですけど、 ABC DEF GHI という改行入りの文字列を ABCDEFGHI としたいのですが、 231 を真似て、 sed -ne 'N;s/%\n//;p' としてみましたが、 ABC と一行の場合は、空白になってしまいました。 どうすれば実現できますか?
286 :
login:Penguin :2006/11/27(月) 03:00:07 ID:OelJATmM
>>285 while read line;
do
echo -n "$line"
done <<END
ABC
DEF
GHI
END
echo
----
とかではあかんの?
#
>>285 さんもお仕事中ですか?
#私の方は目途が付いたのでそろそろ仮眠入ります(=.=)
> 280さん そうなんだ 正式名称ってわけではないのっすね Solarisでびっくりした記憶が むぅ ねむい
288 :
login:Penguin :2006/11/27(月) 07:50:47 ID:bqAw+xNf
289 :
login:Penguin :2006/11/27(月) 22:38:33 ID:0CtuQywK
アホな初心者なんだけど教えて! $Aと$Bにはそれぞれ時刻が(xx:xx:xx)の形式で格納されているんだけど これを$Aと$Bの比較を行いそれぞれ条件分岐で表現させたいんだが どうすればいいだろう? if文でずっと考えていたんだが 文字列と数列演算の比較しか調べても出てこなかった。
>>289 $A と $B を date コマンドで変換して比較するとか。
date -d "$A" '+%s'
xxの部分が必ず二桁であるなら、言い換えれば、コロン除いて必ず6桁であるならば、 [ "`echo \$A|sed \"s/://g\"`" -eq "`echo \$B|sed \"s/://g\"`" ] とか。 bash依存でいいなら、 [ ${A//:} -eq ${B//:} ]
292 :
login:Penguin :2006/11/27(月) 23:09:28 ID:bqAw+xNf
感動した
294 :
login:Penguin :2006/11/28(火) 00:23:02 ID:fFcPBnEd
あるファイルの一部(何行もある)を違うファイルに書き換えるのはどうやるの? 例えば、 aaa aaa aaa aaa aaa aaa abc 1 2 abc 3 4 bbb bbb bbb というファイルを abc 1 10 abc 3 20 と言うファイルを使って aaa aaa aaa aaa aaa aaa abc 1 2 10 abc 3 4 20 bbb bbb bbb にしたいんだけど。。 どえらく行があって普通にsedの置換する行を書かせて実行したら 一日で終わらないくらい時間がかかってしまって。。。 もしくは、行単位で置換じゃなくて、数行単位で置換は出来ないのでしょうか? 偉い人教えてください。
sed -e 's/abc 1 2/abc 1 2 10/gc' -e 's/abc 3 4/abc 3 4 20/gc' <input.txt とか。
>>295 そのabc 1 2ってところがファイルの内容によって変わるから-eでは指定できなくて
困ってんじゃないの。
俺ならperlに逃げるが、...
どうしてもsedでやるなら、「2番目のファイルから
>>295 のようなsedスクリプトを
生成する」というスクリプトをsedなりawkなりで書くんだろうな。
297 :
login:Penguin :2006/11/28(火) 01:38:28 ID:hlMS5leM
294だけどそれを数だけ書いて実行したらどえらく時間がかかってしまって…
タグで抽出してからいじれ
いずれにせよ行指向なシェルスクリプト+αにゃ不向きだな。 置換したい行の位置が変わってもよければまだなんかありそうだが。
301 :
login:Penguin :2006/11/30(木) 15:18:39 ID:qADJb4/Z
シスログなどのファイルからエラー項目を取り出して、 対象となるデーモンをリスト化したファイルとマッチさせて 対象があれば正という処理をしたいんですが 参考となるスクリプトを掲載したHPはありますか? 考えられるキーワードでググっても出てこないので 困ってます。
grepで済むと思うが
303 :
login:Penguin :2006/11/30(木) 15:48:37 ID:qADJb4/Z
で、問題はこれを5分間隔でやっているので その間に発生したエラーログのみ監査対象が限定されるのです。 シスログの日付とlocaltimeを比較しないとダメなんです。
ならdateとgrepで済むと思うが
>>303 最近のsyslogdなら、名前付きパイプに対応してる。
FIFO経由で順次処理の方が良いんじゃね?
306 :
login:Penguin :2006/12/01(金) 19:53:40 ID:gsraXxcw
ところで、シスログなどのファイルをリストとして読み込むには 皆どう処理してる?
>>294 awkで書いて見た。久しぶりに使ったけど便利だな。
BEGIN{
while( getline p < ARGV[1] >0){
split(p,a," ")
word[ a[1] + a[2] ] = a[3]
}
ARGV[1] =""
}
{
if( word[ $1 + $2 ] != "" ) {
print $0 " " word[$1 + $2]
} else print $0
}
>>307 ちょっとだけ修正
word[$1 + $2]は
word[$1 + " " + $2]の方がいいかも
word[$1 + $2]だと "abc" + "1"が"abc1"になるので
"abc" + "1"と"ab"+"c1"が両方とも"abc1"になってしまう。
>>294 のように文字数が一定なら問題ないけど。
まあ実用にするんだったらもっとあちこちいじらないとダメだな。
一万行あったら終らない。
スクリプトでなんともできない量なんだったら、
いっそCで組むなりDBにいっぺんつっこんでなんかで処理するなりしたほうが。
>>303 1. いっぺんログ(a)を全部コピる(b)
2. 5分たったら(b)の行数分だけ(a)からはじいて更新行だけ抜く(wcなりtailなりdiffなり)
3. 抜いたものに処理かまして1.に戻る
312 :
login:Penguin :2006/12/02(土) 17:04:04 ID:6y2Ykjot
以下のような配列から 20061201120000 **** ***** **** 20061201130000 **** ***** **** 20061201132000 **** ***** **** 20061201132100 **** ***** **** while文で上のリストを読み込んだときに 左1番目の日付記録と現在の記録を比較して 5分以内のみを取り出して別のファイルに読み込ませる ということを行いたいです。 whileとifの組み合わせでうまくいかないんですが 皆さんならどう書きますか?
まずは自分がどう書いたかだ。
314 :
308 :2006/12/02(土) 18:00:30 ID:RMFwKrIK
>>308 おおボケかましてた。
>word[$1 + $2]だと "abc" + "1"が"abc1"になるので
"abc" + "1" は 1 だった。
+を抜いて word[$1 " " $2]こうしないと
BEGIN{while(getline < ARGV[1]) word[$1 " " $2] = $3; ARGV[1] = ""}
{ if(word[$1 " " $2]){ $4 = word[$1 " " $2]
#ここも追加
}else delete word[$1 " " $2];
print $0
}
END{for( s in word) print s "=" word[s];}
これで見るとif(word[$1 " " $2])の時にwordに追加されるようで
でかいファイルでやってたらメモリが足りなくなる。でdelete を追加。
>>294 のデータでのテストならちゃんとした結果が出るが
実際のデータでやってたらおかしな結果になったんだろうな。
危ない危ない。もうない事を祈ってorz
ふつーに word[$1, $2] でいいのではないかと。 多次元配列のように見えるけど、実体は word[$1 SUBSEP $2] という 組み込み変数 SUBSEP で連結しただけの1次元配列。
こんな感じかな? gawk 'BEGIN{ filt=strftime("%Y%m%d%H%M%S",systime()-300) } $1>=filt{ print }' < 元ファイル > 新ファイル名
>>312 (d=`date -d -5min +%Y%m%d%H%M%S`; while read l r; do if [ "$l" -gt "$d" ]; then echo "$l $r"; fi; done) < list > other
318 :
312 :2006/12/03(日) 13:51:58 ID:N72hre3c
>317 ありがとうございます。 私は今こんなスクリプトで書いていますが検討もつきません。 cat /var/log/errlog | sed -e "s/Jun/1/g" | sed -e "s/Nov/11/g" | sed -e "s/://g" | awk '{print $1$2$3}' これらをwhileでまわしてどう比較させるのか、まったくわからん・・
ああ現在の記録の方か
321 :
login:Penguin :2006/12/03(日) 14:28:51 ID:0bKgPd66
質問です。 a.aaaa.aaaa.aaaa.a b.b cccccc.c.c.cc.ccccc のような内容のファイルがありまして、最後の.から右側だけを取り出したいのですが、 sedだとどうやるんでしょうか。 $ sed -e '/^(.*)\.(.*)/\2' のようなやり方だと、後方参照の数字が分からないで困ってます。
\.([^\.]+)$
それ何てAA?
\.([^\.]+)$ プギャー
>>324 ご本人殿、馬鹿に付き合ってくれてありがとう
326 :
321 :2006/12/03(日) 17:50:37 ID:0bKgPd66
>322 ありがとうございます。 しかし、 $ cat list | sed -e 's/\.\([^\.]+\)$/\1/' a.aaaa.aaaa.aaaa.a b.b cccccc.c.c.cc.ccccc となってしまいます。何故だろう。
sed 's/^.*\.//g'
あgいらんわ
foreach line (`cat file`) foreach> echo $line:e foreach> end とかいう技がある。csh/zsh だけどね。
IFS=. while read line do set set ${line} eval "echo \"\$$#\"" done POSIX な sh なら動くと思われ。 取り敢えず、ash/ksh/bash それと emulate sh/emulate ksh な zsh では確認。
cut -d\. -f2- list が最短?
334 :
321 :2006/12/04(月) 17:16:11 ID:IolELO07
>328 すげー。ありがとう。
>>333 > ピリオドの個数は不定。
だから -f 2- なんだと思うが
あ、ごめん「最後の.から」か
rev | cut -d. -f1 かな。
いろいろ覚えるの面倒だからなんでもawkでやってしまう。 jgawk -F. "{print $NF}"
\.([^\.]+)$ プギャー
カレントディレクトリにあるflvをflv2mpeg4を使ってaviに変換するために 以下のようなスクリプトを書いています。 #!/bin/sh for file in `ls` do case "$file" in *.flv) flv2mpeg4 $file `echo $file|sed -e "s/\.flv$//"`.avi ;; esac done しかし、flvのファイル名にスペースがあると(cat vs dog.flvみたいな) dog.flvというファイルを変換しようといてしまいます。空白を含むファイル名 も正常に変換するにはどのように書けばよいのでしょうか? 初歩的な質問かと思いますが宜しくお願いします。
てか、なんでcase "$file"と自分からquoteしておきながら、 flv2mpeg4 $fileの方はquoteせんのんのん?不思議や。
>>341 for file in *.flv
do
flv2mpeg4 "$file" `basename "$file" .flv`.avi
done
>>343 `…` もクオートせんと、単語分割されるかと。
"$(…)" を使うか、可搬性をあげたいなら
basename=`…` と、一旦変数に格納するか。
ま、俺だったら
for file in *.flv
do
flv2mpeg4 "$file" "${file%.flv}.avi"
done
だな。
345 :
341 :2006/12/09(土) 00:39:41 ID:1jyOluzm
うほっ出来ました。 目的のことよりもたくさんの知らないノウハウを得ることが出来ました。 皆さん本当にありがとうございました。
画像とかで名前だけ違って中身が同じファイルがあることがよくあるので ファイルのサイズが同じファイルがあれば表示するようなのを つくろうと思っているんですが、可能ですよね?
>>346 ls -lなりstatなりでサイズを取得しつつ、
sort (適当なフィールド) |uniq -d とかすればいいんじゃね。
サイズ同じで実は違うファイルって言うレアケースも、
md5とかのハッシュ使えば判別できるだろ。
>>347 サイズをうまいこと受け取ることができるか不安ですが ありがとうございます。やっぱりできそうですね。 重複を自動で消すのもかんがえましたが手違いがあったら恐いので サムネイルでも確認しながら手動で消すことにします。
>>348 サムネイルで確認すると言うことは画像ビューアを使うと言うことだよね?
それなら、重複画像検索機能つきの画像ビューアを使った方がはやいかも。
重複画像判定アルゴリズムを再発明する必要はないと思う。
cmp では何か問題ある?
>>350 >>346 に書いているだけの内容ならcmpで十分だと思うけど、Exifを削除しただけで
同じ画像にもかかわらず違うファイルと判定されるので、
>>346 はすぐに限界に気が
つくと思う。
>>352 おぉぉぉ、これは便利そうな。
精度と速度のバランスがどれくらいか分からないけど、Shellスクリプトから使える
のは何よりもありがたい。
>>353 md5sum位取ったほうがいいと思う。
355 :
login:Penguin :2006/12/12(火) 17:31:57 ID:o5CvLJw/
「夜23時からから朝の7時以外ならcommand実行」 というスクリプトを書きたいのですが、いい方法ないでしょうか?
>>349 >>351 わかりました。
そのような既存のソフトは結構あるようなので
そういうのを使います。
>>355 #!/bin/sh
test `date +%H -d '+ 1 hour'` -gt 8 || exit
...
>>358 はウソ。あまり考えずに書いてしまった。スマソ
360 :
355 :2006/12/13(水) 00:12:01 ID:0m8saZaP
>356 >358 ありがとう。 >359 参考になりますよ
あるディレクトリにファイルが沢山入っていて、 更新時間が早いファイル順に並べて(ls -t)、そのうちの上から20%のみを移動させたい のですが、いい方法はないでしょうか? それt、lsって絶対パスでファイル名を表示させるオプションはないでしょうか?
>>361 for i in `find .`;do `pwd`/$i;done
>>362 なんで全ファイルを実行してるのかよくわからんが
素直に find `pwd` でよくね?
>>384 「Bourne Shell 自習テキスト」は、リダイレクトのところが誤解を与える説明になっている。
というか、間違っている。
366 :
361 :2006/12/13(水) 13:04:20 ID:9APFlcGm
ありがとう
ディレクトリに多くのファイルが入っていて、とある日付より前のファイル、 例えば「最終修正時刻が2006年12月01日より以前のだけを抜き出す(表示)」 ということをしたいのですが、シェルスクリプトで何とかならないでしょうか?
touch -t 200612010000 /tmp/hoge.$$ && find /dir \! -newer /tmp/hoge.$$ && rm /tmp/hoge.$$
369 :
login:Penguin :2006/12/16(土) 19:09:54 ID:bwKTijT0
date --date '1 day ago' +%Y%m%d なんだよ!あるんじゃん!計算しそうになったよウワァァァァァァヽ(`Д´)ノァァァァァァン!
372 :
login:Penguin :2006/12/17(日) 15:45:21 ID:waTrWC3J
【やりたい事】 2ちゃんねる過去ログの任意のレス番カキコを手動あぼーんしたい。 【やりかけている解決法】 2ちゃんねるログは1行1レスの書式なので、まずあぼーんしたいレス番をファイルdeathnoteに 書き連ね、それを読み込んで指定行ごとに置き換え処理をするスクリプトabonerを作る。 ファイルAの中身(例: 1 3 5 --------------------------------- スクリプトabonerの中身: #!/bin/bash INS="deleted<> <> <> <>" for i in `cat $1` do sed -i.bak -e "${i}s:rst:${INS}:" $2 done ---------------------------------- $ ./aboner deathnote xxx.dat これで一応望みの結果は得られるのだが、どうもスマートじゃない。 実際処理時間は、300kB程度の1000到達ログの400件あぼーん処理を Athlon3000+で約10秒。 sed以外(awk,perl)は使えません。 forで毎度sedを呼び出さず、sed一度で済む方法があれば教えてください。
sed 's/$/s:rst:deleted<> <> <> <>:/' dethnote | sed -f- xxx.dat rst って文字列を置換してるようなのでそうしてるけど、rst って何だ?
374 :
372 :2006/12/17(日) 16:37:55 ID:waTrWC3J
>>373 即レス感謝です。
すいません。rstはテスト用の適当な文字列で無意味です。
一行で出来るとは素晴らしい。処理の負荷も格段に減らせそうです。
提示していただいた式をヒントに、自分の目的を完全に満たすように更に詰めて。
後でまた報告します。
重ねてありがとうございました!
OS X のdateは、GNU date じゃないので注意.... 自分で作ったものだとPerl で timelocal 使って計算しているな〜
この板で他の OS の話持ち出されても。
>>375 のようないかにもLinuxしか知りませんてのはこの板だから許されるんだから
おおめに見てやろうや。
bashのスクリプトで ファイルの容量が一定以上の場合指定の処理を行う という記述はどのようにすればいいでしょうか わかるかたいましたらお願いいたします。
384 :
login:Penguin :2007/01/02(火) 18:40:10 ID:Y0JKQGy+
標準エラー出力は 2>/dev/null とかで捨てることができます。 でもシェル内部コマンドだとこれが有効でないようです。 echo aaa > test.txt chmod 000 test.txt echo aaa > test.txt bash: test.txt: 許可がありません echo aaa > test.txt 2>/dev/null bash: test.txt: 許可がありません echo の場合も標準エラー出力を捨てたいのですが、 なにか方法はありますか?
それ、echoじゃなくてbashのエラーだと思われ。
exec 2>/dev/null
>>384 外部コマンドでもいっしょだよ。
/bin/echo aaa >test.txt 2>/dev/null
とかやってみ。
内部、外部関係ないですね。 シェルでリダイレクトする部分でエラーになるんですね。 chmod 000 の意味はとくになくて、"w"のビットを 落としたかっただけです。 横着せずに echo する前に適切に chmod することにします。
>>386 ,391
すんません、exec 2>/dev/nullでうまくいきますね。
サンクス。
>>396 >>389 > 内部、外部関係ないですね。
> シェルでリダイレクトする部分でエラーになるんですね。
のこと?
まさにこれを言いたかったんだけど。
>>398 内部 - bash 組み込みコマンドのecho
外部 - /bin/echo
>>399 ああ、思い出した。
何検討違いなこと言ってんだ。と言うお話だった。
401 :
login:Penguin :2007/01/05(金) 00:43:02 ID:SpssQH6A
質問です。 ファイル名が1行につき1つリストアップされているファイルfilelistが あって、for文でそれを処理したいとき、以下のようにするとスペースを 含むファイル名のものをうまく処理できません。 何か良い回避方法ありますか? for i in `cat filelist` do ファイルに対して何か処理 done 引数として渡した場合は「"$@"」を使えばいいんですけど・・・
>>401 for i in "`cat a.txt`"
do
echo "$i"
done
とか?
>>401 (
while read filename
do
"${filename}" に対して何か処理
done
) < filelist
IFS いじるとか。
>>403 対象がファイル名ならあまり心配はないかもだけど一応
read -r filename
while read line do python youtube-dl "$line" done < "$@" こんな感じのは? 俺がyoutubeからリストで落とすときに使ってるやつw
407 :
401 :2007/01/06(土) 03:01:07 ID:Gq/KqTu1
すいません遅くなりました。
>>402 これだと1回で一度にa.txtのすべての行を処理するようです。
ただ、引数として改行を渡す方法は始めて知りました。
これはこれで後で使わせていただきます。
>>404 おっしゃりたいことは分かるような気がするのですが、実現できず。
精進します・・・
>>403 ,405,406
なるほど。readを使うのは考えつきませんでした。
これで意図したとおり動作しました。
みなさんありがとうございます。
今初めてShell Scriptを作成しています。 バックアップ用のShell Scriptなのですが、 フルバックアップディレクトリ内のファイルとバックアップ対象ディレクトリ内のファイル群を比較し、 1. 変更前の古いファイル(差分)を抽出して「昨日の日付名のディレクトリ」に追い出し、 2. 変更後の新しいファイル(新規作成ファイルを含む)をフルバックアップディレクトリに追加して、最新の状態にしたいです。 更新されたファイルをチェックして、古いものを昨日のディレクトリへ移し、最新のファイルを最初に作成したバックアップディレクトリに追加するという処理をしたいです。 最新のファイルが存在するバックアップディレクトリは、バックアップが実行されるたびに、その実行日名にリネームします。 で、今こんな感じなのですが、ご助言を頂けないでしょうか? #/bin/sh back=backup kyou=$(date '+%y%m%d') kinou=`date --date '1 days ago' '+%y%m%d'` mkdir /$back/$kyou if test -d /$back/$kinou -a -e /$back/$kinou ; then #mv /$back/$kinou/* /$back/$kyou/ rsync -vrpogtu --delete /data/ /$back/$kyou else rsync -vrpogtu --delete /data/ /$back/$kyou fi 1.バックアップ元とバックアップ先のファイル群を比較する方法が分かりません。 2.比較の結果の変更前の古いファイル(差分)だけを抽出して昨日のディレクトリにコピー する方法が分かりません。 3.変更後の新しいファイル(新規作成も)をフルバックアップに追加して最新の状態にする 方法が分かりません。 よろしくお願いします・・・ # 当方本当にシロウトです。
>>408 rsyncとかbontmiaでぐぐると幸せになれると思う。
>>409 rsyncもpdumpfsも知っているのですが、このbontmiaって言うのは何ですか?
ググったのですが、「これさえあれば他のバックアップツールはたぶんいらない」とか
「まさに rsync + pdumpfs なバックアップツール」とかそんな事しか書いてないので
具体的にどういう動作をするのか分かりません。
それから、2007/01/08/data みたいな深い階層がイヤで
070108 みたいなフォルダに差分抽出更新バックアップをかけていきたいのです。
そういうソフトが無いのでShell Script書くしかないと思っています・・・
>>409 Archive structure
The archives is placed in a directory structure like this:
2003/05/06/04:00/
2003/05/07/04:00/
2003/05/08/04:00/
2003/05/08/05:00/
2003/05/08/06:44/
これはひどい・・・・時間まで入ってさらに階層が深くなってるOTL
>>412 希望する仕様の詳細が不明だけど、
1. diff -rq sourcedir backupdirで変更されたファイル一覧を作成
2. 1 の出力から、sourcedirだけに存在するものをのぞけばファイルリストができるから、
それらを cp -p で backupdir2 にコピー
3. rsyncでbackupdirを最新版のバックアップに
4. ディレクトリ名は適当にリネーム
>>413 アドバイスありがとうございます。
[root@host root]# mkdir test
[root@host root]# cd test/
[root@host test]# mkdir dir1 dir2
[root@host test]# touch dir1/a.txt dir1/b.txt dir2/a.txt dir2/c.txt
[root@host test]# diff -rq dir1/ dir2/
dir1/だけに発見: b.txt
dir2/だけに発見: c.txt
[root@host test]#
このようになるわけですが、b.txtを除くわけですよねぇ。しかし
"dir2/だけに発見: "という文字列が邪魔で、その出力結果を例えば・・・
# tmp=`diff -rq dir1/ dir2/`
# cp -p $tmp backupdir2
のような事が出来ません。(それプラスに、1レコードずつ処理させる方法が・・・)
ん〜と、1レコードずつ処理させるには・・・ファイルに落としてしまって・・・
# diff -rq dir1/ dir2/ > list.txt
# for i in `cat list.txt` ; do cp -p dir2/$i backupdir ; done
ってやるんですかねぇ・・・?1レコードずつ処理させる方法がコレであってるなら
後は邪魔な文字列を消す方法をお願いします・・・
>>414 こんな感じか
LANG=C
DIR1="dir 1"
DIR2="dir 2"
diff -rq "${DIR1}" "${DIR2}" | while read i; do
echo $i | grep -e "^Only in $DIR2" | sed "s/^Only in \(.\+\): /\\1\//"
echo $i | grep -e "^Files" | sed "s/Files .\+ and \(.\+\) differ/\\1/"
done
リストにはディレクトリも出てくるから cp には -r もつけた方がいい
>>408 いまいち仕様がよくわかんないんだけど、
rsync の --copy-dest とか --link-dest あたりじゃだめ?
>>415 わけがわからないですが、とりあえずコピペして実行してみます。
>>416 pdumpfsと同じような動作をするようですのでダメです。
pdumpfsがなぜいけないかというと
1.ディレクトリが深すぎる。 2007/01/08/ のように掘るのではなくて
070108/ と1個作ってくれるとありがたいです。
2.全てのファイルが各日付フォルダの中にある。
ココが一番困るところで、更新したファイルのみが過去のフォルダに残っていってくれると
この日にこのファイルを更新したのだと分かりやすくていいのですが・・・
ハードリンクで更新したファイルも更新してないファイルも全部残っているでしょう?
それがまずいんです。
もしよろしければ
Fabreの仕様
http://hp.vector.co.jp/authors/VA004777/report/fabre2.html をお読みくださいませんか?
私の方からも簡単に説明いたしますと・・
まず一回目実行した時にLinuxのdateコマンドの # date '+%y%m'で得られる形式の
フォルダが作成され、そこにバックアップ対象フォルダ内のファイル及びフォルダが
全てコピーされます。最初の1回だけはタダのコピーです。
その後2回目の実行(1日過ぎて)で、また日付フォルダが作成されます。
一回目が070110(今日)なら、二回目は070111フォルダが作成され、
バックアップ元の更新されたファイル、追加されたファイルが070110フォルダに
追加され、070110の中身が全て070111(明日)フォルダに移動されて、当日更新した
ファイルの、更新前の古いファイルのみが070110(今日)フォルダに残ります。
そして明後日実行した時に、070112フォルダが作成され、070111フォルダに
バックアップ元の更新されたファイル(差分)のみが追加され、070111の内容が全て
070112フォルダに移動され、明日更新したファイルの更新前の古いファイルのみが
070111(明日)フォルダに残ります。以後この繰り返しです。
ココの方が分かりやすいかも
http://www.vector.co.jp/magazine/softnews/030806/n0308062.html ちょっと説明が難しいですかね・・・私の口から言うよりサイトを見て頂いた方が分かりやすいかもです。
>>417 1はスクリプトの組み方しだい。
2は、いわば --move-dest みたいな機能があればいいのかね。
rsync ソースいじってみたら?
開発元に送ったら組み込んでくれるかもよ。
>>417 日本語メッセージは扱いにくいのでロケールをCにして英語メッセージにする
diff -rqの出力は3種類。DIR1だけにあるファイル、DIR2だけにあるファイル、両方にあって内容が異なるファイル。
2番めと3番めのパターンだけを抽出して、sedの正規表現で望む形式に変換
特に難しいことはない。あと数行足せばやりたいことが完結するはず
>>418 既に完成されたソフトウェア(pdumpfs)なので、それを改造するなんてそんなスキル
ありません。--move-dest とは?
http://www.google.com/search?num=50&hl=ja&safe=off&q=move-dest&lr=lang_ja rsyncのソースをいじるなんてとんでもない。C言語を少しかじった事がある程度ですよ?
そんな人間がそんな事してるときっと破壊するwwww
>>419 なるほど、それで
>>415 様がLANG=Cしてるのね。ちなみにsed使った事ありませんし、正規表現も全く知りませんので不可能です。
で、自分なりに書いてみたスクリプトがこれ!
backup.sh
#/bin/sh
kyou=`date '+%y%m%d'`
kinou=`date --date '1 days ago' '+%y%m%d'`
list=`date '+%y%m%d'-list`
mkdir -p /backup/$kyou
if test -d /backup/$kinou -a -e /backup/$kinou ; then
./list.sh >> ./$list
mv -f /backup/$kinou/* /backup/$kyou/
for targ in `cat ./$list` ; do mv /backup/$kyou/$targ /backup/$kinou/ ; done
rsync -av /data/ /backup/$kyou/
else
rsync -av /data/ /backup/$kyou/
fi
同じディレクトリ内に list.sh
#/bin/sh
LANG=C
DIR1="/data/"
DIR2="/backup/`date --date '1 days ago' '+%y%m%d'`"
diff -rq "${DIR1}" "${DIR2}" | while read i; do
echo $i | grep -e "^Only in $DIR2" | sed "s/^Only in \(.\+\): /\\1\//"
echo $i | grep -e "^Files" | sed "s/Files .\+ and \(.\+\) differ/\\1/"
done どうですか?(行数の制限で改行がきつい^^;)
>>420 pdumpfsの階層が深いとは自分も思う。
ので、それを改造した版を数年実運用しています。
ハードリンクの方もどうにかなるんじゃないかと。
[root@vine backupset]# ./backup.sh mv: ``/backup/070111//backup/070110/PineNet.txt'' を stat できません: そのようなファイルやディレクトリはありません となっちゃいました。あと少しで完成なのにっ 惜しい!!!! PineNet.txtだけを更新して、dateコマンドでシステムの日付を明日にして シェルスクリプトを実行してみたところ、その更新したファイルのファイル名はとれてる のですが、どうやらディレクトリ、フルパスが余計なようです?多分。。 恐れ入りますが、ファイル名だけを取得するにはどのように改良すればよろしいのでしょうか? もう少しで完成しそうなのでお付き合い頂けるとコレに勝る喜びはありません。
>>423 ありがとうございます!コレで完成!と思ったのですが・・・
[root@vine backupset]# ./backup.sh
mv: ``/backup/070111/070111-list'' を stat できません: そのようなファイルやディレクトリはありません
backup.sh
#/bin/sh
kyou=`date '+%y%m%d'`
kinou=`date --date '1 days ago' '+%y%m%d'`
list=`date '+%y%m%d'-list`
mkdir -p /backup/$kyou
if test -d /backup/$kinou -a -e /backup/$kinou ; then
./list.sh >> ./$list
basename ./$list > ./$list
mv -f /backup/$kinou/* /backup/$kyou/
for targ in `cat ./$list` ; do mv /backup/$kyou/$targ /backup/$kinou/ ; done
rsync -av /data/ /backup/$kyou/ >> ./$kyou-rsync.log
else
rsync -av /data/ /backup/$kyou/
fi
同じディレクトリ内に list.sh
#/bin/sh
LANG=C
DIR1="/data/"
DIR2="/backup/`date --date '1 days ago' '+%y%m%d'`"
diff -rq "${DIR1}" "${DIR2}" | while read i; do
echo $i | grep -e "^Only in $DIR2" | sed "s/^Only in \(.\+\): /\\1\//"
echo $i | grep -e "^Files" | sed "s/Files .\+ and \(.\+\) differ/\\1/"
done
もうちょぃ〜とで完成なんですが、何が悪いんでしょうか?よろしくお願い致します。
おっと、操作手順は まず backup.shを実行 これは正常に成功して、/backup/070110/ の中に /data/の内容がrsyncでフルコピー されました。 そして # date 011122052007 とかやって、明日の日付にシステムを変更しました。 さらに、/data/PineNet.txt ファイルを修正して上書き(つまり更新)しました。 その状態で # ./backup.sh を実行すると上記のようになりました。
>>424 なんかぐちゃぐちゃだな・・・
ちゃんと試してないから責任は持たんけどこんな感じだろ。
backup.sh:
#/bin/sh
DATADIR=/data
BACKUP_BASEDIR=/backup
KYOU=`date '+%y%m%d'`
KINOU=`date --date '1 days ago' '+%y%m%d'`
BACKUPDIR_KYOU=${BACKUP_BASEDIR}/${KYOU}
BACKUPDIR_KINOU=${BACKUP_BASEDIR}/${KINOU}
BACKUP_TMPTAR=${BACKUP_BASEDIR}/${KYOU}-tmp.tar
CWD=`pwd`
if [ -d ${BACKUPDIR_KYOU} ]; then
echo Backup directory for today ${BACKUPDIR_KYOU} already exists. Aborting.
exit -1
fi
if [ -d ${BACKUPDIR_KINOU} ]; then echo Saving changes from yesterday... mv -f ${BACKUPDIR_KINOU} ${BACKUPDIR_KYOU} mkdir -p ${BACKUPDIR_KINOU} rm -f ${BACKUP_TMPTAR} touch ${BACKUP_TMPTAR} cd ${DATADIR} ${CWD}/list.sh ${BACKUPDIR_KYOU} . | while read i; do tar uf ${BACKUP_TMPTAR} "$i" done cd ${BACKUPDIR_KINOU} tar xvf ${BACKUP_TMPTAR} cd ${CWD} rsync --delete -av ${DATADIR}/ ${BACKUPDIR_KYOU}/ >> ./${KYOU}-rsync.log else echo First-time to run the script. Making a full backup... mkdir -p ${BACKUPDIR_KYOU} rsync -av ${DATADIR}/ ${BACKUPDIR_KYOU}/ >> ./${KYOU}-rsync.log fi echo Done.
list.sh: #/bin/sh LANG=C if [ $# != 2 ]; then exit fi DIR1="$1" DIR2="$2" diff -rq "${DIR1}" "${DIR2}" | while read i; do echo $i | grep -e "^Only in $DIR2\:" | sed "s/^Only in \(.\+\): /\\1\//" echo $i | grep -e "^Files" | sed "s/Files .\+ and \(.\+\) differ/\\1/" done
>>426 rsyncは--deleteしない方がいい。でないと、削除されたファイルがどこにも残らない。
それか、削除されたファイルも前日のバックアップに含める方がいい。
技術のない奴程、ディレクトリが深いとか文句を言い、 技術のある奴程、あまりいじらず、そのまま想定された使い方をする
ちゃんとチェックしてないけどこんな感じ? `find ...` ってあふれるとマズいんだっけ。 #/bin/sh BACK=/backup KYOU=`date '+%y%m%d'` KINOU=`date --date '1 days ago' '+%y%m%d'` mkdir $BACK/$KYOU if [ ! -d $BACK/$KINOU ]; then rsync -v -a /data/ $BACK/$KYOU else rsync -v -a --link-dest=$BACK/$KINOU /data/ $BACK/$KYOU cd $BACK/$KINOU for i in `find . -type f`; do [ $i -ef ../$KYOU/$i ] && rm $i done for i in `find . -depth -type d`; do rmdir --ignore-fail-on-non-empty $i done fi
>>431 へえ、rsync --link-destってそうやって使うのか、勉強になった。俺の長いスクリプト無駄orz
Linuxのハードリンクの利点も生かせるし、無理に元の仕様にあわせずrsync --link-dest
そのまま使った方がいいな。検索したらそのままのがあった。
ttp://slashdot.jp/~ruto/journal/362588 for i in `find ...`はファイル名に空白があるときおかしくなるっぽい。
find ... | while read で回してるのはそのため。
>>432 あぁ、空白があったか。
このくらいなら find の -exec に押し込んじゃってもいいかも。
特殊ファイルのことを考えてないけど rsyncを使わずに素直に書いてみた。 #!/bin/bash src=${1%%/} dst=${2%%/} today=`date +%y%m%d` yesterday=`date -d 'yesterday' +%y%m%d` mkdir -p "$dst/$today" find "$src" -type f | while read i; do name=${i##$src} tn=$dst/$today$name yn=$dst/$yesterday$name td=`dirname "$tn"` if [ ! -e "$td" ]; then mkdir -p "$td" fi if [ ! -e "$yn" ]; then cp -p "$i" "$tn" elif [ "$i" -nt "$yn" ]; then cp -p "$i" "$tn" else mv "$yn" "$tn" fi done
436 :
424 :2007/01/11(木) 22:00:07 ID:qzcPBdsk
>>426 初めてシェルスクリプトと言うのをほとんど無学で書いたので、そりゃーぐちゃぐちゃですよ。
可能な限りトレースしてみましたが、
if [ -d ${BACKUPDIR_KYOU} ]; then
echo Backup directory for today ${BACKUPDIR_KYOU} already exists. Aborting.
exit -1
で、1日2回以上実行した場合は最新に更新しないんですね。1日に1回しか実行できないと。
それより1日に何回でも実行できますが(基本的には1日に1回しか実行しないけど)、
その実行をするたびに/dataディレクトリの状態を${KYOU}ディレクトリへ反映した方がいいかな。
${CWD}/list.sh ${BACKUPDIR_KYOU} . | while read i; do
ここらへんも良く分からないOTL。
>>429 そうですそうです。前日のバックアップディレクトリに含めるんです。
>>430 お恥ずかしい限りです。精進します・・・
>>431 >>434 もう全然分からないOTL
>>435 そのコマンド一発で一気に出来てくれると助かりますねぇ。
しかし開発元に投げるって、そんな事したことが無くて全然投げ方とか分かりません。
それに英語で書く必要があるんですよねえ。英語できなくて・・・。
もっとシェルスクリプトの書き方、各コマンドを知るって事をしないとダメですね。
$kyou とか私は記述していますが、 ${KYOU}のように皆さんは記述されていますね。
{ } で囲んだ方が見やすいとは思いますが、大文字にしないといけないのでしょうか?
しなくてもいいなら ${kyou}でもいいと思うのですが、見易さの観点から大文字ですか?
>>436 たとえば $kyou の直後に空白を入れず x と表示したいときに
echo ${kyou}x と書かなきゃいけない。
変数名を大文字にするのは、まぁ、慣習だ。
だれでも最初ははじめてだよ。
>>436 > それより1日に何回でも実行できますが(基本的には1日に1回しか実行しないけど)、
> その実行をするたびに/dataディレクトリの状態を${KYOU}ディレクトリへ反映した方がいいかな。
そうなるとだいぶ話が変わってくるな。
からっぽのディレクトリを作ってそこにコピーするのと
内容が入ってるディレクトリを更新するのとでは
やり方はかなり違う。
そういう仕様は先に言ってほしい。
>
>>431 >>434 > もう全然分からないOTL
どこがわからない?
だから素直に pdumpfs を改造すれば良いのに。
440 :
424 :2007/01/12(金) 00:33:12 ID:LG5Wdg1W
>>437 なるほどなるほど、って事はこれからは${KYOU}って書きますね〜ありがとうございます。
>>438 http://hp.vector.co.jp/authors/VA004777/fabre.html ぶっちゃけこのソフトと同じ動きをしようと思っているんですが・・・
私一人の力ではsedとか正規表現とか分からなくて、アルゴリズムもそんなに強くないので
協力をお願いしています。仕様・・ん〜・・このサイト見ても詳しい事は分からないのかな・・
分からないところは聞いて教えてもらうようなところではないほど基本的なところなので
自分で学びます。具体的にはrmdirのオプションとかrsyncの--link-destの動きとか・・・。
で、
name=${i##$src}
src=${1%%/}
dst=${2%%/}
↑これは教えていただけませんかねぇ・・・調べにくそうなので・・
ん〜細かいところ分からないところ多いですが、もっとシェルスクリプトを学んでから
質問しないと皆様に悪いです。あまりにも私のレベルが低すぎるので。それも聞かなくても
自分で解決できるところも多々あります。時間を見つけて学びます。
C言語のfor文やif文、while文とは勝手が違って困惑しております^^;
基本的なコマンドをまずは知り尽くさないとダメですね。
シェルが分かったらLinuxに明るくなれそうな気がしたもので・・・。
ただ専門学校の勉強(情報専門学校ですw)もあって時間がなかなか微妙なので
まとまった時間が欲しい〜。資格試験の勉強とかでシェルスクリプトの勉強する時間が・・
>>440 > name=${i##$src}
> src=${1%%/}
> dst=${2%%/}
man bash で ## とか %% で検索すれば出てくるよ。
具体的には Parameter Expansion のとこ。
身の上話には興味ありません。
学生ほどまとまった時間がとれる身分はないのにみすみす逃すとは何ぞな
>>436 >それより1日に何回でも実行できますが(基本的には1日に1回しか実行しないけど)、
>その実行をするたびに/dataディレクトリの状態を${KYOU}ディレクトリへ反映した方がいいかな。
それをすると例えば、今日の1回目と2回目の実行の間に削除されたファイルは
${KINOU}にも${KYOU}にも残らなくなる。いくつかシナリオ考えてみるといい。
一日一フォルダの仕様をやめれば自然に解決できるけど。
Fabreっていうソフトで一日に複数回バックアップを実行するとどうなるの?
444 :
login:Penguin :2007/01/12(金) 01:34:25 ID:U4rFYhBs
シェルスクリプトの中でsedで置換したファイルを作成したいんだけど、 #!/bin/sh sed -e "s/abc/ABC/" testfile > testfile1 こうしてもtestfile1の内容はtestfileのままになってしまいます。 プロンプトから実行すればうまくいくのですが。。 解決策おしえてください。
446 :
444 :2007/01/12(金) 02:02:45 ID:U4rFYhBs
うーん。自己レスします。何故かRedhat9だと普通にできて ES3だとできない。
>>444 なんかの環境変数が違うのかな。
それかカレントディレクトリが違うとか。
まさか改行コードとか
449 :
424 :2007/01/12(金) 03:25:37 ID:LG5Wdg1W
>>441 教えてくださりありがとうございます、読んでみます。
>>442 うちの専門学校は忙しいんですよ。
>>443 Fabreで1日に複数回実行した場合は・・・
まず1回目実行した場合は
070112A
というフォルダが作成されて、フルバックアップ
次は 070113A 070114A と言う風になるのですが
1日に複数実行すると
070113A 070113B 070113C のようにアルファベットがドンドンついていきます。
このアルファベットは分かりにくいし1日のバックアップをそんなに残す必要は無いので
やめて、070113フォルダを最新に更新し続けるって事でいきたいなと。
>>449 >1日に複数実行すると
>070113A 070113B 070113C のようにアルファベットがドンドンついていきます。
そうなってる理由の一つが
>>443 なんだろう。元の作者は考えて作ってるんだから、
そこだけ勝手に変えたら破綻するだけ。
なぜ破綻するかはシェルプログラミングの問題じゃなく設計の問題。
仕様を先に決めろと言われてるのはそういうことだ。
451 :
424 :2007/01/12(金) 08:09:02 ID:LG5Wdg1W
>>450 なるほど。
学校でも設計やりますが、ぶっちゃけ仕様書を書くより先にプログラムを作って
それから仕様書を書きたくなりますが、そうじゃなくてしっかり仕様を決めて、それから
って事ですか・・。
と言う事はつまり、やっぱりA、B、Cと作っていかないと1日のうちに削除されたファイルが
バックアップするのを日をまたげば残されますが、日をまたがずに複数回バックアップした
場合に消滅しちゃうって事ですね・・・。しかし日付を取得するだけでも精一杯なのに
順番にA B Cと取得って・・・
for targ in A B C D E F G ・・・ Z ; do hogehoge ;
ってやるんですかねぇ・・・
452 :
424 :2007/01/12(金) 08:14:11 ID:LG5Wdg1W
書き忘れましたが、もう1つ勝手に変えてるところがあります。 Fabreではバックアップする際、ディレクトリ構造ごとバックアップします。 つまり/data/foo/var/hoge/hoge.xls が更新された場合は /backup/foo/var/hoge/hoge.xlsと保存されると言う事ですが 私が書いたシェルスクリプトだと /backup/hoge.xls とディレクトリ構造が消滅します。まぁ単純にディレクトリ構造を保持する方法が 分からなかったのと、ディレクトリまで掘らなくてもいいんじゃない?と 思ったからなんですが・・・。 それから、WindowsXPのデフォルト設定だとファイルを「更新してない」のに 開くだけで更新日付が変わってしまい、内容が同じなのにタイムスタンプが違う というだけでバックアップ対象に含まれちゃうんですが、Fabreではこういうことが おきないみたいです。この辺のこともどういうアルゴリズムなのか分かる方 いらっしゃいますか?
>>451 一日に26回以上実行したらどうすんの?
>>452 >ディレクトリまで掘らなくてもいいんじゃない?
バックアップ対象に同名のファイルが複数あったらどうすんの?
>Fabreではこういうことがおきない
タイムスタンプでなく内容を比較してるのでは?知らんけど。
他の人が貼ってるやつで十分動くから、実用に使いたいだけならそれ使えば?
勉強のためにやってるならいいトレーニングになるかもね。
>>453 Z→AAだろ。
なんにせよ、発想もやり取りも場当たり的だね。破綻するよ。
バックアップは確実に取れてなんぼ。
CVS とかその手のやつの方が要求満たしたりしないかな。 アリモノを上手く使う方法を考えた方がいいよ。 スキルないのにいろいろやりすぎ。
そうそう。 ディレクトリの階層が深いと言われているけど、それも理由があるよ。 毎回のバックアップディレクトリが全て同じ階層に並んだら 後々、色々と面倒なことが起こるんだよ。
>>456 なんか Fabre とやらを見てみたけど、どうなの?
最新のバックアップフォルダが消えたらほぼ全滅じゃん。
いますごい自演を見た
? どこがどう自演なのかさっぱり
自作自演というより、多重人格だなw
459は、456なのかな、457なのかな。 精神科医さん、よろしく診断おながいします。
462 :
424 :2007/01/12(金) 16:35:41 ID:LG5Wdg1W
>>453 >一日に26回以上実行したらどうすんの?
はっ! と思ったけど
>>454 がZ→AAでなるほどっ!と思ったw。
っていうか一日にそんなにたくさん実行しないと思いますけど・・・。
>バックアップ対象に同名のファイルが複数あったらどうすんの?
すっかり抜けていました。確かに、同名のファイルが他のディレクトリにあった場合は
おかしくなりますね、下手したら上書き。片方消えちゃいますね。。。あちゃー
だからFabreは階層も保存対象なんだ・・・。なるほどなるほど。抜けだらけですね。
>タイムスタンプでなく内容を比較してるのでは?知らんけど。
内容を比較する事はdiffコマンドで出来ますか?
>他の人が貼ってるやつで十分動くから
どれが一番いいですかねぇ・・・ぶっちゃけ完璧にトレースする事が出来ないので
どれを選んでいいか分からないです・・・。まぁ勉強のためでもありますけど、
とりあえずは動く事が急務かな・・・。
>>456 >後々、色々と面倒なことが起こるんだよ。
面倒な事とは?少し具体的な例をあげて教えていただけ無いでしょうか?
その場合はバックアップ元に最新の全データが残っているので大丈夫です。
しかしバックアップ元と最新のバックアップフォルダの両方が同時に消えるって事は・・・
そうそうないと思うんですが・・・それを言ったらミラーリングだって同時に消えたら?
って事になるわけで・・・。
とりあえず皆様の話から
1.階層を省いてバックアップは不可能、階層付でバックアップする
2.一日に複数回実行した場合はバックアップ先の${KYOU}のディレクトリを最新に更新する
つまり1日に複数回実行した場合、その日のうちに更新したファイルは残らない事になるけど
ぶっちゃけそこまで細かい単位で残す必要は無い(1日単位で十分)ので。
となると、1個問題が・・・ list.shで出力されるファイルリストからファイル名の部分を除いた
そのファイルまでのパスのみを抜き出したtempファイルも出力して
# mkdir ${temp}
を実行しないといけませんよねぇ・・・。となるとまだsedとか正規表現が・・・分からないOTL
463 :
424 :2007/01/12(金) 16:38:37 ID:LG5Wdg1W
>>462 の
>その場合はバックアップ元に最新の全データが残っているので大丈夫です。
以下は
>>457 の
>最新のバックアップフォルダが消えたらほぼ全滅じゃん。
へのレスです。抜けてましたすみません。
自演の意味が分かった。アンカーミスくらいスルーしてくれ。
>>462 一つのディレクトリに大量のファイル・ディレクトリがあると
ファイルシステムにもよるが、パフォーマンスがすこぶる悪くなる。
それと、スクリプトで * なんて指定しようものなら、
引数が長過ぎって怒られることもしばしば。
cugwin の方が顕著に起こるね。
また、バックアップディレクトリとオリジナルが同時に消えても
pdumpfs なんかだと大丈夫でしょ。
465 :
424 :2007/01/12(金) 18:23:13 ID:LG5Wdg1W
>>464 なるほど・・・そういう理由があるんですか・・・
でもそれはLinux系OSを使う場合ですかねぇ?
私がバックアップするファイルはWindowsのファイルなんですが、
LinuxのSambaで
backup data の二つを見えるように設定して
backupはSambaからだとRead Only。dataは自由に書き換えてOK
Windows版のrsyncでバックアップしてもいいし、"ばっちり同期"っていうソフトを使って
バックアップしてもいいし、とにかくWindows側からLinuxのSambaサーバに毎日
自動的にdata ディレクトリと同期を取る。
後はLinuxサーバが自動的にdataディレクトリの中をbackupディレクトリへ
毎日差分で保存していくと。そういう使い方をしますが、それでも、やっぱりパフォーマンスが
すこぶる悪くなるんですかねぇ。
ディレクトリ内で「rm *」と入力すると「rm: `.' や `..' は削除でき ません」と表示されるんだけど、表示させないようにするにはどうすればいい?
467 :
424 :2007/01/14(日) 04:09:06 ID:xucnhoE2
>>466 # rm -rf *
って実行したらそれ表示されないけど・・・・
# rm -rf / じゃないの?
469 :
424 :2007/01/14(日) 04:44:18 ID:xucnhoE2
シェルスクリプトって、C言語のfor文みたいな命令は無いのですか? 例えば、ある一連の処理を50回実行したいとかいった場合に for(i=0;i<50;i++){ 一連の処理 } と言う具合に出来ないでしょうか?
471 :
424 :2007/01/14(日) 05:35:44 ID:xucnhoE2
>>470 ありがとうございます。
#/bin/sh
for i in `seq 1 100`;
do
/root/backup.sh
date --set '1day';
done
で、出来ました。1日に1回実行するから、最初は1日ずらしてはbackup.shを
実行していたのですが、手間がわずらわしくなって、シェルスクリプトでこれも
やっちゃえるんじゃない?とか思ったので。
シェルスクリプトって凄いですね。これ人間の手で手動で100回やってたら
途方も無い労力・・・・
>>469 for ((i=0;i<10;i++)); do echo $i; done;
がつかえる。
473 :
424 :2007/01/14(日) 12:40:25 ID:xucnhoE2
>>472 おおお!まさにこれ!こっちの方がC言語しか知らない私にはあってます!
ありがとうございます。
ところで、最後の done の後には ; はいらないんじゃ?無くても動きましたよ。
こういう風にした方がseqコマンドに依存しないんだ・・・
でも bash 依存なので、#!/bin/sh じゃなくて #!/bin/bash と書こうね。
475 :
424 :2007/01/14(日) 12:44:40 ID:xucnhoE2
>>474 いや、#/bin/sh で動作しましたよ
って書こうと思ったけど
/bin/sh は /bin/bashへのシンボリックリンクでした。なるほどです。
476 :
424 :2007/01/14(日) 13:57:05 ID:xucnhoE2
家の掃除が面倒です。毎回決まった作業をします。 シェルスクリプトで出来ませんか?
>>476 #!/bin/bash
rm -rf ~
これを毎日cronで回せばいい。
478 :
424 :2007/01/14(日) 14:20:44 ID:xucnhoE2
>>477 wwww
家→homeディレクトリ
だからhomeの掃除→homeディレクトリ内のファイルを全削除
だからそうなるのか・・・w いや、冗談に付き合ってくれてありがとうw
481 :
424 :2007/01/14(日) 20:24:17 ID:xucnhoE2
C言語しか知らない私
483 :
424 :2007/01/14(日) 21:45:06 ID:xucnhoE2
>>482 面白い事を言っているのかもしれませんが、ネタの意味が分かりません。
なので笑えません。申し訳ない。
カスが
485 :
login:Penguin :2007/01/18(木) 07:40:47 ID:TIv0wXG8
Fedoraを使用してシェルの勉強をしています 文字列関連でわからないところがあり 行き止まってしまいましたのでお力を貸していただけないでしょうか 質問なのですが testディレクトリの中に存在しているファイルの名前をExistenceFile.txt に吐き出してあげようと思っています testディレクトリにある多くのファイル名は 「xxxxx ffffff rrrrrr」 というように半角スペースが所々に入ってしまっております その状態で下記を実行しますと #!/bin/sh FILE=`find /test -typef` for I in $FILE do FILE_NAME=`basename "$I"` echo $FILE_NAME >> ExistenceFile.txt done 結果が 20060712 backup file 等とスペースがあるところで改行されてしまいます これを 改行なしで1行でExistenceFile.txtに吐き出す方法はありませんでしょうか
find /test -type f | while read I; do
>>485 find /test -type f -printf '%f\n' >>ExistenceFile.txt
488 :
login:Penguin :2007/01/18(木) 08:15:38 ID:TIv0wXG8
ありがとうございます findの後にいろいろつけたらいけそうな気がしてきました
>>487 findの -printf ってすげぇ便利だね。
初めて知った。
xxxx from xxx.xxx.xxx.xx(xxxはIP) hoge tcp/ip とかこんなのがたくさん書かれてあるファイルがあります。 その中から xxx.xxx.xxx.xxのIPの部分だけを抽出したいのですが それをやるにはsedでどのようにすればよいのでしょうか? 1レコードずつ取り出してfor文で回して処理したいのです。
>>490 sed でのやり方はわからないけど
awk 使うと簡単だと思う。
sed -e 's/^.*from //g'
grep -o -P '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}' GNU grep 限定。 範囲チェックはしてない。
マルチに答える奴かっこわるい
マルチじゃないですよ。
はわわ〜
いやそっちのマルチじゃなくって。 ダウンを5名勧誘すると 問屋になれてダウンの売り上げの18%が 懐に入るようになるやつの方。
>>497 他人のボケを潰してまで言いたいボケかね。
UNIX板の方から来ました。
797 :名無しさん@お腹いっぱい。 :sage :2007/01/29(月) 14:38:20
若干スレ違い気味な気もしますが
(p)
ttp://x68000.q-e-d.net/~68user/unix/pickup?iconv > 入力ファイルに無効な文字 (-f で指定した文字コードと矛盾するようなデータ) が
> 含まれていた場合、iconv はエラーとして終了する。FreeBSD の iconv では
> -c オプションを指定することで、無効な文字を無視して無視して続行することができる。
> 他の iconv では必ずエラーで終了してしまうようだ。
Linux で、変な文字を無視しつつ文字コードの変換をしたいときにはどうするのがベストでしょうか。
(個人的に馴染のある言語の) php で iconv//IGNORE をする、という手は思いついたのですが。
これ、相談させてください。
とりあえず今は
~/php/bin/php -r 'while (($line = fgets(STDIN)) != NULL) { echo iconv("Shift_JIS", "UTF-8", $line); } '
としてしのぎました。
>>499 Linux の iconv にも -c あるみたいだけど
それじゃだめなん?
うわまじだ、できました。 man iconv だけ見て実際に試してませんでした。 お騒がせしました。
502 :
login:Penguin :2007/02/01(木) 10:23:06 ID:c0AyEF+O
ある空のディレクトリを複数用意してそこにユーザが自由にユーザが ファイルをUPするとします。ファイルが何も入っていないディレクトリを 抽出するようなスクリプトを作りたいのですが、 if [ ! -f /TESTDIR/* ];then こんな感じで書いていたら最初はうまくいってたのですがファイル数が 多くなったらtoo many arg...のエラーでてうまくいかなりました。 何か良い方法ありますか?
>>502 find /TESTDIR -maxdepth 0 -type d -empty
>>503 ちょっと違うか。
でもまぁ、find で空ディレクトリ一覧は出せるよ。
空のディレクトリのみ削除したいなら
いきなり rmdir しちゃうとか。
>>502 > if [ ! -f /TESTDIR/* ];then
これだと /TESTDIR/.test なんてファイルがあったらだめだな。
506 :
502 :2007/02/01(木) 13:37:30 ID:c0AyEF+O
>>505 そうでした。うかつです。
>>503 -maxdepth 0をつけるとなぜかファイルが入ってるディレクトリも
抽出されたのでfindで出来るというレスをヒントに
find /TESTDIR -type d -empty
で一見うまくいってるかも?です。少し様子見します。
ありがとうございます。
507 :
502 :2007/02/01(木) 13:53:02 ID:c0AyEF+O
と、思ったら失敗しました。 TESTDIRの下にディレクトリa,b,c,d...と初期にこちらで用意した ディレクトリがありその初期ディレクトリで空のもののみを抽出した かったのですが、ディレクトリaの下に通常のファイルの他に 空ディレクトリとか作られると find /TESTDIR -type d -empty でやるとディレクトリaの下の空ディレクトリも抽出されてしまいます。。
508 :
502 :2007/02/01(木) 14:48:33 ID:c0AyEF+O
自己レス find /TESTDIR -maxdepth 1 -type -d でうまくいきました。ありがとうございました。
find /TESTDIR -prune -type d -empty
du
>>510 多分だめ(な場合がある)だろ。
LinuxのFS(たとえばext3)って、ファイルがないディレクトリのサイズは「必ず」0なのか?
他のUNIXでよくあるのは、いっぱいファイルを作った(当然ディレクトリのサイズ増大)後で、
ファイルを全部削除しても、ディレクトリ自体はすぐにはtruncateされない場合がある
ってな実装戦略なんだが。(この戦略は決してサボリじゃなく合理的理由がある)
512 :
511 :2007/02/01(木) 23:56:02 ID:ZVcHJobk
>>511 みたいな複雑なケース以前にもっと単純に...
>>510 duだと、サイズ0のファイルが存在しても、それはないものとして数えられちゃうよね。
やっぱduのようにサイズを計るツールでファイル数を計るのは無理あるんじゃね?
find でやるのが正解だと思うけれど ls -A も使える。 for dir in /TESTDIR/*/ /TESTDIR/.*/ ; do count=`ls -A "$dir" | wc -l` ; if [ $count -eq 0 ] ; then echo "$dir": empty ; fi ; done /TESTDIR/.*/ だと /TESTDIR/. と /TESTDIR/.. もマッチしちゃうけど。
duで最小サイズのディレクトリを見付けfindする。
hogeを5秒後に起動したい #!/usr/bin/sh sleep 5 && hoge
>>515 誤爆か?
3分後にカップラーメンを食べたい
#!/usr/bin/sh
sleep 3m && play /usr/share/sounds/login.wav
じゃあこれでいい? 3秒後にhogeを起動したい #!/usr/bin/sh sleep 3s && /usr/bin/hoge
お前らatを知らんのか。
atは許可されないと使えないわけだが。
atd 動いてないかもしんないし。
指定した時刻に電源がオンになるようなのはできますか?
シェルスクリプトで、という意味? 普通はbiosとかの役割だと思うけど。
>>521 Wake On Ringコネクタにキッチンタイマーをつなげ。
つ nvram-wakeup これで次起きたい時刻をセットしてマシン落とせば(もしくはサスペンドすれば)おけ。
525 :
login:Penguin :2007/02/12(月) 13:31:38 ID:SMeHWOZn
7za x * というふうに*(ワイルドカード)が使用できないので なんとかスクリプトで出来ないかとやってみたがダメ。 今いるディレクトリにある.7zすべてを展開したいけど なして? #!/bin/bash for i in $* do 7za x $i done $ ./7za.sh '*.7z' Incorrect command line
シングルクオートで括ってるから?
だな
528 :
login:Penguin :2007/02/14(水) 21:07:43 ID:kfyu3aZW
シェルスクリプトの練習のために、ftpでrsyncの様な事をする(つもりの)ものを書いてみました。 添削、助言などいただけると嬉しいです。定数定義等は省略してあります。 SERVER_FILE_LIST=$( ftp -n "${SERVER_ADRESS}" << END 2>>${LOGFILE_NAME} user ${FTP_USERNAME} ${FTP_PASSWORD} cd ${SERVER_DIR} ls -l END ) SERVER_FILE_LIST=$(echo "${SERVER_FILE_LIST}"| awk '{print $9}') UPFILE_LIST=$( ls -1 |sed "/^${LOGFILE_NAME}$/d" ) for SERVER_FILE in ${SERVER_FILE_LIST} do UPFILE_LIST=$(echo "${UPFILE_LIST}" |sed "/^${SERVER_FILE}$/d" ) done for UPFILE in ${UPFILE_LIST} do ftp -i -v -n ${SERVER_ADRESS} << END >>${LOGFILE_NAME} user ${FTP_USERNAME} ${FTP_PASSWORD} cd ${SERVER_DIR} bin put ${UPFILE} quit END done
ようつべよりぐぐるの動画を……
なんかちょっとgoogleっぽいIDが出た。
GUIが好きならDemocracyPlayerオススメ。
534 :
528 :2007/02/15(木) 12:45:31 ID:w0BybIhd
タイムスタンプファイルサイズも比較しないレベルの低いのはヌルーっすかwww 変なことは書いていないと肯定的に考えるべきか…
つーか読むのめんどい。 多少汚くても 自分がやりたいことが実現できてるなら それでいいんじゃね? どっかわからない・うまく動かないとこがあるなら言ってよ。
536 :
528 :2007/02/15(木) 14:19:37 ID:w0BybIhd
>>535 それはそうですね。一応、使えてるのでOKかも。
mputがうまくいかなかった理由(ファイル名を”で囲う)がわかったのでforも一個減らせたし。
さて次はタイプスタンプでも取得するか。
du -a /usr/local/bin | gawk '{printf "%s\n", $0}' コマンドラインから 動作。 ファイルに書いて、ファイルを実行すると gawkで gawk: cmd. line:1: {printf "%s\n", $0} ' in expression:1: ^ invalid char ' エロ意人おしえてください
538 :
528 :2007/02/15(木) 15:06:03 ID:w0BybIhd
printf("%s\n",$0) にしてみるとか
>>538 >>539 レスさんきゅ。
gawk: cmd. line:1: printf ("%s\n", $0)
' in expression:1: ^ invalid char '
いやぁ、動作しないのがおかしいんだけどね・・・。
おかしいなぁ。
いい忘れたが
元はといえば、Solaris HPで動作したシェルスクリプトがまったく動作しない。
ソラリス、HP:OK
CentOS4.4:NG
541 :
540 :2007/02/15(木) 16:24:13 ID:1HhpQr6V
自分のCentOS4.4では 動作しないが 実際動作させる環境(RHEL)で動作したから、クローズです。 gawk awkが違うってことだな。
たぶん改行コードが腐ってる。awk のせいではない。
シェルが腐ってて''の中の\nを解釈しちゃうのかね。
違う。改行コードが CR+LF になっているので、awk の引数が {....} ではなく {.....}CR になって構文エラーになる。
YouTubeとかGreasemonkeyで良いじゃんって思うんだけど w3mで見れないし
初めてのシェルスクリプトです。自信ないけど見てください。
mktempで作成した一時ファイルは削除した方がいいのでしょうか。エラー処理とかよくわかりません。
使用例
echo '
http://shupoxxx.2.dtiblog.com/?page=0 ' | ./urlcollector.sh '/\?page=[0-2]' | grep 'jpg$'
#!/bin/sh
# urlcollector.sh
REGEX=$1
TMPFILE=`mktemp /tmp/urlcollector.sh.XXXXXX`
DL_FILE=`mktemp /tmp/urlcollector.sh.XXXXXX`
download() {
while read LINE; do
if grep `echo "$LINE" | sed -e 's/?/\\\\?/'` $DL_FILE; then
:
else
echo "DEBUG:$LINE" 1>&2
echo "$LINE" >> $DL_FILE
lynx -dump -image_links "$LINE" | grep -o '
http://.*$ ' |
tee -a $TMPFILE | grep -E "$REGEX" | download
fi
done
}
download # let's do it!
cat $TMPFILE | sort -u
エラー処理は set -e trap '...終了時の掃除処理...' 0 1 2 3 14 15 あたりを冒頭にかくよろし。
>>547 urlcollector.sh: line 1: ...終了時の掃除処理...: command not found
trap 'echo ...終了時の掃除処理...' 0 1 2 3 14 15
>>546 それだと相対パスのリンク取れないけどそれでいいならいいか。
俺なら手抜きでこうやる。
URL=
http://hogehoge.jp wget -nv -nd -r -w1 --delete-after $URL 2>&1 | awk '{sub("^URL:","",$2); print $2;}'
if文で「(AかつB)またはC」を条件にしたい時 if [ ( A -a B ) -o C ] という構文は 解釈してくれないようなのですが、どのように 表現したらいいのでしょうか? とりあえず if [ A -a B ] ; then ... elif [ C ] ; then ...(同じコマンド) としているのですが・・・。
>>550 if [ A -o C ]; then
if [ B -o C ]; then
...
fi
fi
>>550 解釈する。
ただし、ほとんど全てのシェルで括弧はサブシェルを意味するから、
if [ \( A -a B \) -o C ]; then
と書く必要があるよねえ。
553 :
550 :2007/02/28(水) 19:31:48 ID:KugGv7KW
554 :
login:Penguin :2007/03/01(木) 20:53:35 ID:7aN7LiNz
pingを使用し実行結果によって失敗した場合"NG"の文字が書き込まれるスクリプトを作りたいと思ってます。 どのように作ったらいいでしょうか?お願いします。
555 :
login:Penguin :2007/03/01(木) 22:52:27 ID:08JSMW9W
仮に192.168.0.1があるとする ping -c 2 192.168.0.1 | grep error | awk '{print $7}' 無表示 192.168.0.2はないので ping -c 2 192.168.0.2 | grep error | awk '{print $7}' error← これがでる あとはGoogle先生に聞いてみ
556 :
login:Penguin :2007/03/01(木) 23:00:23 ID:7aN7LiNz
>>554 if ping -c 1 -q 192.168.0.1 > /dev/null
then
echo OK
else
echo NG
fi
558 :
login:Penguin :2007/03/02(金) 00:13:15 ID:eLbGjXrV
559 :
login:Penguin :2007/03/02(金) 00:56:16 ID:mhRNhPgc
var/log/messagesを以下のように整形したいんだけどどうしたらいい? *************************** Mar 1 01:20:24 SrvName messages1 Mar 1 01:20:24 SrvName messages1 messages2 messages3 messages Mar 1 02:32:26 SrvName messages1 messages2 *************************** ↓ *************************** "Mar","1","01:20:24","SrvName","messages1" "Mar","1","01:20:24","SrvName","messages1 messages2 messages3 messages4" "Mar","1","02:32:26","SrvName","messages1 messages2" *************************** messages部分のスペース区切りの個数が不定で堂処理していいかわかんね
messageが、5列目から行末まででひとつ、というように決まっていたらawkで簡単にできる希ガス。 そこが変化するとしたら、多少難しくなるけど。
562 :
560 :2007/03/02(金) 01:51:37 ID:eENYHLYp
>messageが、5列目から行末まででひとつ、というように決まっていたらawkで簡単にできる希ガス。 それ教えて欲しい
sedだけじゃだめか…
perl -lane 'print "\"@F[0]\" \"@F[1]\" \"@F[2]\" \"@F[3]\" \"@F[4..$#F]\""' /var/log/messages
こっちの方が簡単か perl -pe 's/^(.+?)\s(.+?)\s(.+?)\s(.+)$/"$1" "$2" "$3" "$4"/' /var/log/messages sedって最小マッチないの?
sed -e 's/\([^ ][^ ]*\)/\"\1\",/g' -e 's/,$//'
awk '{printf("\"%s\",\"%s\",\"%s\",\"%s\",\"",$1,$2,$3,$4)}{for (n=5;n!=NF;n++){printf("%s ",$n)}}{printf("%s\"\n",$NF)}' /var/log/messages
perl -ne 'chomp;print join(",",map{"\"".$_."\""}split(/\s+/, $_, 4)),"\n"' ruby -ne 'chomp;print $_.split(/\s/,4).map!{|i|"\""+i+"\""}.join(","), "\n"'
ぜんぜん関係無いけど もれクォーテーション1つ抜けてでアワワアワワしちゃうんだよなww 上のスクリプト見てると神にみえるww
クォートとエスケープはいつもなやましいよなぁ。 実際上のいくつかでも、messageに"だの'だの入ってたらどうしようとか、 "",区切りにしてエスケープどうなってんだとか、悩みどころはあったりw
571 :
560 :2007/03/03(土) 00:14:45 ID:iiaDHPL3
遅くなりましたが結局こうする事にしました。
CSVの規約に従うため「"」エスケープ⇒行頭に「"」追加⇒行末に「"」追加⇒項目1と項目2の間の「 」に「","」
追加⇒項目2と項目3の間の「 」に「","」追加⇒項目3と項目4の間に「","」追加⇒項目4と
項目5の間に「","」追加
sed -e 's/"/""/' -e 's/^/"/' -e 's/$/"/' -e 's/ /"\,"/' -e 's/ /"\,"/' -e 's//"\,"/' -e 's/ /"\,"/'
>>567 の人のスクリプトに似てるのかな?
どうもありがとう
サーバ・ユーザごとのログインログアウト履歴を作りたいんだけどどうしたら良いだろう 整形前 日付,サーバ名,ユーザ名、ログイン時刻、ログアウト時刻、区分 ********************************************************** "2007/02/16","SrvName1","USER1","2007/02/16 00:10:00","",1 "2007/02/16","SrvName1","USER2","2007/02/16 00:20:00","",1 "2007/02/16","SrvName1","USER1","","2007/02/16 01:00:00",6 "2007/02/16","SrvName1","USER3","","2007/02/16 01:20:00",6 "2007/02/16","SrvName2","USER1","2007/02/16 00:10:00","",1 "2007/02/16","SrvName2","USER1","","2007/02/16 00:20:00",6 "2007/02/16","SrvName2","USER1","2007/02/16 01:00:00","",1 "2007/02/16","SrvName2","USER1","","2007/02/16 01:10:00",6 ********************************************************** 区分「1」はログイン、「6」はログアウト 整形後 日付,サーバ名,ユーザ名、ログイン時刻、ログアウト時刻 ********************************************************** "2007/02/16","SrvName1","USER1","2007/02/16 00:10:00","2007/02/16 01:00:00" "2007/02/16","SrvName1","USER2","2007/02/16 00:20:00","" "2007/02/16","SrvName1","USER3","","2007/02/16 01:20:00" "2007/02/16","SrvName2","USER1","2007/02/16 00:10:00","2007/02/16 01:10:00" **********************************************************
>>572 続き
1行目 SrvName1,USER1は「ログイン、ログアウトともにある」ので全ての項目があり
2行目 SrvName1,USER2は「ログインのみ」なのでログアウト時刻なし
3行目 SrvName1,USER3は「ログアウトのみ」なのでログイン時刻なし
4行目 SrvName2,USER1は複数回のログインログアウトなので一番早いログインをログイン
時刻、一番遅いログアウトをログアウト時刻
複数回のログインログアウト時の「ログインのみ」「ログインログアウトともにあり」
「ログアウトのみ」の考え方は
ログイン回数>ログアウト回数⇒「ログインのみ」
ログイン回数=ログアウト回数⇒「ログインログアウトともにあり」
ログイン回数<ログアウト回数⇒「ログアウトのみ」
あ、あと「サーバ名」、「ユーザ名」は事前にはわからない(整形前のデータから持って
くる)という前提
これをBourne sh(awk,sed)でやりたいんだけどどうすれば良いと思う?
>>573 続き
考え方としては
1.サーバ名,ユーザ名、ログイン時刻、ログアウト時刻でソート
**********************************************************
"2007/02/16","SrvName1","USER1","2007/02/16 00:10:00","",1
"2007/02/16","SrvName1","USER2","2007/02/16 00:20:00","",1
"2007/02/16","SrvName1","USER1","","2007/02/16 01:00:00",6
"2007/02/16","SrvName1","USER3","","2007/02/16 01:20:00",6
"2007/02/16","SrvName2","USER1","2007/02/16 00:10:00","",1
"2007/02/16","SrvName2","USER1","2007/02/16 01:00:00","",1
"2007/02/16","SrvName2","USER1","","2007/02/16 00:20:00",6
"2007/02/16","SrvName2","USER1","","2007/02/16 01:10:00",6
**********************************************************
2.サーバ・ユーザ一覧の作成(SQLのDISTINCTのイメージ)して
サーバ名,ユーザ名
**********************************************************
"SrvName1","USER1"
"SrvName1","USER2"
"SrvName1","USER3"
"SrvName2","USER1"
**********************************************************
>>574 続き
3.サーバ・ユーザごとの単位でログイン回数の取得、ログアウト回数の取得
サーバ名,ユーザ名、ログイン回数、ログアウト回数
**********************************************************
"SrvName1","USER1",1,1
"SrvName1","USER2",1,0
"SrvName1","USER3",0,1
"SrvName2","USER1",2,2
**********************************************************
4.ログイン回数、ログアウト回数の比較により処理の分岐
ログイン回数>ログアウト回数⇒最初に現れるログイン行を「区分」をはずして出力
ログイン回数=ログアウト回数⇒最初に現れるログイン行から日付,サーバ名,ユーザ名、
ログイン時刻、最後に現れるログアウト行からログアウト時刻を出力
ログイン回数>ログアウト回数⇒最後に現れるログアウト行を「区分」をはずして出力
だと思うんだけどどう記述していいかさっぱりわからない。
部分的にでもいいから教えてくれると助かる。
awk --field-separator , '{print $2 "," $3}' filename | sort -t , -k 1,2 | uniq | while read i; do echo $i; done echo $iの部分を書き換えて3,4をやればいい。grep $i filename | ...
お題が長すぎて読む気にならないw ところで、 >sed -e 's/"/""/' -e 's/^/"/' -e 's/$/"/' -e 's/ /"\,"/' -e 's/ /"\,"/' -e 's//"\,"/' -e 's/ /"\,"/' こういう書き方は、行が多いときにすごく時間がかかるような気がするんだが、どうなんでしょ。 まあ、一個一個の置換がごく単純だから実際に動かすと大したことないのかも知れんけど。
>> 576 thx!
とりあえず
>>575 の 「3.」までは出来た。
awk -F, '{print $2 "," $3}' filename | sort -t , -k 1,2 | uniq | while read i; do grep $i filename |
awk -F, 'BEGIN{i=0;j=0} {if($6=="1"){i+=1};if($6=="6"){j+=1}} END{print $1 "," $2 "," $3 "," i "," j}'; done
"2007/02/16","SrvName1","USER1",1,1
"2007/02/16","SrvName1","USER2",1,0
"2007/02/16","SrvName1","USER3",0,1
"2007/02/16","SrvName2","USER1",2,2
「4.」はどうすればいいのかなぁ?
582 :
581 :2007/03/04(日) 02:57:10 ID:1YavrZjg
とりあえず出来た
>>581 の結果をfilename2
ログイン回数>ログアウト回数
awk -F, '{if($4>$5){print $1 "," $2"," $3}}' filename2 | while read i; do grep $i filename |
awk -F, '{if($6=="1" && NR==1 ){print}}' ; done
ログイン回数>ログアウト回数
awk -F, '{if($4<$5){print $1 "," $2"," $3}}' filename2 | while read i; do grep $i filename |
awk -F, 'BEGIN{j=0} {if($6=="6"){j+=1}} END{if($6=="6" && NR=j ){print}}' ; done
ログイン回数=ログアウト回数
ログインをfilename3、ログアウトをfilename4として作成。キー部分の区切り文字変更「,」→「;」
awk -F, '{if($4==$5){print $1 "," $2"," $3}}' filename2 | while read i; do grep $i filename |
awk -F, '{if($6=="1" && NR==1 ){print $1 ";" $2 ";" $3 "," $4 "," $5}}'; done > filename3
awk -F, '{if($4==$5){print $1 "," $2"," $3}}' filename2 | while read i; do grep $i filename |
awk -F, 'BEGIN{j=0} {if($6=="6"){j+=1}} END{if($6=="6" && NR=j ){print $1 ";" $2 ";" $3 "," $4 "," $5}}'; done > filename4
filename3とfilename4をjoinして区切り文字を戻す。
join -j 1 -t, -o 1.1 1.2 2.3 filename3 filename4 | sed 's/;/,/g'
>571 もう解決したようだがperlのsplitで個数制限した方が簡単じゃないのか。 bashのreadでもいいが。 cat log | while read mon day time host message do echo '"'$mon'","'$day'","'$host'","'$time'","'$message'"' done
>572 ぁぁ似たようなお題をsendmailログでやったことがある。 awkでやるならログインの時刻をlogin[server;user]って連想配列に記録して ログアウトの行がでてきたらlogin[server;user]の有無をチェックすりゃいい。 あればログアウト時刻ともども整形して出力する。 エラーとして扱うものとしては ・ログアウトだけが先に出てきた場合 ・ログインが重複した場合 ・ログインだけでログアウトが無い場合。 先2つは配列チェックでわかるし、最後はログアウトが出てくるたびに 配列をdeleteしとけば、ENDで残ってる配列を出力すればいい。
あ、すまん。 ちょっと早とちりしたな。 複数回のログイン/ログアウトがあるのと、最終時刻の処理があるんだな。 そうすっと、ログインでインクリメント、ログアウトでデクリメントする カウンターで判別して、1→0になったときに出力するような処理になるな。
仕様がはっきりしないけど、多分そうじゃない気がする 一番早いログイン時刻と一番遅いログアウト時刻を記録したいのだろう
そうすると、すべてのログを読み込んでからでないと確定できないな。 それだと単純に、loginとlogoutの両方の配列を用意して、最小値と最大値で 更新すりゃいいだけになる。 ただ、この場合ログイン数が0になっても、ログイン中として扱うパターンが あり得るんだが、いいのかなぁ。
588 :
582 :2007/03/05(月) 02:02:20 ID:tWB3mW28
ええと、仕様的には
>>573 にあるように「サーバ名・ユーザ」単位でログイン・アウトを記録したいという内容。
複数回ログイン・アウトがあった場合はその日のログインログアウトの一番早いログイン時刻と一番遅いログアウト時刻を記録する仕様。
日またぎでログイン・アウトがあるとそれぞれの時刻が落ちて出力される。
なので
1日目 ログインのみ
2日目 1日目のログアウト 2日目のログイン 2日目のログアウト
だと
1日目の出力結果は「1日目ログイン時刻のみ」
2日目の出力結果は「2日目のログイン時刻 2日目のログアウト時刻」
という内容なんだけど…説明悪かったかな?
>>587 詳しく説明して欲しいかも
589 :
582 :2007/03/05(月) 02:14:35 ID:tWB3mW28
ごめん
>>588 訂正
なので
1日目 ログインのみ
2日目 1日目のログアウト 2日目のログイン 2日目のログアウト
だと
1日目の出力結果は「1日目ログイン時刻のみ」
2日目の出力結果は「2日目のログアウト時刻」
ついでに
1日目 ログインのみ
2日目 1日目のログアウト 2日目のログイン 2日目のログアウト 2日目のログイン2回目
3日目 2日目のログイン2回目に対応するログアウト
だと
1日目の出力結果は「1日目ログイン時刻のみ」
2日目の出力結果は「2日目のログイン時刻 2日目のログアウト時刻」
3日目の出力結果は「2日目のログイン2回目に対応するログアウト時刻」
>複数回ログイン・アウトがあった場合は なら、問題なさそう。 1日に細切れでログイン/ログアウトを繰り返した場合に、実際の使用時間と 加工後のデータから得られる使用時間はまったく一致しないからね。 ただ、元データの方にttyなどのコネクションを識別できる情報があった方が 正確な情報は得られる。(多重にログインしたユーザーの積算使用時間も出せる) ま、それは必要とする仕様かどうかによるけど。
ファイルを日付で分類したいのです。 1) 2007-03-05のようにディレクトリをつくって 2) 200x-xx-xx のファイルは200x-xx-xxに分類したいです。 $ mkdir `ls -tl | awk '/^-/{print $6}'|uniq` でディレクトリはつくりました。 強引に mv ファイル名 日付 を大量に出力してそれを実行しました。 $ls -tl | awk '{print "mv -i "$8" "$6}' >mv.sh $chmod +x mv.sh $./mv.sh で成功しました。 もっと効率のいい方法はありませんか?
>>591 ls -tl | awk '{print "mv -i "$8" "$6}' | sh
>>591 一発で全部やりたいならこんな感じかな。
何も変わってないじゃんって言われればそれまでだけどw
$ ls -tl \
| awk '{print "test -f \""$8"\" && mkdir -p "$6" && mv -i "$8" "$6}' \
| /bin/sh
>>592 そうですよね。最後は |sh でいいですね。
>>593 一発でできて便利なので使わせていただきます。
for i in *; do a=`echo $i | cut -c 1-10`; [ ! -d $a ] && mkdir $a; mv $i $a ; done
シェルスクリプトの宿題スレって存在するの?
597 :
login:Penguin :2007/03/08(木) 13:14:23 ID:TAQWLHvv
ddで長時間バックアップしてる間にプログレス表示としてよく見かける、 ....................... といった経過表示をddが終了するまで表示したいのですが、 何か簡単な方法はあるでしょうか? 子プロセスとしてddを立ち上げて、そのプロセスが終わるまで文字 . を表示する という感じでできるかなと考えたのですが、実際スクリプトにしようとすると よくわかりません。 よろしくお願いします。
バックグラウンドで動かして、その直後に無限ループ、でいいんじゃね?
>>597 ... じゃないけど
進行ぐあいなら USR1 送れば見れるよ。
man dd 参照。
( ・∀・)つ〃∩ ヘェーヘェーヘェー
601 :
login:Penguin :2007/03/08(木) 14:40:25 ID:TAQWLHvv
>>599 #!/bin/sh
(gzip -dc < /hda.gz | dd of=/dev/hda) &
pid=$!
kill -USR1 $pid; sleep 1
kill -USR1 $pid; sleep 1
kill -USR1 $pid; sleep 1
kill -USR1 $pid; sleep 1
kill -USR1 $pid; sleep 1
ためしに上のを実行すると
./t.sh: line 5: 5098 ユーザ定義シグナル 1 (gzip -dc < /hda.gz | dd of=/dev/hda)
./t.sh: line 6: kill: (5098) - そのようなプロセスはありません
./t.sh: line 7: kill: (5098) - そのようなプロセスはありません
./t.sh: line 8: kill: (5098) - そのようなプロセスはありません
./t.sh: line 9: kill: (5098) - そのようなプロセスはありません
kill -USR1 $pid でdd死んでしまいます(KNOPPOX501です)
それとやっぱり...というシンプルな表示がしたいです
>>601 それだとシグナルをサブシェルに送ってる。
dd に送らなきゃ。
603 :
login:Penguin :2007/03/08(木) 15:40:43 ID:TAQWLHvv
>>602 どうしたら良いですか?
リダイレクトしてるので良くわからないです…
名前付きパイプを使う手があるな。 mknod p hoge gzip -d < /hda.gz >hoge & dd if=hoge of=/dev/hda & 検証してないから、ちゃんと動くかどうか知らんけど。
>>603 シェルスクリプト良く知らないけど、こんなのではだめ?
#!/bin/sh
$* &
PID=$!
while sleep 1;do
if ps -p ${PID} >/dev/null; then
echo -n "."
else
break
fi
done
echo
>>601 > それとやっぱり...というシンプルな表示がしたいです
それだと進捗ぐあいじゃなくて
単に時間の経過しかわからないと思うんだけど
それでもいいの?
>>605 while ループはこれでいいかも。
while ps -p ${PID} >/dev/null; do
echo -n "."
sleep 1
done
609 :
605 :2007/03/08(木) 16:18:46 ID:+LJ7KyQP
>>608 はるかに分かりやすくなってる。ありがと。
bashのシェルスクリプトで質問があります。 シェルスクリプトでディレクトリを読み込んだら、(bash scriptname dirname) ディレクトリの中に入っているファイル名一覧が表示され、その中にあるひとつひとつのファイルに対して echo -n "このファイルを削除しますか?(y/n):"という質問が動いて、yを入力したらファイルの削除、 nを入力したら次のファイルへ... の繰り返しで、すべてのファイルに対し質問が終わったら自動終了といったスクリプトを組むにはどうすればいいのでしょうか?
rm -i * じゃ駄目なの?
613 :
login:Penguin :2007/03/08(木) 19:40:06 ID:yay+VEJ8
>>611 man bashくらい読め。
#!/bin/sh
ls
for f in $(ls)
do
read -p "$f: このファイルを削除しますか?(y/n)" yn
if [ $yn = 'y' ]; then echo "hoge"; fi
done
$ find . -type f -ok rm {} \;
どう考えてもrubyで書いた方が楽だと言う結論に至った漏れ。orz bashが入ってない環境も世の中には有るよ。
>>615 この板で bash が入ってない環境って言ったら
組み込みとか 1FD Linux とか?
でもそんな環境で Ruby はあるの?
Ubuntuはデフォルトでbash入ってないよ。びっくりした。 awkもgawkじゃない。 しかしインスコスクリプトにpythonを使ってるらしい
そしたら ubuntu のユーザーシェルは何使うようになってるの?zsh とか? /bin/sh は NetBSD の sh(ash)とかよく使うよね。 awk は debian も mawk だね。
dashだよ。Debianのシェルらしいけど、Debianもデフォルトはbashなのか。
bashでもdashでもkshでも動作するシェルスクリプトを書けば良くね?
↑天才現る。
>>615 そりゃあどう考えてもrubyで書いた方が楽だけど、bashが入ってない環境よりrubyが入ってない環境の方が多い
sh互換でおk
perl ならまず入ってるよ(w
どういう意味だ。 perlはまず入ってない と言いたいのだろうか。
ヒント:「まず入ってる」の否定は「まず入ってない」ではない。
どういう意味だ。 「まず入ってる」の否定の一枝として「まず入ってない」はあり得ない と言いたいのだろうか。
で結局
>>615 はどんな環境のことを言ってたんだ?
>>631 ウィンドウズにきまってるじゃないか!!!
世界のパソコンの90%いじょうにはbashなんてはいってないんだぞ!!!!!
この板をどなたと心得る。
634 :
login:Penguin :2007/03/13(火) 02:45:00 ID:HgbRL3Pw
bashでシェルスクリプトを組もうとしています。 今、hohogehoge.txtというファイルに、色んな文章に紛れて以下のような一文 があります。 内容 :IP=192.168.0.5(foo-bar-mona-giko)がおかしいよ。 「IP=」の後の<IPアドレス>はランダムに変わります。また()内のハイフンの 区切りについては、その数も値もランダムに変更するものとします。この中か ら<IPアドレス>と()内の一つ目の項目(例の場合ならfooだけ)を抜き出して copy.txtに出力する場合、どのような方法がありますか。出力時のフォーマット はコンマ区切りです。 こんな感じです。 192.168.0.5,foo 自分なりに作ってみたんですけど、力不足でsedだけで何とかすることが出来 ず、苦肉の策としてawkを使ってしまいました。何かもっとスマートなやり方 があるような気がするのですが思いつきません。 grep '^内容' hogehoge.txt | sed -e 's/.*=\(.*\)(\(.*\)).*/\1,\2/' | awk -F'-' '{print $2}'> copy.txt よろしくおねがいします。
perl -nle '/^内容:IP=([\d\.]+)\(([^\-]+)/ && print "$1,$2"' hogehoge.txt > copy.txt
>>634 awk -F '[=()-]' '{print $2 "," $3}' hogehoge.txt > copy.txt
>>635-636 「これでやる」と決めたらもう意地になってそれで通そうとするのが私の悪い癖ですね。
やっぱり意固地になっちゃ駄目ですね。
>>635 何もsedに拘る必要などはなく、perlで良かったんですね・・・。
そうすればもっと早く解決できたのかも知れません。
教えていただいたものの、正規表現は勉強になりました。
有難う御座います。
>>636 awkのこの使い方だと、デリミタに指定している文字が入る行全てに適用され
てしまうため、以下のようにするとうまく行きました。有難う御座います。
grep '^内容' hogehoge.txt awk -F '[=()-]' '{print $2 "," $3}' > copy.txt
bash.exeぐらいビスタ入れとけと思う。
639 :
login:Penguin :2007/03/14(水) 05:37:07 ID:EOnMAlGF
シェル上からPCのMACアドレスを取得するにはどうしたらいいでしょうか? #!/bin/sh MAC=`ifconfig | grep eth0 | awk '{ print $4 }'` echo "$MAC" とかやれば一応出てきますが、eth0が有効になってないと できないみたいなので、LANケーブルがささってない状態から 取得できる方法がないか探しています。
いやそうじゃなくて…
dmesg | grep eth0 ならどう?
>>640 失礼しました、今確認したらLANケーブル繋がって無くても
ifconfig eth0でOKな様です。
でもダメな時があった様な…
>>642 dmesgにはMACアドレスは出てこないみたいなんですよね。
あの辺はデバドラが出してるんでしょうか。
eth0みたいな論理?デバイス名から取得するにはifconfigしかないのかな。
/proc配下探してもそれらしいのは無いし。
>>643 そういうふうにやりたいなら cat /sys/class/net/eth0/address とか
ifconfig使った方がいいと思うけど
>>645 あ、たぶんそれです。
今2.6環境がないので/sys〜は試せませんけど、そういう事やりたかったのです。
ありがとうございました。
>>638 なあ、おっちゃん。Windows mobileで動くbash.exeって無いかな?
648 :
login:Penguin :2007/03/15(木) 05:29:51 ID:/H5IKm/o
awkやperlの前段で馬鹿の一つ覚えのようにgrepで絞り込んでる奴は池沼。 awkの基本構文 '//{ }'くらい覚えろ。 その上さらにgrep AAA | grep BBB とかgrepを多段接続してるやつはぬるぽ。 簡単な正規表現くらい覚えろ。
>>648 問題: grep AAA | grep BBB と等価なことをgrep一発で済ます正規表現を書いてみよう。
650 :
login:Penguin :2007/03/15(木) 08:35:59 ID:mM6Oz18e
egrep 'AAA.*BBB|BBB.*AAA' 動作確認はしていない携帯なので
問題: grep AAA | grep BBB | grep CCC と等価なことをgrep一発で済ます正規表現を書いてみよう。 egrep 'AAA.*BBB.*CCC|AAA.*CCC.*BBB|BBB.*AAA.*CCC|BBB.*CCC.*AAA|CCC.*AAA.*BBB|CCC.*BBB.*AAA'
awk '/AAA/ && /BBB/ { print }' awk '/AAA/ && /BBB/ && /CCC/ { print }'
スクリプトって、人間性出るよね。 だからいい。
grep -E [AB]{3} && kill `ps x | awk '{print $1}'`
awk の pattern {action} で、action が print だけのときは {action} を省略できる。 awk '/AAA/&&/BBB/' sed -n '/AAA/{/BBB/p;}'
省略できるの知らなかった メモった
>>652 すげー感動した。
俺は最近始めたばっかりだけどご多分に漏れずgrepの繰り返ししてた orz
>>655 更に感動した。
660 :
login:Penguin :2007/03/15(木) 12:21:52 ID:bLhkgTOV
でもさあ、
grep AAA | grep BBB
の方が意図が伝わるしわかりやすいよね。
>>650 以下は一週間ぐらいしたら忘れてそう。
略記法とか正規表現てバッドノウハウな気がするんだわ。
>>661 grep AAA | grep BBB | grep CCC みたいにパイプパイプパイプなんてやると
巨大なファイル郡を処理させたときに、処理時間にとんでもない差がでる。
1プロセスでできる処理なら1プロセスでやったほうがいい場合もある。
>>661 AAA なんとかかんとか BBB
だけが抽出対象の時は、正規表現なしのgrepの連結だけでどうやるの?
パイプなんだから、1プロセスだろ。
>>663 grep AAA |grep BBB
とか
意味取り違えている?
でもお舞ら、システムのブートスクリプトとか眺めてても、 「grepの多段パイプはけーん。書いた奴阿呆でーw」 とか言って、勝手にawkなんか使って書き換えるなよな。
ま、パイプを増やすことによる負荷の増加は算術級数的にしか増えないが、 正規表現を増やすことによる負荷の増加は幾何級数的に増えるから、 何事もほどほどにな。
負荷を押さえた正規表現の指定ってのも重要。 awk使うくらいならruby呼ぶ。
if [ -d A* ] ; then rmdir A* ;fi これだと A と AA がある場合のように A* に一致するものが複数あった時に bash: [: A: binary operator expected とエラーになるのですが rmdir A AA を実行できるようにするには [ -d A* ] の部分はどう書けばよいですか?
>>670 for i in A*; do
[ -d "$i" ] && rmdir "$i"
done
空かどうかは見なくていいの?
単にこれでもいいかも。 rmdir A* 2>/dev/null
673 :
670 :2007/03/16(金) 01:18:12 ID:RidIExC4
>>671-672 レスありがとうございます。
[ ] に渡す物が一個ずつになるように for でやってみます。
> 空かどうかは見なくていいの?
はい。大丈夫です。
rm -rf A* じゃだめか?A*というファイルは消しちゃダメなの?
>>674 例ではAとされているが、実はその文字は . かも知れないじゃん。
677 :
login:Penguin :2007/03/16(金) 16:37:18 ID:VcZCcuMK
awkで困っています。 スペース区切りで日付データが出力されるコマンド|awk '{print mktime("$1,$2,$3,$4,$5,$6")}' とやってもmktimeの結果が−1と出力されてしまいます。 awkで分割した変数を組み込み関数の中で使うにはどうしたら良いのでしょうか?
>>677 echo '2007 03 01 10 10 11' | gawk '{print mktime($1" "$2" "$3" "$4" "$5" "$6)}'
でうまくいった。
echo '' | gawk '{print "$1 $2 $3 $4 $5 $6"}'
で調べたらわかったけど、awkはダブルクオーツの中身は変数展開してくれないみたいだな。
perlとチャンポンでやってると、混同しやすいな
>>677 ああ後mktimeはスペース区切りで日付が出力されるんじゃなくて、
スペース区切りのYMDHMを与えてエポック病に変換する関数みたいだぞ
680 :
677 :2007/03/16(金) 18:07:55 ID:VcZCcuMK
>>678 素早く的確な回答ありがとうございます!
助かりました。
きちんと動作する事を確認しました。
>>680 echo '2007 03 01 10 10 11' | awk -F '_' '{print mktime($0);}'
682 :
login:Penguin :2007/03/17(土) 08:15:03 ID:kZdD4YRT
htmlのリンクをはずそうと思うのですが、 $ sed 's/<a href[^>]*>\([^<]*\)</a>/\1/g' sed: -e 表現 #1, 文字数 30: unknown option to `s' となります。 文字数30こえたらダメなのですか?
あ、わかりました。/ですね。失礼します。
これまた腐った日本語メッセージだなあ。
686 :
login:Penguin :2007/03/20(火) 22:20:52 ID:OwvLXsox
リサイズ済みの同じサイズの画像が15あります。 その画像を 縦x横 3x5 で結合したいのです。 x x x x x x x x x x x x x x x ↑こんな感じにです。 順番はどんな順番でもかまいません。 これをコマンドラインでできませんか?
convert とか ImageMagick のツールでできそう。
>>686 montage -tile 5x3
童貞大百科でも作るのか?
>>688 ありがとうございます。
オプションとか使いこなせたら面白そうですね。
>童貞大百科でも作るのか?
そんな感じです。
いる部分だけ抜き出し、
まとめて1つの画像に残したいときに使わせてもらいます。
690 :
login:Penguin :2007/03/26(月) 14:16:01 ID:4w79sb0R
質問させてください Fortranのネームリストファイル(init.nml)からmax_Xとmax_Yの値を取り出し、 それをシェルスクリプトの変数(varXとvarY)へ代入して gnuplotの描画範囲指定(xrangeとyrange)に用いるスクリプトを考えています。 awkでどのように書いたらいいのか教えてください。スクリプトは↓ awk '/???/{print;}' init.nml #*****←ここが分からない!***** varX=??? #*****←ここが分からない!***** varY=??? #*****←ここが分からない!***** gnuplot << EOF set terminal png set output "$1img/${var2}.png" set xlabel "X[m]" set ylabel "Y[m]" set xrange [0.0e0:${varX}] set yrange [0.0e0:${varY}] set title "Karman Vortex Street" plot "$1/${var2}.dat" with vector EOF ------------------------init.nmlの内容------------------------ &karCar max_X = 2.0d0, max_Y = 2.0d0, div_a = 100, div_b = 100,/
>>690 var X で変数を定義するスクリプトって何?Pascal?
あと、$1と${var2}は何?シェルスクリプトの引数??
692 :
login:Penguin :2007/03/26(月) 14:40:32 ID:4w79sb0R
すみません。行が足りなかったので消してしましました。↓です #!/bin/sh #awk '/&/{print;}' init.nml #varX= #varY= for i in $1/*.dat do var1=${i:8} #Cut 8 letters at the begining of string var2=${var1%.dat} #Cut ".dat" gnuplot << EOF set terminal png set output "$1img/${var2}.png" set xlabel "X[m]" set ylabel "Y[m]" set xrange [-0.10e0:2.1e0] set yrange [-0.10e0:2.1e0] set title "Karman Vortex Street" plot "$1/${var2}.dat" with vector EOF convert $1img/${var2}.png $1img/${var2}.gif rm $1img/${var2}.png -f echo "["$i"] has drown." done
varX=`gawk '/max_X *= */ {sub("^.*max_X *= *",""); sub(",$",""); print}' init.nml` varY=`gawk '/max_Y *= */ {sub("^.*max_Y *= *",""); sub(",$",""); print}' init.nml`
>>693 はinit.nmlの中身がダブってたりすると死ぬから、あくまでその場しのぎね。
ちゃんとやるなら、init.nmlを最後まで読み切ってからEND{}で一回だけ出力するとか
した方がいい。
あと.nmlファイルって知らんのだが、 max_X=2.0d0, max_Y=2.0d0, .... みたいな書き方されると、
これも死ぬ。perlなら
perl -nle '{/max_X\s*=\s*([^,]+)/ && print $1}' init.nml
とシンプルにいけるけど。
awkでも似たようなこと(マッチ&抽出)が出来たような覚えがあるが、漏れは(´・ω・`)
695 :
690 :2007/03/26(月) 15:17:36 ID:4w79sb0R
ありがとうございます!!こんなに早く返信があるとは思いませんでした。スゲ ちなみに gawk '/max_X *= */ {sub("^.*max_X *= *",""); sub(",$",""); print}' init.nml は言葉でいうと 「『max_X』という言葉にマッチする行から、『max_X』と『,』を『』で消す」 という意味で良いのですか? 実際にやってみると二番目のsub()が効いていないのか、『,』が残ってしまいます。 むむむ...
awk -F'( = |,)' '/max_X/{print $2}' init.nml
そりゃきっと、カンマの前後にスペースとかがついているんだな gawk '/max_X *= */ {sub("^.*max_X *= *",""); sub(",.*$",""); print} ' init.nml これでいけるはず。あとこれだと、行繋がりしていても正しく抽出できるだろう。 あと、ダブっていても最後のをひとつだけ抽出できるようにするなら、 gawk '/max_X *= */ {sub("^.*max_X *= *",""); sub(",.*$",""); v=$0} END{print v}' init.nml あとはmax_Xの行がinit.nmになかった時の処理だが、このままだと/bin/shの側でsyntax errorで死ぬかも。 これは、sh側でチェックするしかない罠
698 :
690 :2007/03/26(月) 15:43:10 ID:4w79sb0R
perl -nle '{/max_X\s*=\s*([^,]+)/ && print $1}' init.nml awk -F'( = |,)' '/max_X/{print $2}' init.nml の両方でできました!ありがとうございます!! フィールドセパレータを『=』か『,』にするという方法もあったのか。
頭の悪い俺に教えてくれ。 expectを使ってtelnetでログインして、コマンドを入力してやりたいんだが、 うまくいかないんだ。 例えばプロンプト$が出たときに、ls -lって打つようにやりたいんだけど expect "$" ; send "ls -l\r" って、書いたらエラー吐き出して $ expect: invalid option -- l usage: expect [-div] [-c cmds] [[-f] cmdfile] [args] って出ちゃうんだよな。 なんでorz
>>699 ssh ホスト名 'ls -l'
じゃだめなん?
>>700 最終的にファイルを作ってftpで送信してもらう、みたいな感じで
いろいろやりたいんだよな。
単体でlsとかだけならいけるんだけど、オプションつけるとなんかおかしくなる・・・。
>>701 その「いろいろ」を書いたスクリプトを向こうに置いときゃいいじゃん。
> expect "$" ; これがまずいのでは。「$」を与えたいなら '$' で。
#!/bin/sh
#echo 'test'
LIST="list.url"
#URL="
http://www.youtube.com/watch?v=9730SY-F8xE "
TMP="ahoaho"
BASEURL="
http://youtube.com/get_video.php? "
while read LINE
do
if [ ! -e "$LINE" ]
then
URL="$LINE"
wget $URL -O $TMP
TTMP=$BASEURL`grep player2.swf $TMP | cut -d? -f2 | cut -d\" -f1`
NAME=`grep watch_fullscreen $TMP | cut -d\" -f4`
NNAME=`echo "$NAME"| sed -e "s/[^a-zA-Z0-9]//g"`
wget "$TTMP" -O temp.flv
ffmpeg -i temp.flv "$NNAME".avi < /dev/null
rm temp.flv
fi
done <"$LIST"
こんなん書いてみました。添削して下さい。
>>704 一部パクられた感じがするが…
テンポラリファイル名は固定しない方がいい。別々のファイルを拾うために、
同時に同一ディレクトリで複数のスクリプトを走らせたらどうなるか考えてみろ。
まあ
>>529 でも、同時に同一ファイルを拾いに行ったらおかしなことになるが…
706 :
529 :2007/03/29(木) 10:31:00 ID:Pt6e5Sbi
707 :
704 :2007/03/29(木) 21:48:41 ID:gfauW22r
>>705-706 パクっちゃってすみません。ググって出てきたスクリプトを参考にしたら
>>529 のと同じようなスクリプトになってしまいました。
現状で
1)NNAMEでファイル名作っているのですが、ファイル名に使えない文字を省くための処理をしているのですが、
日本語のタイトルには使えないので、もっとスマートな方法を知りたいです。
2)ffmpegの行で< /dev/nullが無いとffmpegの処理が終わるとスクリプトが終了してしまう。
ためしに < /dev/nullを書いてみたら上手くいってしまったが、この動作について知りたいです。
>>652 遅レスだけど
you は shock!
youはshock
you ha shock
みたいなのが検索対象のとき、どうするの?
>>708 awk '/you *(は|ha) *shock/' you_ha_shock.txt
710 :
login:Penguin :2007/03/30(金) 13:45:35 ID:IYfEQetc
>>708 >>709 grepの連結や、awkの&&では対処できない。「shockはyou」もマッチしてしまうからな
A B \ C D E \ F G \ H \ I というファイルを \[改行] となっている箇所を結合したいんですが↓ A B C D E F G H I sed でどのように書けばうまく出来ますか?
sed ':b;/\\$/{s/\\$//;N;s/\n//;bb}' これでどうだろう。
sedの質問です。 hoge begin fuga end geho というデータがあった場合、begin..endで挟まれてるfugaを抜き出すのは sedでどうやりますか?combineは知ってるのですが sed -e '/begin/,/end/{/begin/d;/end/d;p}' とパターンを2度書くダサい方法しか思いつけませんでした。 sed -e '/begin/,/end/{(1);(2);p}' で(1)(2)でpattern space内の先頭「行」と終端「行」を切り落として やるのが一番エレガントだと思うのですが、何か方法ないでしょうか?
>713 できました。ありがとうございます。
大して、変わってないかも知れんけど、 sed -n -e "1,/begin/b;/end/q;p"
>>716 おーなるほど、bでスキップしてしまうのか。
パターン文字列が複雑なときは2回書くの手間なので、助かります。
まだまだsedを使いこなせてないなぁ>自分
>>712 sedなぞいらん。
(while read l; do
echo "$l"
done) < file
でおk。
>>718 意味わからん
ちょっと説明してくれる?
>>712 sedなぞいらん。cpp でおk。
…ホントかな。
いいけど、このスレ的に駄目。
723 :
login:Penguin :2007/04/04(水) 02:05:36 ID:8bqEa14S
関数で分からないことがあるので質問します。 指定したディレクトリに'.pid'という拡張子が附いたファイルが無ければNOと 表示し、個数を問わず存在すればexistと表示するスクリプトを作っているの ですがうまく行きません。 OS:CentOS シェル:bash #!/bin/sh PDIR=/home/test/pid pid_count () { local PIDCOUNT PIDCOUNT=`ls $PDIR|grep '\.pid'` [ x = x$PIDCOUNT ] && return 0 return 1 } if [ pid_count ];then echo 'no' else echo exist fi こんなんじゃ駄目ですか?
grep -c で、ヒット行数を出力させることができる。 また、ヒットする/しないだけでいいなら、出力じゃなくて終了コードで判断することも出来る。 if (ls $PDIR|grep '\.pid' >/dev/null 2>&1);then echo exist else echo 'no' fi
ちなみに、 ls $PDIR|grep '\.pid' の部分は find -regex を使う方がいいのかもしれんけど。
727 :
723 :2007/04/04(水) 03:15:49 ID:8bqEa14S
723です。
>>724-725 出来たよ!わあいわあい!
このようにしてうまく行きました。
ブラケットじゃなくて、パーレンで囲むんですね・・・
有難う御座いました。
pid_count () {
local PIDCOUNT
PIDCOUNT=`ls $PDIR|grep -c '\.pid'`
return $PIDCOUNT
}
if (pid_count);then
echo 'exist'
else
echo 'no'
fi
>>727 いやいや、自分で言うのもなんだけど、( )でくくったのは全く意味がない。
なしでいいよ。
簡単なシェルスクリプトを作りたいのですが、 どうしても初心者1歩目の私には構成の仕方が思いつかないので下記の文章を簡単に作って頂いて自分なりに文章の構成の仕方を覚えたいのですが、どなたか行っていただける方おりましたら宜しくお願いします。 【fileA】に【/home/etc】の内容を書き写す。 ↑のfileAをcrontabで時間指定して行うというような作業を最終的にしたいのですが crontab -eの使い方は分かるのですが、上に記載したシェルスクリプトの構成がわかりません。 宜しくお願いします。
>>729 やりたいことがいまいちよくわからんが
cp /home/etc fileA
ってこと?
cron から呼ぶなら
先に cd しておくか
fileA はフルパスで書いた方がいいよ。
>>729 ls -a /home/etc > fileA
ってことか?
>>730 迅速なレスありがとうございます!
ちょっと自分でも理解できいるのがどの程度なのかわからず自分自身も頭を抱えているのですが
実際に細かいやりたい事をいわせて頂くと
AというファイルをBというファイルに週一(数値は適当で)バックアップするcronを作ってみたいというのが正確な言い方なのかもしれません;;
朝からテキスト等を見てチョコチョコ考えてみてるのですが定義の仕方やコマンドの書き方が頭の中でゴチャゴチャで煮詰まってしまいました。
もし
>>730 様のcp /home/etc fileA を直接cronに時間指定に後に打つとコマンドは有効なのでしょうか?
自分の中では【* * * * * cp /home/etc fileA】で *****(時間のとき)fileAに/home/etcの内容を書き写す。という解釈になっているのですがこれは間違いでしょうか?
733 :
729 :2007/04/04(水) 16:21:27 ID:h7ydsGVi
すみません
>>731 様もありがとうございます;;
考えながら書いていてトロクテ申し訳ありませんが皆様お力を貸していただけたら宜しくお願いします。
>>732 「* * * * *」はもちろん必要。
でもそれはシェルスクリプトの話ではない。
もうちっと自分で調べたり試したりしてから質問しに来なよ。
なんだ、マルチか。
マルチっちゅうか、 ID:h7ydsGVi はまるっきり逆なんだよな、訊く場所と内容が
739 :
login:Penguin :2007/04/05(木) 02:00:36 ID:tW/x3cMg
cshで1行づつ読み込んで処理を行いたいのですが、 下記のソースでは行内にスペースが入っていると期待する結果になりません。 良い方法があれば教えて頂けないでしょうか。 宜しくお願い致します。 foreach line (`cat input.txt`) 【$lineに対して行単位の処理】 end
foreach line ( "`cat /etc/hosts`" ) echo "[$line]" end
741 :
739 :2007/04/06(金) 00:52:17 ID:6RGj1rOS
>>740 早速のレスに感謝です!
今日の仕事を無事に終えることが出来ました。
m(_ _)m
便乗です。 shだったらどうやるのでしょう。 うまくいかないので、こうする? while read line do echo $line done < /etc/hosts
>>744 そーいわずに。。。forを使いたいのです(ただの興味なんですが)。
こういうスクリプトならうまくいきそうです。
#!/bin/sh
ORGIFS=$IFS
IFS='
'
for i in `cat /etc/hosts`
do
echo $i
# echo aaaaa
done
IFS=$ORGIFS
あんまりキレイじゃないですね。
>>745 foreach line ( "`cat /etc/hosts`" )
echo "[$line]"
end
もそうだけど、ファイルを読み込んで、一旦配列(メモリ)に読み込むから。
748 :
739 :2007/04/12(木) 02:15:39 ID:VOD0EPIg
先日はありがとうございました。 また質問させてください。 cshで複数の処理をバックグラウンドで起動してwaitで待ち受けた後、 個々が正常終了か異常終了かを判別するにはどうすれば良いでしょうか? #!/usr/bin/csh ./a.csh & ./b.csh & ./c.csh & wait exit【a,b,cがすべて正常なら0、それ以外なら1を返したい】
細かい事を聞かせてください。 このスレを [/bin/sh]で抽出してみたのですが、皆さんシェルスクリプトの一行目 #!bin/sh #bin/sh と二通りの方がいらっしゃいます。どちらが正解なのでしょうか? 確かCGI等では #!/usr/local/bin/perl って書いてたような。
細かいことを言えばどちらも違う。#!/bin/sh だw まあ ! が抜けてるのは単に忘れてるだけだろ。
751 :
login:Penguin :2007/04/12(木) 20:04:11 ID:srakSzLq
>>749 スクリプトの一行目の#!はそのスクリプトがどのコマンドによって実行されるかを
記述するための仕掛けです。
正しくは #! /bin/sh とスペースも入りますが、最近はそうしないと正しく動作しない
シェルを使ってる人はいないでしょう。
#!/bin/sh ならば二行目以降を/bin/shの標準入力に流し込みます。
#!/usr/local/bin/perl ならば二行目以降を/usr/local/bin/perlの標準入力に流し込みます。
ちなみに追加オプションとかも記述することができます。 (例: #!/bin/sh -v)
うひょー、お二人ともありがとうございます。 なんて親切なんだ。 という事で、私は今後シェルスクリプト書くときは #! /bin/sh って書くようにします。 動くといってもやっぱりなるべく正しく書きたいのが日本人ってもんです。
何かの寸劇みたいな締め方だなw
>>748 % cat a.csh
#!/bin/csh
sleep 2
exit 1
----------------------------
% cat test.csh
#!/bin/csh
./a.csh
echo '$status='$status
./a.csh &
wait
echo '$status='$status
----------------------------
% test.csh
$status=1
[1] 1945
[1] 1で終了しました ./a.csh
$status=0
%
・・・という具合に、バックグラウンド起動なしなら$statusにexitコードは入るが、
裏に回すと、単にwaitの実行結果(wait成功?)としての0しかとれないみたいだな。
「[1] 1で終了しました ./a.csh」とかいうメッセージを無理やり拾ってここからexitコードを
取り出すか、さもなくばファイルかなんかでやりとりするしかないんじゃないのかな?
bashなら... #!/bin/bash ./a.sh & pida=$! ./b.sh & pidb=$! ./c.sh & pidc=$! wait $pida exitcodea=$? wait $pidb exitcodeb=$? wait $pidc exitcodec=$? if [ $exitcodea == 0 -a exitcodeb == 0 -a $exitcodec == 0 ]; then exit 0 else exit 1 fi
>#!/bin/sh ならば二行目以降を/bin/shの標準入力に流し込みます。 違う。 スクリプトファイル名自体を引数にして1行目に書かれたコマンドを実行する。 だから、標準入力を受けつけないコマンドでも使えるし、 コメントが # でないスクリプト言語では使えない。 逆に、コメントが # でありさえすればスクリプト言語でなくても使える。 たとえば、logrotate の設定ファイルの1行目に #!/usr/sbin/logrotate と書いて chmod +x しておけば、その設定ファイル自体がログをまわすための実行コマンドとして 使えるようになる。
>>751 インタプリタを呼ぶのはシェルではなくてカーネルの仕事だ。
それにスペースを入れたらむしろ動かないことがある。
スペースを入れないのが無難だ。
~/.bash_history から cd か pushd の引数になっているディレクトリを 抜き出して、個数に従って降順に並べて出力させようとしています。 今のところ下記のようにしていますが、もっと簡潔でしかも高速にできる 方法はないでしょうか? awk '/^(cd|pushd) [^\.]/ {print $2}' ~/.bash_history | sed -e 's/^~/echo $HOME/e' -e 's/\\//g' -e 's/\/$//' | sort | uniq -c | sort -k 1r,1 | awk '{print $2}'
>>758 実行時のカレントディレクトリを考慮していないという欠陥があるように
思えるんだけど、いいの?
>>758 ls; cd hoge とか cd ~taro とかはいいのかな。
>>759 ~/.bash_history からだと無理じゃない?
>>759 ご指摘ありがとうございます。
.(ピリオド)を使った相対パス指定については最初のパターンにある[^\.]で
除外しています。
>>760 > ls; cd hoge とか cd ~taro とかはいいのかな。
ご指摘ありがとうございます。
前者の方は手間がかかりそうだし遅くなりそうなので、今後の課題にさせて
いただきます。
後者の方は、
-e 's/^~/echo $HOME/e'
→ -e 's/^~\//echo $HOME\//e'
と変更してみます。
perl -e 'map { /(cd|pushd) ([^\.].+)/ && $cnt{$2}++} grep{s/~/$ENV{HOME}/ ||1 } <>; map {s/^\d+#//;print $_,"\n"} reverse sort grep {$_="$cnt{$_}#$_"} keys %cnt;' .bash_history ちと無理があるな...
パス名展開は sed にやらせたくないな。 なんとかシェルにやらせられないかねぇ。
awk '/^(cd|pushd)/&&$2!~/^\./{print $2}' .bash_history | xargs -i sh -c 'eval echo {}' | sort | uniq -c | sort -nr | cut -b9-
awk -v h=$HOME ' /^(cd|pushd)/{sub(/^~/,h,$2);a[$2]++} END{for(dir in a) print a[dir],dir} ' ~/.bash_history | sort -nr | awk '{print $2}' なんかスマートじゃないな…
767 :
login:Penguin :2007/04/13(金) 19:17:00 ID:CeIWV8n2
1 ディレクトリ名をキーにしてヒストグラムを作る 2 "度数 ディレクトリ名"形式で出力して、ソート 3 頭の数字を取り去る 何でやっても、大体こんな感じ?
769 :
758 :2007/04/13(金) 21:46:07 ID:I9CXZd1n
みなさん、たいへんありがとうございます。
>>766 さんのスクリプトが桁違いに高速なので使わせていただきます。
awkすごいですね。シェルスクリプトを作るなら勉強しないといかん
と思いました。
ただし、フィールドを使うと、空白の入ったディレクトリ名に対応できない
ことに気付いたので、とりあえず以下のようにしました(長すぎる行がある
と怒られたので適当に改行を入れてます)。
awk -v h="$HOME/" '/^(cd|pushd) [^\.]/{sub(/^(cd|pushd) /,"",$0);
sub(/^~\//,h,$0);sub(/\/$/,"",$0);gsub(/\\/,"",$0);a[$0]++}
END{for(dir in a) print a[dir],dir}' ~/.bash_history
| sort -nr | awk '{sub(/^[^\/]+/,"",$0);print $0}'
770 :
758 :2007/04/13(金) 22:20:19 ID:I9CXZd1n
>>768 すいません。どこがだめなのかわからないので宜しければ教えてください。
771 :
758 :2007/04/13(金) 22:30:37 ID:I9CXZd1n
cd するごとにディレクトリを記録しておけばいいんじゃないのか
773 :
758 :2007/04/13(金) 22:55:19 ID:I9CXZd1n
>>772 なるほど。
それは、つまりcdコマンドのラッパーを作るということですね。
zsh では chpwd を定義しておけば、その都度実行してくれるけど、 bash に似たような仕組みがなければそういうことになるかな。
>>770 相対パスがドットでいつも始まるわけでじゃないから。
/aaa/
に居て
cd bbb
したら
/aaa/bbb/
に行く
776 :
login:Penguin :2007/04/14(土) 07:54:06 ID:g8Mqkjvf
質問させてください。 以下のように、test-serverへ接続し、 date;hostname;whoamiを実行するスクリプトを書いてます。 date;hostname;whoamiの結果をリダイレクトし、 スクリプト本体があるサーバに保存したいのですが、 その場合、どう記述すれば良いでしょうか。 #/bin/bash HOST=test-server UNAME=root PASSWD=*** expect -c " set timeout 20 spawn telnet $HOST expect login:\ ; send \"$UNAME\r\" expect sword:\ ; send \"$PASSWD\r\" expect \"$\" ; send \"ls\r\" expect \"$\" ; send \"date;hostname;whoami\r\" expect \"$\" ; send \"exit\r\"
777 :
758 :2007/04/14(土) 08:13:25 ID:ZyZ9VcbW
>>775 そのパターンもありましたね。うっかりしちょりました。
ご指摘ありがとうございます。
ということで修正しました。
awk -v h="$HOME/" '/^(cd|pushd) ~*\//{sub(/^(cd|pushd) /,"",$0);
sub(/^~\//,h,$0);sub(/\/$/,"",$0);gsub(/\\/,"",$0);a[$0]++}
END{for(dir in a) print a[dir],dir}' ~/.bash_history | sort -nr
| awk '{sub(/^[^\/]+/,"",$0);print $0}'
>>776 expectで関数を流し込むのはどうだい?
function myfunc(){
date
hostname
whoami
}
myfunc > a.txt
sed -i みたいに awk でファイルを書き換えるオプションはありますか?
Perl で書かれた CGI が生成する掲示板などの log ファイル(タブ区切りテキスト)から、 最新の一行だけを抜き出して、ページ内の任意の場所に貼り込むための簡単なスクリプトを書こうと思っています。 基本的には tail か head(元の CGI の作法によってどちらを使うかが決まる)を使って、 該当の一行を抜き出せばいい、というのはわかるのですが、 ここから、必要なカラムだけを取り出すにはどうすればいいのでしょうか? 例えばこのログファイルのフォーマットが 番号<TAB>日付<TAB>タイトル<TAB>本文<TAB>ホスト となっているとして、本文だけを抜き出したい、というような場合です。 どなたか教えていただけませんでしょうか。よろしくお願いいたします。
>>782 head に cut を合わせて、目的通りのツールを作ることができました。
ありがとうございました。
ハードウェアを認識した時に何かシェルスクリプトが走る ハードウェアの認識を失った時にも何かシェルスクリプトが走る プリンタの場合は /etc/init.d/cupsys ファイルが認識した時に走る では認識を失った時にはどこのファイルが走る?
786 :
784 :2007/04/29(日) 23:19:16 ID:SbkIGRrk
>>785 いや、マジで質問しているんだけど。。。
プリンタを認識したり認識解除したりすると、/etc/samba/smb.confファイルが
勝手に書き換えられる(I-O DataのLANDISKをハックして使っているから)
問題に対処する為に、認識した時に自分で作った設定ファイルを上書きコピーする
ように出来たのはいいんだけど、認識解除した時にまた勝手に書き換えられるから
それにも対処したいんだけど、認識解除した時にどこのシェルスクリプトファイルが走っている
のか分からなくて困っているから質問しています。
788 :
784 :2007/04/30(月) 00:43:14 ID:rs45s6UC
>>787 ん?udevのルールとは?
udev ルール プリンタ等で検索して調べましたが
/dev/hda とか /dev/sda とか、そういう命名規則を設定する?ソフト?みたいな
感じに書かれてありましたが、よくわかりません。
出来れば詳細をお願いできませんか?
よくわかんないけどオートマウンタみたいなハードウェア用の デーモンが動いててそれがやってんじゃないの?
>>786 smb.confの所有者書き換えたらなんとかなるんじゃないの
792 :
784 :2007/04/30(月) 02:27:52 ID:rs45s6UC
>>791 landisk:~# ls -l /etc/samba/smb.conf
-rw-r--r-- 1 root root 1524 2007-04-29 22:27 /etc/samba/smb.conf
landisk:~#
どう所有者を書き換えろと・・・OTL
794 :
784 :2007/04/30(月) 13:27:07 ID:rs45s6UC
>>793 いや、だから、既にrootだから、システム側はroot権限のファイルすらも書き換えちゃう
って事ですよ?なので一般ユーザ等に変更しても書き換えは防げ無いでしょ。
chmod 555 とかやってもroot権限で書き換えられてるようだから効果ないよね
モキュ・・・・・。
シェルスクリプトでなんとかならんものか・・・・OTL
>>794 LANDISKか白箱スレ行きゃ速効答えが出ると思うが。。。
んで、ハックって何をどうする事よと。
796 :
784 :2007/04/30(月) 18:30:11 ID:rs45s6UC
ハードウェア版にスレあるじゃん。 ファイルシステムが ext2 系なら chattr +i で書き込み不可にできるが。
実行されるものがシェルスクリプトということなら、 一時的にシェルを置き換えてみたら? スクリプトを与えられて実行したときにその名前をどっかに記録するようなもの で置き換えて試せばどうかな。もっと賢い方法もあるかも知れないけど。 それにしても根本的な設定ファイルを無断で書き換えるって、 それはLANDISKとやらがそういう作りになっているの? まあI/Oデータ以外の人がいじることは考えていないからだろうけど、 随分と嫌な動作をするように作ってあるんだねぇ。 smbcontrol -s <プリンタ部分だけ変えたもの> smbd reload-config とかで目的は果たせないものかな。
800 :
784 :2007/04/30(月) 21:18:41 ID:rs45s6UC
>>797 おお、chattrで変更を拒否ですか!それは凄い。。。設定してみます!ありがとうございます!
しかしそこまでIO Dataが読んでたら、
#! /bin/sh
chattr -i /etc/samba/smb.conf
とかその勝手に書き換えるシェルスクリプトに書いてたりして。もしそうだったら意味がない。
でも試してみます!
>>798 どうもありがとうございます。シェルを置き換えるとかそんな事は出来ませんが
smbcontrol -s からのコマンドラインで、/etc/samba/smb.confじゃなくて、他のファイル
をSambaの設定ファイルにしてしまう事が出来るんですよね?
これはこのコマンドを1度実行して、再起動しても恒久的に変更が反映されますか?
それとも起動時に毎回実行する必要がありますか?
今2つ希望が見えました。とにかく検証してみます。本当にどうもありがとうございます。
mv abc def をしたら、 symlink -> abc も symlink -> def に変えるスクリプトを、出来るもんなら作ってみろ
mv $1 $2 ln -sf $2 symlink
いけず
KENT-WEB からもらってきて改造して使ってる perl の CGI で生成される掲示板の log ファイルから、 最新の記事一つを抜き出す簡単なスクリプトを作り、html に埋め込んでいます。 そのスクリプトは以下のような具合です。 #! /bin/sh head -n 1 /var/www/html/ore/bbs/bbs.log | cut -f 6 bbs.log ファイルの中で、6番目のカラムが記事の本文が格納されたカラムです。 このままですと、記事全文が抜き出されてしまうのですが、文頭から文字数指定で、 例えば100文字のみ抜き出し、などというのはどう表現するのでしょうか?
head -c 200
>>805 それだと200バイト目で2バイト文字がぶった切られるケースもあるんじゃないの?
echo 'あいうえお' | head -c 5 moge | iconv -f euc-jp -t euc-jp 2> /dev/null | od -tx1 まぁ文字といってるからには200バイトではないんだろうが。
すみません、スクリプト中で自分がバックグラウンドで動いているかどうか判定したくて jobsを使おうかと思ったのですがjobsは呼び出したプロセスの子しか判定しないみたいで自分の状態が取得できません。 何か自分がバックグラウンドで動作してるかどうか調べる方法はないでしょうか?
バックグラウンドかフォアグラウンドかというのは OS ではなくて シェルが管理しているものなので、どういう状態かを知っているのは スクリプトを呼びだしたシェルだけ。呼び出された側から知るのは不可能。
>>809 完璧ではないがNICE値で判断するっていう手もある。
バックグラウンド走らせたプロセスは大抵そのシェルよりNICE値が大きくなるから。
>>809 なるほどやはりそうでしたか。
状態で処理を変えるような設計自体悪い気がするので別な方法を考えてみます。
>>810 バックグラウンドで行うとシグナルを出すコマンドを使って判定しようかとも思いましたが
bg->fgにした際の判定等色々な問題でやめました。
そこまでするぐらいならやはり別な仕様にした方が良そうですし。
どうもありがとうございました。
猫バトン用フィルターを作ってみにょ。 >『猫バトン』 >○これが回ってきたら次に書く日記の語尾すべてに「にゃ」「にゃん」「にゃー」等をつけにゃくてはにゃらにゃい。 >○「な、ぬ」も「にゃ、にゅ」にすること。 >○一人称は必ず「我輩」にすること。
ユーザ毎のメモリ消費量を表示させたいのですが いい方法はないでしょうか?
共有ライブラリなんかは、複数のユーザやプロセスで 共有されと思うんで、実際に正しい使用量を把握するのは 難しいと思われ。
815 :
login:Penguin :2007/05/28(月) 01:26:46 ID:djvYxPmr
質問します。 lsnrctl<<EOF set log_file listener.tmp exit EOF RET=$? if [ $RET -ne 0 ];then logger -t tagtag -p local1.notice "切り替えに失敗しました" exit 1 fi とエラーが出たときにSYSLOGにメッセージを表示させ 異常終了させたいのですが、どうもエラーがでてしまい うまく動きません。 何か対処法はありますでしょうか?
>>813 top -b -n 1
を加工するとか。
817 :
813 :2007/05/29(火) 16:06:22 ID:qaFgFmD3
>>814 なるほど、その通りですね
>>816 今期はこれで十分です
これ使えば簡単ですね。
ありがとう
Makefileを作成中なのですが、ディレクトリの移動方法が分かりません。 cd /usr/lib pwd としても、現在のカレントディレクトリのパスが表示されてしまいます。 make.shを作成して cd /usr/lib pwd を書いておくと、こっちのほうでは成功するのですが・・・
cd /usr/lib; pwd
>>818 Makefileは確か、コマンド記述した行の一行一行ごとにシェルを起動して、その中で
コマンド実行する。だからcdとかsetenvするなら一行にまとめて書く必要がある
>>815 エラーの内容は?誰が出してるの?リスナー?ロガー?それともシェル自身?
パーミッション755 のホームディレクトリを 700へ強制変更したい場合、 どのようにすればよいでしょうか?
824 :
822 :2007/06/07(木) 18:54:10 ID:SgVASGqq
説明不足でした、755のパーミッションである ディレクトリ「のみ」を変更したいです。
>>824 find ~ -maxdepth 0 -perm 755 -exec chmod 700 {} \;
>>825 それだったら、755の実行ファイルも700にならないか?
find ~ -maxdepth 0 -perm 755 -type d -exec chmod 700 {} \;
>>826 -maxdepth 0 だから対象は ~ だけだよ。
>>823 はディレクトリ(入れ物)のパーミッション変更
>>825 はディレクトリからfindした一個一個のファイルディレクトリのパーミッション変更
>>831 見落としたwwww
違いはファイルかディレクトリかではなくて、 -perm 755が入っているかどうかの部分か
-maxdepth 0 だから、~のみしか変更されないから chmod 700 ~ と同じで合ってるよね?
835 :
login:Penguin :2007/06/13(水) 22:10:59 ID:cYyJ3pdD
ファイルの先頭2行分を削除したいんですが、 sedでできますか?
836 :
login:Penguin :2007/06/13(水) 22:57:55 ID:1QPMUNje
>>835 awk で良ければ awk '(NR>2')' FILE
>>835 836はセミコロンが一つ多かった・・
あと、いきなりFILEを変更したいなら
perl -pi -e 'undef $_ if($.<=2)' FILE
sed -i 1,2d FILE
先頭を削除ならsed単独でいいけど、 後ろになると、sed単独では無理かな?
>>840 2行でいいなら sed '$d' | sed '$d' で。
842 :
login:Penguin :2007/06/13(水) 23:55:59 ID:cYyJ3pdD
>>836-840 ありがとうございます。
sed、awk、perlと使いこなせれば凄い便利ですね。
勉強します。m(_ _)m
>>840 できるよ。hold spaceを直前N行を保持するキューとして使う。
たとえば末尾3行を落とすなら
sed -e '1h;1!H;1,3!{g;P;s/[^\n]*\n//;h;};d' file
キーコードを発行するスクリプトって、どう書けばいいのでしょうか。 例えば実行するとfirefoxにCTRL+Qを発行して終了させるとか。
X上のという意味? 自分は crikey というのを使ってるけど。目的のウィンドウに送るには、 ウィンドウマネージャの機能と組合せる必要があるかもね。 自分は fvwm だから FvwmCommand + crikey でやっている。 今ならもっと便利なものがあるんじゃない。
終了したいだけなら pkill firefox-bin でいいんじゃね?
そりゃそうだが、単に終了する例を出しただけだろう
848 :
844 :2007/06/16(土) 09:33:29 ID:f0v0sW7Q
説明が不十分ですみません、ありがとうございます。 crikeyでいけそうです、使ってみます。
if mythshutdown -s then sleep 0 else exit fi (続きの処理) こんなスクリプトを書いています。 sleep 0って無駄なので止めたいのですが、 他にいい方法ありますか?やりたい処理はmythshutdown -sの 戻り値が0の時は続きの処理に行って、0以外だとその値を スクリプトとして返したいのです。
850はたぶん $? のことを教えたかったんだと思うけど、 849のような場合はふつー使わない。 とりあえず、「何もしない」という処理を書きたいのならば、 :(コロン1個)を使う。 あるいは、この場合はいっそ if を使わず以下で十分。 mythshutdown -s || exit
スクリプトと関係ないけど
>>846 のコマンド、pkillって便利ですね
他界したまま戻ってこないアプリを
叩き落とすのに便利でした
便乗でありがとう
>>852 killallってのもある。
特にSolarisでの便利さは異常。会社のサーバで是非rootで実行してみよう
実行中のシェルをバックグラウンドにするには、一度CTRL+Zで中断してbgコマンドでバックグラウンドにするしか方法はないですか? 中断させずに実行中のシェルをバックグラウンドにする方法があれば教えてください
>>854 アンパサンド?
screen使うとか?
アンパサンド?って&これのことだったのね シェルを実行時に文末につけるとバックグラウンドで実行が始まるのは知ってますが 実行中のシェルもバックグラウンドにできるのですか?
>>857 スマン。一番下の行しか読んでなかった。
screenなら君の要件を満たせると思う。
>>858 screenについて簡単に調べてみました
これはscreen上で実行しているシェルなら別の端末エミュレータに切り替えることができるという感じのようですね
シェル実行前にかならずscreenを実行するくせをつけてあれば使えそうですね
ありがとうございました
先ほどの質問に、関係するのですがもう一つ質問があります
SSH上でシェルを実行しているときに、フォアグラウンド、バックグラウンド問わずSSHが切断されてしまうと
再度SSHで接続して確認すると、psコマンド上からはバックグラウンドでシェルが動いているように見えるかと思いますが
このシェルをフォアグラウンドに戻すことは可能なのでしょうか
screenコマンドを使っておけば、SSHの再接続後でもフォアグラウンドに戻すことができるのですか 御意見参考にさせていただきます スレ違いすみませんでした
そうです、screenのせいで 仕事を家からのSSHに持って帰れるようになってしまったのです。
仕事場から自宅の鯖で遊びたいという用途にもぴったしでs
Linuxわりかし初心者です。しつもん! 1) sedって標準出力がディスプレイみたいですが、読み出したファイルの行自体を変更って出来ますか? sed -e "s/a/b/" example.txt >>example.txt みたいな 行の指定の仕方がわかりません 2) ある行の内容によって、約10行前の内容を変更、みたいなのはできますか? <table> <td></td> ・・・ <td>テーブルを青くする</td> </table> とあったときに、 sed -e 's/<td>テーブルを青くする</td>/<table bgcolor="blue">/' みたいなかんじで 3) sed ""の""内で#には\要りますか? 申し訳ないのですが実機環境がないので試してみれません。 SEなのにそれってありえねーだろ!死!
1)-i 2)s/hoge\n(fuga)\n(piyo)/foo\n\2\n\3/ みたいのじゃ無理?試してないけど。 3)いらない。(#を区切り文字にしている場合は必要)
867 :
864 :2007/06/22(金) 02:28:38 ID:8IDYCEkA
>>866 1)
-iってオプション何処にも載ってないんですが・・・
結局.tmpふたつ作って行ったり来たりさせることに('A`)
3)
さんくす。こんなの試しにやってみれば一発なのに('A`)
2)
説明不足でしたが、元のファイルに
<table>〜</table>で囲まれた同じような表がたくさんあって、その中の一部に
<td>青</td>ってあったら<table bgcolor="blue">
<td>赤</td>ってあったら<table bgcolor="red">
的な変換がしたかったのです(本当は全然違うけどイメージ的にこんなの)
結局↓みたいに相当力押しに書いてしまったんだが動くのやらどうやら
"s/<table>\n\(<tr>.*<\/tr>\n)*\)\(.*[^青]\)/<table bgcolor=\"blue\">\n\1\n\2/g"
>>865 こんな便利なのあるんだ!やってみる!thx!
>-iってオプション何処にも載ってないんですが・・・ sed --helpか、 LANG=C man sedしてみな
csvのn番目のフィールドがある値の物のみ抜き出すのってどうやりますか? 例えば aaa,bbb,ccc,ddd www,xxx,yyy,zzz 111,bbb,222,333 で2番目が"bbb"の物だけ抜き出すと aaa,bbb,ccc,ddd 111,bbb,222,333 って感じです。 sed '/^[^,]*,bbb,[^,]*$/p' とかやってみたんですが、100番目がXXXの物を抜き出したいとかやろうと思うと気が遠くなりそうだったので…。
awk -F, '{if($2=="bbb")print $0 }' FILE
csvはちょっと面倒臭いので、それ専用のperl libとかで扱った方がエエかも。 面倒臭い例→"a,aa",bbb,ccc,ddd
>>869 >>871 みたいな例はPerlとか使うのがいいけど、フィールドにカンマや改行を含まないCSVなら
awk -F, '{print $2}' csvfile
でどうだろう。
$100ができるかはawkの実装によるかも。
Linuxならgawkだろうから大丈夫だと思うけど。
873 :
872 :2007/06/23(土) 11:38:40 ID:dKiUoK3M
すまん。870を見落としてた。無視しといて。
ある文字列の出てくる行からある文字列が出てくる行までを削除 ってしたいんだけどやり方がわからんちん
>>874 aaaが出てくる列からbbbが出てくる列までを削除したいなら
sed '/aaa/,/bbb/d'
#!/bin/sh FTPFILEDIR=/home/hogehoge;ftp -niv < ftpcomd.txt ==ftpcomd.txtの内容== open 192.168.0.50 user nurupo gattu cd $FTPFILEDIR/fugafuga binary bye これだとftpcomd.txt内の環境変数を実行時に 置換($FTPFILEDIR⇒/home/hogehoge)してくれないですよね・・・ なにかいい方法あるでしょうか?
環境変数になってないじゃん
あ、本当ですね・・・ミス・・・ まぁ、そこはexportしてると行間を読んでくださいw
>>878 目的はファイルのputですか?
FTPFILEDIR=/home/hogehoge; ncftpput -u narupo -p gattu -v 192.168.0.50 $FTPFILEDIR/fugafuga ファイル名
880 :
878 :2007/06/30(土) 01:04:10 ID:ew4CTk9S
>879 質問の意図が曖昧ですみません。 背景として、FTPコマンドが記述されたテキストファイルが現在 大量に存在しており、それをできる限り有効活用したいのです。 同種類のFTPコマンドがあちらこちらのシェルで利用されるので、 シェル内に直接コマンドを組み込むことはできるだけ避けたいと思っています。 従って、目的は 「既存のFTPコマンドテキスト(変数含む)を、シェルで読込んで実行したい。」 です。 FTPコマンドテキストをサブシェル化するしかないですかね?
882 :
878 :2007/06/30(土) 01:46:19 ID:ew4CTk9S
>881 それもあんまりスマートじゃないですよね〜(ごめん) 一応、下のような方法は考えています。 #!/bin/sh FTPFILEDIR=/home/hogehoge;export FTPFILEDIR;sh ftp.sh ==ftpsh== #!/bin/sh ftp -niv < <!! open 192.168.0.50 user nurupo gattu cd $FTPFILEDIR/fugafuga binary bye !!
シェルにftp組み込むってすげーな。 わかってるけど。
>FTPFILEDIR=/home/hogehoge;export FTPFILEDIR;sh ftp.sh ↓ FTPFILEDIR=/home/hogehoge /bin/sh ftp.sh
(echo "ftp -niv <<END"; cat ftpcomd.txt; echo "END") | sh 試してないけど
#!/bin/sh cd $FTPFILEDIR/fugafuga ftp -niv < ftpcomd.txt ftpcomd.txtにcd ... の行は含まない
887 :
878 :2007/07/01(日) 01:24:33 ID:emR+Frn5
いちおうレス
>>884 ???
>>885 うまくいかない
>>886 うーーん・・・俺の質問の仕方が悪いのか・・
求めてる回答はそうじゃない・・・
本質的には、
「標準入力からのリダイレクト時、読み込むファイル内に記述された
環境変数を変数値で置換して入力したい」
と言うのが要件なんだが・・・
まぁSEDやAWK使えって言われたらそれまでなんだが
えう゛ぁるなよ
889 :
878 :2007/07/01(日) 11:36:38 ID:emR+Frn5
スマソ そういうつもりじゃなかったんだが、 酔ってたので 文章に配慮が足りなかったな 不愉快にさせてたらゴメン・・・ 回答くれた人には感謝しています。
eval でどうにかしろという意味かと思ってた。
evalか。 理屈は簡単で便利なんだけど、見にくくなるからなぁ。
1 0:05 2 0:08 3 0:10 4 0:03 5 0:02 6 0:09 7 0:12 8 0:05 とかかれているファイルの2カラム目を 集計したいんですが どうすればいいですか?
>>892 perl かなんかでスクリプト書いちゃいなよ。
>>892 for x in `cut -d ' ' -f 2 file`; do 集計;done
「集計」が何をしたいのかわからん
MM:SS形式?の値を同形式で単純集計したいってことじゃ? 数値でなくMM:SS形式ってのがポイント・・・か?
cat /tmp/test.txt | gawk '{split($2,t,":"); sum+=(t[1]*60+t[2])} END{printf("%d:%02d\n", int(sum/60), sum%60)}' これでどうかな?
イヤだ。catしてるのがイヤだ。
catキタ━━━━━━(゚∀゚)━━━━━━ !!!!
なぜ喜ぶ?
俺もここで指摘されてから cat hoge | awk とかが凄く目につくようになった。
cat walk と空目した
本題を忘れてたw
>>897 なんでcatしたらイヤなん?
キャッキャッ
>>896 深い意味はないけど。一行スクリプトをコマンドライン上で編集繰り返すとき、中身(スクリプトの部分)が
最後のほうに固まってると編集しやすいし、あと行末に何もついてないとちょっとだけ見やすい。
完成したら、あとは前からcatで流し込もうがawkのパラメータとしてファイル名を渡そうが同じことだから
好きにすればいいんじゃねえの?
行末に何もついてないちょっとだけ見やすいcat例。 $ cat file | cat
後付けで言い訳するなw
いや、かわいいしw
ハム太郎「はっ(;゜Д゜)!背中に殺気!」
>>905 頭に cat を使う理由がそれだけなのならば
< file cmd という形式のリダイレクトを使えばいいんじゃね。
cmd < file と等価。
ちなみに、cmd < file arg と cmd arg < file も等価。
よーするに、どこにあってもいい。
でも < /etc/hosts { sort; } とかはできないんだよなぁ。
zsh はできるな
よし!暇だからLinuxで動くcmd.exeのクローンを作るぞ
Windows CEで動くbashを作ってくれよ。 さらに暇があったらcygwin CEも。
いまさらCE?
シェルって自由度高すぎて返って難しいよな 結構人によって癖があるし。 そんな漏れは割りとcat好き 理由は905とほぼ同じ?前から後ろにつなぐので個人的には直感的に書ける(ように感じる) スクリプトとして保存するときは、リダイレクトにするけど
どうでもいいが・・・ このスレを見ている人はこんなスレも見ています。(ver 0.20) シェルスクリプト総合 その8 [UNIX] サイレントナイト翔 第2翔 [懐かし漫画] ⇒なんじゃこりゃw HSP - Hot Soup Processor [15] [ゲ製作技術] まぁせっかくなので sed s `/聖衣/シェルター/g' 聖闘士星矢 > サイレントナイト翔 (わかる人少なそう・・・)
自分もサイレントナイト翔スレを覗いてるw 専ブラ使ってるから自分の痕跡じゃないな
青い鳥の神話スレはここですか?
route |grep -E '^220\.210\..+UH.+ppp[0-9]$' とかやると、 220.210.xxx.xxx * 255.255.255.255 UH 0 0 0 ppp1 てなるのでつが、 いちばんうしろの ppp? の部分だけぬきだしたいでつ。 たすけて。
922 :
login:Penguin :2007/07/04(水) 07:17:51 ID:YyHq/MNx
各行の先頭単語を読みこみ、シェルスクリプトの変数に代入する スクリプトを考えているのですが、特定の行を読むところでつまづいています。 while let "${var1} <= 6" do #whileの変数である「${var1}番目」の行を読み込もうとしています DIR=`awk 'NR==${var1} {print $1}' pnl.txt` mkdir ${DIR} var1=$(expr ${var1} + 1) done どう書けばうまくいくか教えてください!
923 :
992 :2007/07/04(水) 08:04:36 ID:YyHq/MNx
と思ったらできました!こうやりました names=`awk '/^/ {print $1}' pnl.txt` for DIR in ${names} do mkdir ${DIR} done
>シェルって自由度高すぎて返って難しいよな ここに空白が(あるとダメ|ないとダメ) とか、 ここで改行(しちゃダメ|しなくちゃダメ)とか そういう自由度は低いけどね。
925 :
login:Penguin :2007/07/04(水) 20:45:32 ID:kum5iDid
>>992 こんなんいかがですか?
awk '{ print $1 }' pnl.txt | while read d; do mkdir $d; done
awk '{ print "mkdir $1" }' pnl.txt | sh (-x)
926 :
login:Penguin :2007/07/04(水) 20:53:43 ID:kum5iDid
>>921 awk '{ print $NF }'
マッドスプリクト
sedとawkじゃないかも知れないけど。 -hoge a b -fuga d e のようなファイルがあって、 -hoge a b -fuga d e のように出力出来ますか? csplitでファイル分割して、全てのファイルの改行を取れば出来るのですが、 中間ファイル作りたくないし、これが実現出来るコマンドがありそうな気がしたので。
>>929 sed s/$/" "/ file.txt |tr -d "\n" |sed s/" -"/"\n-"/g|sed s/" $"//
行末にスペース | 改行を取り除く | "スペース-" の部分で改行 | 行末のスペースを取り除く
sed 'N;N;s/\n/ /g' hoge これはあんまり一般的なやり方じゃねぇか?
933 :
login:Penguin :2007/07/06(金) 20:31:13 ID:zgIWnM6p
GNU sedオンリーだったかな?・・・\n Linux板だからいーんじゃ? Unix板だとperl使えか?
\nはPOSIXでも規定されているし大抵の環境で使える筈。
普通に考えれば
>>932 が順当。
じゃあ、順当じゃなく。 fmt hoge | tr '-' '\n-'
cat /tmp/test.txt | gawk '/^-/ && NR!=1 {print""} {printf($0" ")} END{print""}'
>>929 awk で
{
if ($0 ~ /^\-/ && NR == 1) {
printf("%s ", $0);
} else if ($0 ~ /^\-/ && NR != 1) {
printf("\n%s ", $0);
} else {
printf("%s ", $0);
}
}
END {
print "";
}
938 :
login:Penguin :2007/07/07(土) 08:39:22 ID:niJj2YwU
>>937 状態遷移で改行の制御にしてみた
BEGIN {nl=""}
/^-/ {printf("%s%s", nl, $0);nl="\n";next}
{printf(" %s", $0)}
END {printf("\n")}
ファイル名をすべて小文字にしたいのですけど、 これはCなどのプログラムを書かないとできませんか?
>>939 こんなんでいい?
perl -e '$f=$ARGV[0]; rename $f, lc $f' FILENAME
#!/usr/bin/perl while (true) { rename($_, lc($_)); } # こうですか!? 分かりません><
zshで autoload -U zmv; zmv '(*)' '${(L)$1}' renameで rename '$_=lc($_)' *
943 :
login:Penguin :2007/07/07(土) 14:35:03 ID:niJj2YwU
ls | while read f; do nf=`echo $f | tr 'A-Z' 'a-z'` mv $f $nf done for f in `ls` はファイルが多いと死亡するのでX
>>940 ,941
perlはあまりわからないですけどできるのですね。
>>942 autoloadははじめてみました。
>>943 あ、自分がやったことがあったのはこれだ。trと言うコマンドでした。
たまたま同じ小文字のファイルがないか注意してやります。
945 :
login:Penguin :2007/07/07(土) 18:22:07 ID:niJj2YwU
perlはshellスクリプトのアンチテーゼ。 perl -pe -i の破壊力は強力だけど、諸刃の剣。 awkで済むものはawkでやるのがいいかな? awkの入力駆動はある意味、最高。
awkいいんだけど 正規表現が貧弱
947 :
login:Penguin :2007/07/07(土) 18:34:21 ID:niJj2YwU
>>944 [ ! -f $nf ] && mv $f $nf
or
[ -f $nf ] && continue
mv $f $nf
948 :
login:Penguin :2007/07/07(土) 18:40:57 ID:niJj2YwU
>>946 perl:高度な文字列操作中心orループ速度が高速でなくてはいけない場合
sh:ファイル操作中心orループが低速でいい場合
で使い分けてる
shは明示的にファイルをオープン・クローズしなくてもいいんで、
perlよりもステップが減るケースが多いから。
このスレってsedとawkのスレだと思っていた。スレタイ紛らわしいな。
次スレはそんなことないよう、適切なスレタイでお願いします。
>>950 さん!
申し訳ありませんでした。 次は 【csh】シェルスクリプト総合@LINUX Part3【tcsh】 とします。
>>950 あとPowerShellも足しといてくれ
>>950 それだと、B-shell系が除外されてるみたいだよ
【csh】シェルスクリプト総合@LINUX Part3【sh】
で。
>>950 はネタでしょ。
まぁ、単に「シェルスクリプト総合 Part3」でいいんじゃね?
でも*shでスレタイ検索できるとうれしい
関数で返り値を返すにはどうすればいいんだ? foo(){ # ここで文字列を返したい } baz=`foo $1`
foo(){ # ここで文字列を返したい echo "氏ね" } baz=`foo $1`
foo(){ # ここで文字列を返したい echo "ボクの肛門も返り値にされてしまいそうです。" } baz=`foo $1`
>>943 > ls | while read f; do
> nf=`echo $f | tr 'A-Z' 'a-z'`
> mv $f $nf
> done
すばらしい。これ、ディレクトリを再帰的にたぐるバージョンできないかしら。
>>959 find ./ -type f -exec "f={}; nf=$(echo $f | tr 'A-Z' 'a-z'); mv $f $nf"
じゃだめなの?
961 :
960 :2007/07/09(月) 23:30:19 ID:lRpzjg90
最後につける \; を忘れたorz
こんな感じ?(動かしてないのであれだけど) lcdir() { for i in "$@" do test -d "$i" && (cd "$i" && lcdir *) mv "$i" "`echo $i | tr A-Z a-z`" end } lcdir dir
find /path -type f | awk '/[A-Z]/{print "mv", $0, tolower($0)}' | sh
>>948 >sh:ファイル操作中心orループが低速でいい場合
ループが必要そうに見えてもうまくやればなくせることが多いし、
起動されるコマンドの数を減らせば遅さはカバーできることがほとんど。
965 :
929 :2007/07/10(火) 07:16:10 ID:ejVmm0rs
俺なら頑張っても 「やべ、Basicまざった」 位しか言えないな、、。
begin〜endといえば、Pascalだろ。
969 :
login:Penguin :2007/07/10(火) 22:10:27 ID:vliNJz3h
>>964 こつじゃないけど、デバッグ中は
echo mv $f $nf
これなら実行しないで、実行されるコマンドのみ確認できる
何とかの知恵袋
970 :
950 :2007/07/10(火) 23:24:32 ID:qGthZdME
>>968 begin ないじゃん。
do 書いたから多分Rubyになっちゃったんだろうな。。
972 :
login:Penguin :2007/07/11(水) 04:19:18 ID:tJ7VLZ7p
sed、awkスレじゃないので次のスレタイは適切なのたのむ
>>971 へぇ〜知らんかった。
do〜beginってキモイねw
974 :
login:Penguin :2007/07/11(水) 13:30:14 ID:tP/pX7fg
sedでhtmlファイル内のURLリンクだけ抜き出したいのですが、 うまくいきません。 sed 's/http[^html]*html//g' こんな感じの処理を、これ以外を処理するという感じに書けませんか? 教えていただけるとありがたいです。
grepとパイプで徐々に条件を絞りこんでいけばええんとちゃう?
>>974 頼むからまともなリファレンスの一つも見てくれ orz
[^html]はないだろうよ。
GNU sed だったら -P オプションつけて Perl互換の正規表現使って書け。
それ以外ならあきらめれ。
grepとawkで出来るだろ。なんでsed
そこにsedがあるから
awkで出来るならgrep使う意味もあんまり無いけどな。
>>980 awkを
grep なんとか | awk '{ print $1,$2}'
みたいに行分割ツールだと思ってるやつ、いるな。もうちょっと勉強しろと。
そんな俺のお勧めの本は本家awk作者の書いた高い本じゃなくてASCIIの
「awkを256倍使う本」(オレンジ本)だ。昭和の時代からある本だが、未だに増刷版が
手に入る。これを通読すれば、awkのことは大体わかる。ふざけた口調だし、DOS時代の
記述が目に付くような骨董本だがな。
>>981 このスレ見てるとsedの方もsとdぐらいしかコマンドがないと思ってる奴多いじゃん。
あとGNU拡張かもしれんがgrepの-Aと-Bは何げに便利。
awkは配列が便利だ