シェルスクリプト総合 その1

このエントリーをはてなブックマークに追加
1前スレ950
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。

まずは注意点、リンク、地鎮祭など(>>1-10くらい)をご覧ください。

□前スレ:
☆シェルスクリプトを勉強するにあたって☆
http://pc5.2ch.net/test/read.cgi/unix/989659936/

便利なシェルスクリプト見せろ
http://pc5.2ch.net/test/read.cgi/unix/996949546/

□関連スレ:
【貝】第1回シェル講座【殻】
http://fun.kz/test/read.cgi/unix/1016372780/ (過去ログ)

おまえら! shell は何を使っているんですか?
http://pc5.2ch.net/test/read.cgi/unix/1012330865/

□みんなのお約束:
・特記なき場合はbourne shがデフォルトです。
 bash/csh/zsh/kshなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashなので特に注意。

・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
 manを見ましょう。
 aproposないしはman -kでそれらしい単語による簡単な検索もできます。
 シェルの構文や内部コマンドはman shで。

・シェルスクリプトのことをシェルってゆーな
21:04/11/30 22:18:09
□参考リンク:
Bourne Shell自習テキスト
http://www.tsden.org/takamiti/shText/shText.html

シェルを使おう
http://www.netfort.gr.jp/~tomokuni/lms/shell/text/

/bin/shプログラミング入門
http://freebooks.info.nara-k.ac.jp/archive/ShellProgramming/

なぜcshでプログラムを書くのが良くないのか
http://www.klab.ee.utsunomiya-u.ac.jp/~hiroki/csh-whynot.euc

UNIX FAQ (ただし翻訳はいささか古いです)
http://www.nurs.or.jp/~asada/FAQ/UNIX/UNIX.FAQ.html

UNIX Programming FAQ (シグナルとか使うときは参考になるかも)
http://www.adl.nii.ac.jp/~moro/unix-programmer/faq-j_toc.html

UNIX関係FAQ色々(英語です。UNIX FAQの最新版もあり)
http://www.faqs.org/faqs/unix-faq/

UNIX系各種OSのman page検索
http://www.freebsd.org/cgi/man.cgi

POSIX: Shell & Utilities (標準規格)
http://www.opengroup.org/onlinepubs/009695399/utilities/contents.html

UNIXの部屋 (沢山のコマンドの簡単な紹介など)
http://x68000.q-e-d.net/~68user/unix/
31:04/11/30 22:18:28
□おすすめ書籍:
プロフェショナルシェルプログラミング
http://www.amazon.co.jp/exec/obidos/ASIN/4756116329/

入門UNIXシェルプログラミング―シェルの基礎から学ぶUNIXの世界
http://www.amazon.co.jp/exec/obidos/ASIN/4797321946/

UNIXシェルプログラミング徹底解説
http://www.amazon.co.jp/exec/obidos/ASIN/4822280489/

入門Kornシェル
http://www.amazon.co.jp/exec/obidos/ASIN/4873110149/

入門bash
http://www.amazon.co.jp/exec/obidos/ASIN/4900900788/


□初心者へのアドバイス:
・ここにあがっているような書籍を読んで基本を理解したら、
 /etc/rcなどの実際に使われているスクリプトを読もう。
 (※Linuxのinitとかはbashゴリゴリなので最悪との指摘もあり)
 あと、リダイレクトや引数の扱い(echo * の意味など)を完全に理解しよう。

・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。

・知らないコマンドが出てきたらmanを引きましょう。

・思い通りに動かないときは、まずは sh -x でトレースしましょう。
41:04/11/30 22:19:00
□シェルスクリプトでよく使うコマンド:
制御・条件判定系:
[とtest, expr, true, false, yes, getopts, apply

テキスト処理系:
cat, awk, sed, tr, sort, uniq, grep, wc, head, tail, cut, paste, comm, join

ファイル名・ディレクトリ系:
find, xargs, basename, dirname

出力系:
echo, printf

対話コマンド制御系:
expect, でも単にftpしたい奴は素直にwget使っとけ
51:04/11/30 22:19:39
あ〜緊張した。なんとか立てられてよかったです。

それではまたーり参りましょう。
>>1 スレ立て乙です。
次はこれも入れるといいかも。わたしは自習テキストとこれで勉強しました。

「誰にでも」シリーズ
http://kanji.zinbun.kyoto-u.ac.jp/~yasuoka/publications/dareUni/
ちょっと古いし入手難だがUNIXプログラミング環境も読みたいところ
フィルタプログラミングがわかればシェルスクリプトの心もわかる
http://www.amazon.co.jp/exec/obidos/ASIN/4871483517/
81:04/11/30 23:24:22
前スレでテンプレの相談したときにおっしゃって下さい (´・ω・`)
ま、テンプレは網羅することが目的ではないので……
>>1
ハイパー乙
サンプルがたくさん置いてあるところは無いかと検索すると
ここがやけにひっかかりますが、どうなんでしょうかね

Wicked Cool Shell Scripts: The Library
http://www.intuitive.com/wicked/wicked-cool-shell-script-library.shtml
>>7
名著だけど、今からシェルやらなきゃって人に
最初に勧める本ではないと思う

多少書けるようになった頃に読むと卓効、という感じ
>>1
Z(・∀・)イイ!!
>>1
乙です!
タイトルもシンプルでいいと思います。
久々に良い>>1のスレだ

お疲れ様
>>8
>>11も言ってるようにやっぱり古すぎるし、
テンプレに入れるほどでないので、テンプレ外でひっそり書いてみた。
次回もテンプレからはずしておいてくれ。
>>1
乙!
質問です。偽コンソールログインを洒落で作っておりますUNIXユーザ1年生です。使用shはcshです。
コンソールログインの画面みたいな状態にして、
login: <-ここの行に入力を行い、
passwd: <-ここは入力しても画面には出力しないであたかも本当にパスワード入力画面みたい
んな感じで、エンターすると
You are an ideot.hahaha by 俺
って表示して自分のログインシェルを強制killして、騙された人のidとpassをゲットするというのが夢です。
で、考えてみたのが下です。

#!/usr/bin/csh -f
clear
banner 'logout'

echo 'console login'
set ID=$<
echo $ID >> $HOME/list
echo '$ID password:'
set PASS=$<
echo $PASS >> $HOME/list
sleep 1
echo "You are an ideot.hahaha by ore"
sleep 1
set END='ps auwx |grep 私のID|grep tcsh|awk "{print $2}"|sort|head -n 1'
kill -9 $END

コレですと、loginをechoしたあと自動的に改行してしまうのがまず悩みです。
また、入力した変数$IDの中身もecho表示できない、HOMEのlistに文字が送られてなかった、自分のプロセスを自動的に
消して強制ログアウトしてくれない、という悩みつきです。最期のset END=.....killまでは、logoutでいいかなぁと思ってます。
教えてクンで申し訳ないです。よろしくお願いします。
あと、決して好きな子のパスをゲットしようとか企んではいません。ごくごく健全な大学1年です。なにとぞ。
あと、前期で初めて作ったシェルスクリプトですが、殆どどこかのサイトにあったソースのパクリですが、厨らしくて
よろしいと思ったので晒します。

#! /usr/bin/csh -f
echo 'へいらっしゃい!'
sleep 1
echo 'ラーメンの待ち時間は? 1:3分、2:4分、3:5分'

set t=$<

if ($t == 1) then
echo "$t 番を選択したよ。3分まっててね"
sleep 170 && perl -e 'print "\x07"; print "カップラーメンできますた\n"'
exit(1)
else

if ($t == 2) then
echo "$t 番を選択したよ。4分まっててね"
sleep 230 && perl -e 'print "\x07"; print "カップラーメンできますた\n"'
exit(1)
else

if($t == 3)then
echo "$t 番を選択したよ。5分まっててね"
sleep 290 && perl -e 'print "\x07"; print "赤いきつねできますた\n"'


endif

スレ汚しすみませんでした。精進します。
>>17
専門学校?
宿題 ?
>>17

そんなレベルです。将来はCadenceで回路図カリカリ作る学部です。
2217:04/12/01 01:36:02
まちがえました>>19 でした。


>>20

ちゃいます。シェルを勉強する授業なんてなかとです。
2317:04/12/01 01:54:36
夢はRuby使う生活ですな。寝ます。失礼しました。
新スレ立って一発目がideotか。
>>17 じゃないけど
ncftp などにパスワードをわたすとき
read pass; ncftpput -p $pass
ってなことをするために,
パスワードをエコーバックしないように
できないものかと思ったら,
ググったらすぐわかった.
>>17 cshは分からないのでshで。

#!/usr/bin/env bash
clear
banner 'logout'

echo -n 'login: '
read ID
echo ID=$ID >> $HOME/list
echo -n 'password: '
stty -echo
read PASS
echo
echo PASS=$PASS >> $HOME/list
sleep 1
echo "You are an ideot.hahaha by ore"
sleep 1
kill -9 $PPID
>#!/usr/bin/env bash

あんまりないと思うけど、複数の場所に bash がインストールされてる場合、
$PATH によってどれが使われるのか不定。
ruby の人がよく使ってるけど、あんまりよろしくないと思う。
#!/usr/bin/env 〜 だとbashとかのパスを調べる必要がないようにという
つもりだろうけど、本来はインストールスクリプトで固定すべきものを
サボっているだけだと思う。

環境変数によって挙動が変わるとか、スクリプトはPATHの中にあるのに
rubyやらbashやらpythonやらにPATHが通ってないと動かないというのは
あまりよくない。
そもそも"shで、"と書いてあるのにbashなのは
別途犬板にbashスクリプトのスレを立てると
事がなにかとスムーズに運ぶのかも。
311:04/12/01 21:23:32
>>30
ぜひ誰か立ててください。
実は関連スレに載せようと思ってテンプレ作ってるときに探したんですが、
見つからなくて諦めたんです。
32名無しさん@お腹いっぱい。:04/12/01 21:33:20
犬板にスレ立ててレベルの差別化を図った結果、
あちらのほうが情報量が多くなるのが最近の傾向
3326:04/12/01 21:37:57
>>27
/bin/bashと書くとlinuxがどうのこうのと言われると思ったので。
>>29
すまん。shで書こうと思ったら、$PPIDがshにはなかった。
341:04/12/01 21:45:36
>>32
お互いにS/N比の向上(sh/bashの棲み分けや、煽りとかの削減含む)が望めれば、
あちらのスレが発展するのはこちらにとっても結構なことではないでしょうか。
副作用としてどういうレベルの人たちに最適化されるかという違いができるかも
知れませんけど。
両方見るのめんどくない?
向こうを見るつもりあるの? 俺はない。
こっちがまったりのんびりいけるようになれば万々歳。

いっそのこと、これからスレは全部 linux 板に立てることにしようよ。
Linux板にはへんなスレがあるよ。
新しく立てたほうがいいかもしれないけど。

【Shell】どのシェル使ってる?【Script】
http://pc5.2ch.net/test/read.cgi/linux/1067330754/l50
1 :login:Penguin :03/10/28 17:45 ID:DZdBw1H1
おまいらが使ってるShellを晒せや(#゚Д゚)ゴルァ!!
そして便利なShell Scriptがあれば晒して( ゚Д゚)ホスィ…
GUI Shellも使ってる香具師はそいつも晒せ(゚∀゚)アヒャヒャ
>>26

ありがとうございます。むちゃくちゃ勉強になりました。
上は自分とこのワークステーションに入っているbashのパスを入れます。
read と echo の使い方が特に勉強になりました。
bourne again shell のほうが書きやすいのでせうか。。。うちはCやってるからtcshの方が趣味としてはいいかなと思ったのですが。

>>25
昨日の夜
エコーバックしないやり方を>>25のレスみてから調べてたんですが、自分には分かりませんでした。
むずかすい。
>>39
最後のkill $PPIDは洒落だろうから普通の/bin/shでいいっしょ。
>>39
>>26もエコーバックしないぞ。それと、スクリプトで(t)cshはよくない

なぜcshでプログラムを書くのが良くないのか
http://www.klab.ee.utsunomiya-u.ac.jp/~hiroki/csh-whynot.euc
うちの客先、oracleDBAユーザのログインシェルがcshになってて、スクリプト自体もcsh。_| ̄|○
ヒアドキュメントを与えてshを呼んでしまえ
four varieties of parameter expansion/substring processing.
どの説明みても、わけがわからなかった。

>>2のリンクにある
POSIX規格の頁のサンプルをみて、やっとわかた。
ttp://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html#tag_02_06_02_01


#!/bin/sh
DIR=curdir/some/where/down/deep/deeper/bottom

echo ${DIR##*/}
echo ${DIR#*/}

echo ${DIR%%/*}
echo ${DIR%/*}
1Gくらいのでかいバイナリの任意のバイトを書き換えるにはどのコマンド使えばいいんですかね?
エディタで開こうとしても無理っぽいのでどうしたものかと
dd
私ならmmapして直接書き換えるプログラムを書いてしまう。
と思いつつなにげにコマンドラインでmmap[TAB]とか叩いてみると、
知らんうちにmmapwとかいうコマンドが入ってたw

% mmapw -h

mmapw [-{bwlqL}] <file> <offset> <value>

endianness flags:

-b write one byte
-w write two aligned bytes
-l write four aligned bytes (default)
-q write eight aligned bytes
-L same as -l

xorg-serverについてきたらしい(FreeBSD)。
バイトオーダーも指定できるといいのにな。
-Eでbig endian, -eでlittle endianとか。
splitで編集できる大きさにバラせばいいのでは。
それをすすめると、ddで必要な部分だけ取り出せばいいのでは、ってことですね。
[じっけんしてみよう: ddでひつようなぶぶんをとりだす]
$ ed
a
あいうえお
かきくけこ
さしすせそ
.
w 001.txt
33
! dd if=001.txt of=002.txt bs=1 count=2 skip=15
読み込んだブロック数は 2+0
書き込んだブロック数は 2+0
2 bytes transferred in 0.023819 seconds (84 bytes/sec)
!
! cat 002.txt
く!
q
[じっけんしてみよう: heredocをつかう]

---きりとりせん----
#!/bin/sh
echo "[のりしろ]"
ed << EOF
a
あいうえお
かきくけこ
さしすっせそ
.
w 001.txt
!dd if=001.txt of=002.txt bs=1 count=2 skip=15
!cat 002.txt
q
EOF
echo "[のりしろ]"
----きりとりせん----
少し前にくだ質で出てたsourceで現在読んでるファイルのフルパスを知る方法って、
bashとか、シェルによっては特殊な方法が用意されていたりしますかね?

かなり無理矢理な方法としては、ファイルごとにユニークなキーを
magic=GYUUNYUUDAYOMON
みたいに埋め込んでおいて、lsofで開いてるファイルを調べて片端から$magicで
grepして引っ掛かったのがアタリ、というのを思い付いた。
元ネタを知らないから現在読んでるファイルのフルパスって意味がわからないんだけど、
FreeBSD なら /proc/PID/file
Linux なら /proc/PID/exe
とかいうこと?
>>53
そう。
cat /proc/$$/exe
>>54
元ネタ知らんが、おれは>>52から、

. foo.sh

した先の foo.sh の中で、自分が foo.sh かどうかを知りたいんだと
解釈したんだが、ちがうのか?
>>52
元ネタしらないけど。

history | tail -n 1 とかやって
pwd と組み合わせれば、フルパスの取得も可能かも。
元ネタ知ってるけど
http://pc5.2ch.net/test/read.cgi/unix/1101159381/507
最後まで{何故,何を}したいのか分からなかった。

エスパー解釈だと `dirname $0` かとも思うんだけど。
百者百様の解釈ですな。。。
6056:04/12/14 21:35:44
>>58
> http://pc5.2ch.net/test/read.cgi/unix/1101159381/507
おれの解釈が違っていたことがわかったが、
sourceという単語を使った>>52がアホだということもわかった
すげえ、読み進めるほど訳が判らなくなる…(w
>>56
いや、元質問者自体が途中から
>hoge?.shでは. ./base.sh として設定を読み込んでいます。
とか言ってるので、それをベースにすると>>52>>56も間違っていない。
6356:04/12/15 00:32:15
そうだったのか
アホよばわりして正直すまんかった>>52
フシアナと呼んでくれ
6452:04/12/15 16:19:00
zshだと知る術が用意されているようです。
setopt FUNCTION_ARGZEROした上で$0を参照すればいいらしい。

0 <S> The name used to invoke the current shell. If the FUNC-
TION_ARGZERO option is set, this is set temporarily within a
shell function to the name of the function, and within a sourced
script to the name of the script.
52=元質問者?
6652:04/12/15 17:18:20
ちゃいますよ。
私が元ネタの質問者ならあそこまでグダグダにはならんw
元質問者がlsof知ってるとも思えんし。
で、>>64の方法でフルパスは取得できたのか?
通常の$0と同じだろ。単独でフルパスになる必要はないと思われ。

気がついたら、こんなスクリプトが・・・。
だれかデバグきぼんぬ。

----BEGIN BASE64----(upkenget.sh.bz2)
QlpoOTFBWSZTWYLwQcEAAGHfgEAwf/f/Gj9v3o9////+QAHdktVlEFCHpAA00A2o
NDNQAAADI9QANRoTQGgRkZJk9TGoAHqBoGTQPSNDIcZMmhiMTRgEYCYQBgJpo0yN
AMMSQm1TNNJgRo9Rk09TTIaGgyMgaaABo4lyzxZ7kGXtpZNGh4DZByUJBM9gvbcg
gnQFMl+lgS4gd6n9sNrPAI4jhGnyzb+qh9b3qV1+Z8Qy+cUTV+iqArZ4zSTuZ9GZ
wuXGu+jCia+2DIG2Oc6qEqPFJ2z8ml7j5yPDXNLeydZ1CF4A/AjKFfwG+cdswxMm
AYooMyWTZzQZYDgFWgMWHLeqSiClGI6lAMB0I2kBvZA5wDFETsVSXqJ9NfNt2U7P
0QMQgYPFFVnw1ZItdN7OSGJqOSRhy6JtDzRALEuVj4mS3cQFiW4zZcw0SUz4DhMa
+LhvEHwAtBwIXTKqIoQ+gg8S5v1qHUpFlo9AoQXULgyFCkWtCJT5TvGecgEeUBxA
jcaDYMQlBF4gFrUfzTbB5Lg1yOgOz6pgDulpgfsB0lErLMAyCDJEB7g2IBQ6qA5D
HKr9CxdUTpl6RuneZYGsTNYlQslJFkoukm1k0ImArCEUaVCqC+sdVQbix6nnxl3Z
RVBt1xRUIurFtWY7toBmjIYNMK8KN4SERAxuiHG5Iyuo4X0bYLYWBldddwUBQdNW
3uHmxSEZqmrXSkzx3H2YzmmpOHRutiRzJIROe1g2jqsCnDGJK0KeKaF2RXIGU4H7
Eb/yl/i7kinChIQXgg4I
----END BASE64----
>>69 ですが、最後に wget を呼び出している行で \ の後に \x20 が入ってるので、
そいつを消してください。
こんなスクリプトも気がついたら手元にありますた。
情報を集約する意味で、リンク貼っておきます。

PukiWikiスレ Part1 / 515 cvssync.sh
http://pc5.2ch.net/test/read.cgi/php/1084907353/515-
$ mv *.txt *.doc

なスクリプト無いですか?どうも上手い方法が無くて困ってます。汎用性のある
シェルスクリプト誰か書いてませんか?

for f in *.txt; do
mv $f `basename $f .txt`.doc
done

そんなのでいちいちスクリプト書かない。
$ mv *.txt *.doc
usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
75./chsuff.sh txt doc:04/12/24 14:32:18
#!/bin/sh

for file in *.$1
do
 mv $file ${file%.$1}.$2
done
>>72

$ cat rename.sh
#!/bin/sh
ls *.$1 | sed "s/\(..*\)\.$1/mv & \1.$2/" | sh

リネームしたいファイルがあるディレクトリに cd して
$ rename.sh txt doc
>>72
autoload zmv
zmv '(*).c' '$1.h'
alias mv='noglob zmv -W'
7872:04/12/24 18:16:57
皆さんどうもありがとうございま下。私はlinux||cygwinでbashなのでzshとか
ワカラ無いのですが参考になりました。
一応、こunixuserの新山センセのsedっぽいパターンマッチを使うコマンド
formv.shを使って解決していたのですが、もっとスマートな方法無いかと。

formv.sh
------
#!/usr/bin/bash
if [ $# -lt 2 ]; then
 echo 'usage: formv "s/pattern/pattern/" filename(regexp)'
 exit 1
fi
s=$1;shift
for i in $*; do
 j=`echo "$i" | sed "$s"`
 echo $i "->" $j
 mv $i $j
done
-------
$ formv 's/txt/doc' *.txt
$ formv 's/merry_crithmas/aho!/' *.txt;
変更してないならbashだろう。echo $SHELLで確かめれる。
うちの linux には rename(1) がある
ファイル名が数字のファイルのみ表示したいのですが、
良い方法がありませんでしょうか?

$ ls
hoge 645 b7a 7ba

となるディレクトリで

$ コマンド
645

としたいのです。perlを使うってのは無しで
/bin/ls -1 | egrep '^[0-9]+$' | xargs echo

1行1列にしたければxargs echoはなしで。
zsh なら
ls <->
$ echo $BASH_VERSION
2.05b.0(1)-release
$ shopt -s extglob
$ mkdir foo
$ touch foo/{hoge,645,b7a,7ba}
$ ls foo/+([0-9])
foo/645
$
8581:04/12/28 17:09:50
ありがとう

84さんの方法だけうまくいきませんでした。
$ echo $BASH_VERSION
3.00.14(1)-release

なのでバージョンの違いなのかな。
$ /usr/local/bin/bash
$ echo $BASH_VERSION
3.00.16(1)-release
$ shopt -s extglob
$ mkdir foo
$ touch foo/{hoge,645,b7a,7ba}
$ ls foo/+([0-9])
foo/645
>>85
shopt -s extglobが肝だよ
...なるほど

#!/bin/bash
shopt -s extglob #肝
ARGUMENTS=`ls`;
proc_args() {
while :; do
case $1 in
+([0-9]))
echo $1;
;;
"")
return;
;;
esac
shift;
done
}
proc_args ${ARGUMENTS};
89 :05/01/11 16:56:22
☆シェルスクリプトを勉強するにあたって☆
http://makimo.to/2ch/pc5_unix/989/989659936.html
便利なシェルスクリプト見せろ
http://makimo.to/2ch/pc5_unix/996/996949546.html
90名無しさん@お腹いっぱい。:05/01/13 02:23:12
c shellスクリプトで配列の(部分的)コピーをする方法はありますか?
できるだけ一時ファイルを使わず、メモリ上で配列をコピーする方法です。

いま、set arr0 = (abc def ghi jkl mno pqr)とすると、
$arr0[1], $arr0[3], $arr0[5]を配列 arr1 に格納するのは可能ですか?

91名無しさん@お腹いっぱい。:05/01/13 05:15:37
したいことがよくわかんないけど
set arr1 = ( $arr0[1] $arr0[3] $arr0[5] )
じゃダメなん?
92名無しさん@お腹いっぱい。:05/01/13 06:10:42
どの要素をコピーするかは、条件によって変わってくるんで、
インデックスを使いたいんです。動的コピーしたいという事です。
条件によって一個ずつ取り出して、一個ずつ格納するようにすれば?
#/bin/csh
set arr0 = (abc def ghi jkl mno pqr)
set i = 1
set n = $#arr0
foreach x ($arr0)
set a$i = $arr0[$i]
@ i++
end
set j = 1
while ($j <= $n)
echo $a$j
@ j++
echo $j
end
--------------------------ここまで
このようなスクリプトの場合、
$a$j の部分をうまく処理できません。
改善策や、もっとまともなやり方はあるでしょうか?
95名無しさん@お腹いっぱい。:05/01/13 09:12:48
eval
単一ディレクトリ中のファイルをFTP転送するシェルで、
mput *
とすると、巨大なディレクトリでは
Arguments too long
と出てしまいます。

Cシェルがグロブ展開しているようなのですが、何かうまい回避方法はないものでしょうか。
回避するだけなら先頭文字で適当に分割して何度かやればどうよ。

シェルで画像展開してサムネイルを表示させるようなことってできますでしょうか・・・?
>>98
やりたいことをもっと具体的に書け
画像のサムネイルのhtmlファイルを生成するスクリプトなら落ちてるだろ
100100:05/01/16 21:25:19
100
(・∀・)マサムネ!!
ファイル名の空白文字を _ (アンダーバー)に一括で変更したいんですが,
for i in *.jpg みたいな書き方だと空白の前後で2つに分かれて厄介です。
何かいい方法ないですか?

mv "hoge hoge1.jpg" "hoge_hoge1.jpg"
mv "hoge hoge2.jpg" "hoge_hoge2.jpg"

いつもこんなスクリプトを書いてる(とっても面倒)。
>>102
手元の bash 2.05.0 では for で 2 つに分かれないんだが,
ls -1 *.jpg | while read a b ってのはどう?
あはっ

#!/bin/zsh
for i in $*; do
mv -- "${i}" $(sed 's/ /_/g' <<<"${i}")
done
>>102
for i in *.jpg
do
ls "$i"
done
106102:05/01/17 00:39:55
>>103 いいかもしんない。
とにかく思いっきり嘘をつきました。m(..)m
GNU bash, version 2.05b.0(1)-release (i686-pc-cygwin)
>>102 の書き方では2つに分かれないです。
ちなみに for i in `/bin/ls -1` だと2つに割れます。
10798:05/01/17 07:54:34
すみません。
例えば、objやpngやepsやらが存在しているフォルダがあって、
そのフォルダでlsをすると、普通のテキストファイルやらはファイル名だけでいいんですが、
画像ファイルに関してはサムネイルをコンソール上で表示したいな、と思いました。

html作ってw3m介して画像インライン表示すれば一応できるわけですね。。。
ありがとうございました。
gimv等のビュワーを使う方が早いんでないかい
>>107
xmltermというのでできるぞ。
http://xmlterm.sourceforge.net/
110名無しさん@お腹いっぱい。:05/01/17 10:21:55
tcshを使っているのですが、行番号を指定して処理のできるコマンドがあれば、
教えてください。あと、シェルの勉強ができるいいサイトがあればおしえてい
ただけるとありがたいです。
よくわからんが、ファイルの10行目を編集したいとかいうこと?
それだとedを使って編集コマンドをheredocで与えるのが一般的。
例えばこんな感じで。
#!/bin/sh
# comment out the 10th line of file /omae/mona
ed /omae/mona <<END
10
s/^/#/
w
q
END

サイトは、せっかくテンプレがあるんでまずは見てやってくれ。
112110:05/01/17 13:51:37
>>111
わかりにくくてすみません。
自分がやりたいのは例えば指定した複数の行のみで
cutなどを実行したいということなんです。
勉強不足でよくわからないのですが
例は10行目においてwをqに置換するというシェル
ということでいいんでしょうか?
>>112
行が連続してるなら
tail -20 | head -5 | cut ...
とか?
114110:05/01/17 15:35:09
皆さんありがとうございます。目的を達成できました。
>>112
cat file | head -n 20 | tail -n 5 | cut -f'3-5' | sort

みたいなことかしらん
>・シェルスクリプトのことをシェルってゆーな

>>1ぐらい読めよ
11798:05/01/18 01:03:03
>>108
>>109
情報ありがとうございます。そうですね、簡単にできるなら
あまり大がかりなビューアーとかは使いたくなかったんですが…。
xmltermは初耳!画像表示もほとんどイメージ通りです。
日本語がらみが厳しそうですがちょっと使ってみますね。
パス付きzipを判定して捨てるスクリプトってないですかね?
gunzip -t パス付き.zip とかやるとencyptファイルどうたらとかいうので
これを使ってできないかなぁと思うのですが・・・。
少なくとも*.zipとgunzipは関係ないでしょ。
120118:05/01/18 17:57:56
>>119
何を以て関係ないと言うのかわからないけど、解凍はできなくていいのです。
いや、むしろしたくないです。
ヘタレなりに考えた結果gunzipで判定基準になるのかなぁと思ってあげました。

別にこの方法にはこだわってはなくて、*.zip(できればパス付き*.lzh,*.gcaにも対応したい)の
ファイルパスが書いてあるtxtから読み込んで、パス付き有無の識別ができて、
パス付きファイルがあったら捨てるってことができればそれでよしです。
俺は今

hoge.zip のファイルにパスワードが掛かっているかシェルスクリプトで鑑定したいのですが、
いい方法はないでしょうか?

と書くためにこのスレに来た。
ところが118が同じような事を書いている。これはどういうことだろうか?
運命を感じる。明日はいい日に違いない。
>>120
フォーマット解析したら?
要するにエロが多いだけだな。
118>> encyptファイルどうたらとかいうので
そのメッセージ(stdoutだかstderrだか)を捕まえればいいのでは?
>>118
for f in *.zip; do unzip -q -t -P "" "$f" || echo "$f"; done | xargs rm
126118:05/01/19 00:22:26
>>124
ありがとうございます。
stdoutっていうのしか僕は知らなかったみたいでメッセージをとらえられなくて
どうすればいいのだろう?とか思ってました。
stderrってのを使えばメッセージを捕まえられるのですね。
勉強になりました。

>>125
おお、なんかちゃんと判定してるみたいです?消えました。
しかし正直何してるのかまったくわからないのでひとつずつ調べないとだな。
ありがとうございます。
127118:05/01/19 01:15:18
この $f ってのはどこでセットされるんですか?
( ゚д゚)ポカーン
>>127
ひとつずつ調べるってのはひとつずつ聞くってことかい?
130118:05/01/19 02:43:06
いやいやそうではなく・・・スンマセン。
>>126
理解せずに2ちゃんに書いてあるコマンドを実行するのは危険
くだ質にいきなよ。いいかげんスレ違い。
ed に渡すコマンドって、必ず改行で区切らなきゃいけないんですか?
テキストファイルの行頭の #!/usr/local/bin を #!/usr/bin に
書き換えたいとき、覚えている方法だと

ed -s hoge.rb
1,s%/local%%
wq

スクリプトにする時、ヒアドキュメントを使うと3行かかりますよね。
正常な人は perl -e を使うみたいですが、ed では1行でできないんでしょうか。

echo 1,s%/local%%¥;wq | ed hoge.rb
っと、これもくだ質向けの質問だ。ごめんなさい、もしよければお答えください。
(echo 1,s%/local%%; echo wq) | ed hoge.rb
ありがとうございます…
あとは printf とか? くだらなくてすみませんでした
次の日曜日の日付を得たいのですが、なんか簡単な方法はありませんか?

今日実行すれば 2005-01-30 が得られて 2005年1月30日に実行すれば
2005-02-06 が得られるような方法のことです。
138137:05/01/24 16:13:36
man date を読めば簡単にできることがわかりました。
つまらない質問をしてしまってゴメンナさい。
>>137
man date
曜日を%Aとかで出力させて
現在曜日にたいして1-7日後を判断すればいいじゃん
DATE: Monday
なら6日後とかね日曜なら7日後だ
%w と %j と -d を使えば出来そう。
date(1)とstrftime(3)のマニュアルをじっくり眺めてみる。

1. dateで曜日を表示させて次の日曜までの日を得る
2. 現在時間との差分を指定できるdateを使って表示:
date -v+<その日数>d (FreeBSDの場合)

という感じじゃない?

strftimeの指定子はOSによって違うかも知れないが、FreeBSDだと
expr \( $(date +%w) + 6 \) % 7
で日曜までの日数がとれるから、それを2にあてはめて
date -v$(expr 7 - \( $(date +%w) \) % 7)d
でできる。
142141:05/01/24 16:32:02
あ、ごめん、日曜日には当日の日付を出すと勘違いしてた。
しかもなんか間違えたものをコピペしてしまってるし……(汗

> strftimeの指定子はOSによって違うかも知れないが、FreeBSDだと
> expr \( $(date +%w) + 6 \) % 7

計算式が嘘。なんか実験しながら書いたら間違ったものをコピペしちゃった。

> date -v$(expr 7 - \( $(date +%w) \) % 7)d

これも間違えてるし。あわてて書くとよくないですね。
今回の場合、modする必要ないので

date -v+$(expr 7 - $(date +%w) )d

ですかね。
143141:05/01/24 16:38:54
あとは最終的に書式指定(dateのmanを見てね)をしてできあがり。

% date -v+$(expr 7 - $(date +%w) )d
2005年 1月30日 日曜日 16時33分59秒 JST

% date -v+$(expr 7 - $(date +%w) )d +ごにょごにょごにょ
2005-01-30

strftime(3)で%wが使えない場合は>>139のように文字列で表示させて
パタンマッチすることになります。ただしロケールによって文字列は
変わる(特に%Aなどは national representation を出力する)ので、
LANG=Cを指定するかロケールによらない出力を行う指定子を使う必要が
あります。
144141:05/01/24 16:40:12
>>143
> LANG=Cを指定するか

訂正。s/LANG/LC_ALL/


gnu date は...ダメだよね、きっと。

$ date --date='next sunday'
Sun Jan 30 00:00:00 JST 2005
146137:05/01/24 17:52:18
>>145
> gnu date は...ダメだよね、きっと。
$ date --date 'next monday'
2005年 1月 24日 月曜日 00:00:00 JST
$ date --date 'last monday'
2005年 1月 17日 月曜日 00:00:00 JST
となってしまいます。

man を読んでこんな風にしました。
wday=0
add=$(expr $wday - $(date '+%w'))
if [ $add -eq 0 ]; then add=7; fi
if [ $add -lt 0 ]; then add=$(expr 7 + $add); fi
next_week=$(date -d "${add} days" '+%Y-%m-%d')

# レスを下さった方々どうもありがとうございました。
折角だからもっといかれた方法を考えよう
% cal -d1 | grep -w `date +%d` | cut -d' ' -f7

月またぐと上手くいかないけど、まあそこはそれ。
148118:05/01/24 20:24:50
set `date --date '7 days ago' '+%y%m%d'`;echo $1
PHPで。
% php -r 'echo date("Y-m-d", strtotime("sunday"))."\n";'
>>149
この質問がくだ質で出たならその回答もいいが、
ここはシェルスクリプトスレなんで。
既に回答も出ているし、あまり発散しそうなのはやめた方がいいと思う。
151名無しさん@お腹いっぱい。:05/01/30 04:51:01
シェルのベンチマークテストとかあるのかな?
ランチャー的な動作しかしないとしても、常時動いてるものだし。
>>151
> 常時動いてるものだし。

あんたのシステムがどういうものか凄く興味がある。
>>152
いや「常時動いてる」は言い間違いか。
とにかくconfigureとかああいうのが、もっと
軽快に動作するようになったらいいなあと思う。
configure が遅いのはシェルのせいじゃありません。
おとなしくccacheを使え。
ファイルの日付を切り出すコマンドを sh -c で渡してやりたいです[*1]。

とりあえず
LANG=C ls -l hoge | awk '{print $6, $7, $8}'
で切り出しているのですが、これを sh に渡すとなると

sh -c "LANG=C ls -l hoge|awk '{print $6, $7, $8}'"
awk: line 1: syntax error at or near ,

sh -c 'LANG=C ls -l hoge|awk '{print $6, $7, $8}''
awk: line 2: missing } near end of file

sh -c 'LANG=C ls -l hoge|awk \'{print $6, $7, $8}\''
quote>

sh -c 'LANG=C ls -l hoge|awk \\'{print $6, $7, $8}\\''
awk: 0: unexpected character '\'
awk: line 2: missing } near end of file

むう(´・ω・`)

1. 上記のようなコマンドを sh -c にうまく渡すにはどうすればいいでしょうか?
2. [*1] を満たすエレガントなコマンドがあるでしょうか?
sh -c 'ls -l hoge | awk "{print \$6,\$7,\$8}"'
でいけたよ。
ところでシェルはzsh?
漏れもzsh使ってるんだけど、シングルクォートの扱いだけがzshの嫌なところ。
158156:05/01/30 15:27:57
>>157
鬼のような即レスどうもです。

> sh -c 'ls -l hoge | awk "{print \$6,\$7,\$8}"'
そうか、こうすりゃいいのか。多謝。

> ところでシェルはzsh?
ビンゴー。なんで判ったんざんしょ? quote> って出てるから?

> 漏れもzsh使ってるんだけど、シングルクォートの扱いだけがzshの嫌なところ。
bash とかとどっか違ったっけ? …ってちょっとスレ違いか。
>>158
157ではないけど、bashとかと同じだと思うよ。
シェルのクウォートとか$とか空白の扱いは腐ってるから、あんま
り深入りしないほうがいいと思う。
/usr/bin に a というスクリプトがあったとして、そこから同じく /usr/bin にある b という
プログラムを呼びたい場合、どうすればいいですか?
/usr/bin は固定ではなくて、a と b は常に同じディレクトリにあります。

./b だと、コマンドを呼び出しているパス/b という意味になってしまって、期待通りの挙動に
なってくれません。
$0を使う。$(dirname $0)とか。
でもaにsymlinkしてそれを使う場合など、期待するものがいつも得られるわけではない。

ま、UNIXではそういうことしないでフルパスでbに書くのが推奨される作法。
/usr/binとかの場所に置くものならするべきではないけど、
個人のスクリプトとかなら好きにして。
激しくFQAだが、いい方法がない。
FQAキター
>>58あたりでも出てたな
>>161
どうもありがとうございます。
助かりました。

>>164
微妙に、ガイシュツですね。
スマソ。
166名無しさん@お腹いっぱい。:05/01/31 17:03:21
shで連番を生成する定石ってありますか?
1 2 3 4 5 ... のタイプと 001 002 003 004 005 ... のタイプあたりで。
seq とか?
>>166
for i in `seq 10` ; do echo $i ; done
とか。jotとか。

まあ結局フォーマットするならawk使ってやったほうがいろいろ潰しが効きそう。

a=`awk 'BEGIN { for (i = 1; i <= 10; i++) printf("%03d ", i) }'`;
for i in $a; do echo $i; done

とか。
seq -f %03g 1 5
漏れの回りではseqよりzshの方が存在確率が高かったりする。

% zsh -c 'echo {1..5}'
1 2 3 4 5
% zsh -c 'echo {001..005}'
001 002 003 004 005
連番作成なんて飾りですよ
seq使ってる時点でLinux依存になるだろ。
jotならFreeBSD依存。
どうせ依存するならbashのfor ((;;))とか使っとけ。
前スレ?で既出。定番は
yes ' ' | cat -n | head -n 10
for((i=0;i<10;i++));do printf "%03d " $i;done
これならどこでだって使える
>>174
???
shで使えませんが???
>>172
Linux 依存か?
GNU coreutils に依存するだけだが。
>>172
> seq使ってる時点でLinux依存になるだろ。

ということにしたいのですね。
GNU coreutilsをわざわざ入れてる*BSDやSolarisって
少数派だろうし、それが入っているって期待して
スクリプト書いちゃいかんだろ。
Linuxなら100%入っていると改定して良い。
Linux には 100% 入っている != Linux 依存
>>175 大きな勘違いしてた。shならこうか?
i=1;while test $i -le 10;do printf "%03d " $i;i=`expr $i + 1`;done
XXXがYYY依存とか言い出すとさ、
printf(1)が普通にあるのもLinuxや*BSDに限ったことなんじゃないの?
SunOSや商用OS(HP-UX、AIX...)だと怪しい気がする。あったらごめん。
182名無しさん@お腹いっぱい。:05/01/31 19:18:53
awk 'BEGIN { for( i=1; i<=100; i++ ) print i }'
printf(1)はPOSIX準拠
>>181
そういうときは、テンプレにございます
UNIX系各種OSのman page検索
POSIX: Shell & Utilities (標準規格)
などのリンクを活用くださいませ。
>>181
(i=1;while [ ! ! $i -le 100 ];do case $i in [0-9])echo -n "00$i ";;[0-9][0-9])echo -n "0$i ";;[0-9][0-9][0-9])echo -n "$i ";;esac;i=`expr $i + 1`;done)
>>185
うーん力作だね。
でも、echo -nがSolarisだと動かないね。

ところで、whileのところのtestで ! ! で2重否定してるのはなぜ?
これが原因で動かない環境もありそうな気が・・
/bin/sh -c '(S="";i=1;while [ $i -le 100 ];do case $i in ?)S="$S 00$i";;??)S="$S 0$i";;???)S="$S $i";;esac;i=`expr $i + 1`;done;echo $S)'
ちょっと訂正
純粋なshの機能だけでsubstrやindexといった関数って書ける?
>>182
Solaris の /usr/bin/awk は極めて古いので、BEGIN だけのスクリプトは
/dev/null を食わせてやらないとダメ。/usr/bin/nawk ならば問題なし。

>>188
expr(1) を使わなきゃ難しいような気が。
190166:05/02/01 13:33:19
たくさんの回答ありがとうございます。
とりあえず、>>173がどんな環境でもまず問題なし、exprを使えば
もうちょっと凝ったものも出来る、もっとあっさり書きたい時は
環境依存になるということですね?
ありがとうございます。
>>186
> でも、echo -nがSolarisだと動かないね。

PATH=/usr/ucb:$PATH echo
>とりあえず、>>173がどんな環境でもまず問題なし、exprを使えば

Solaris には yes はないよ。
あるんだなそれが。ってのもyesの代替スクリプトも過去スレで既出。
>>193
代替スクリプトが必要な時点で無いって言うのじゃないですか?
代替スクリプト用意しておいて"ある"って言うなら
gnu coreutils インストールしておけばその環境では"ある"って言えるわけで
while :; do echo yes; done | hoge
ぐらい書くのと、coreutils入れるのと、同じかよ
で、Solaris に yes はあるの?
>>194
/usr/bin/yes にある
うちの Solaris には無い
>>198
すくなくとも
Solaris 9 4/04 s9s_u6wos_08a SPARC
Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
Use is subject to license terms.
Assembled 22 March 2004
にはあるな。
SunOS 3.X の大昔から Solaris 7まで使ってたけど、
yesがないSunOSは見たことなかったぞ。

差し支えなければバージョン晒してみてくれないか? >>198
201not 198:05/02/01 19:47:59
>>200
思い込み激しいな。ほんとにSolaris7まで使ったの?
yesは、
Solaris7やSolaris8にはない。(/usr/binにも、/usr/ucbにさえも)
Solaris9で復活したみたい。
まあ、ucb系のコマンドということで嫌われて一回消されて
復活したというわけかな。
202198:05/02/01 19:53:41
% uname -a
SunOS edu 5.8 Generic_108528-19 sun4u sparc SUNW,Ultra-Enterprise
% cat /etc/release
Solaris 8 2/02 s28s_u7wos_08a SPARC
Copyright 2002 Sun Microsystems, Inc. All Rights Reserved.
Assembled 18 December 2001
% print $path
/usr/local/j2sdk1.4.2_02/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin /usr/openwin/bin /usr/ccs/bin /usr/ucb /opt/SUNWspro/bin /usr/local/java/bin /usr/bin/X11
% yes
zsh: command not found: yes
203200:05/02/01 20:10:31
>>201
スマヌ orz カンチガイカモ
SolarisはGNUモノ入れないと使いものにならなかったからな。
coreutils(当時はsh-utilsか?)のyesが入ってたんでしょ。
ホントに移植性が大事なら
awk や perl で作った方が楽かもね。
$echo -e '#include<stdio.h>\nint main(){int i;for(i=1;i<=10;i++){printf("%03d ",i);}}' > foo.c; gcc foo.c -o foo && ./foo; rm -f foo.c foo
今度はそうするとビルドツールやlibcが問題になって泥沼化かw
で、perlを使えば、perlがベースから外されたFreeBSD 5.xで問題になる。
awkはSolarisで問題になり、かと言ってnawkを使うとSolaris以外で使えない。
じゃぁcshで。
>>207
NetBSDも昔っからperl入ってないし、pkg_addすると
/usr/pkg/binに入るんで、/use/binにperlのシンポリック
リンクを張った覚えがあるな。

NetBSD2.0はまだ触ってないから知らんが。
二つのファイルが同じときに、文字を表示するにはどうしたらいいのでしょうか?
diffやcmpだと違いがあったときにしか表示されません。
何かいいコマンドとか方法はありませんか?
>>210
diff の返り値見るとか。
cmpで黙らせた方が速そう
>>210
#!/bin/bash
cmp|diff "${1}" "$[2}"
if [ $? -ne 0 ]; then
hogehoge(eg. cat "${1}")
(eg. echo "identical")
fi
>>210
md5sum を比較するとか。
>>210
comm
#################
#!/bin/sh
trap "echo hoge" INT
echo start
sleep 100
echo stop
#################

こんなスクリプトを書いています。
sleep 100 には実際には長たらしい処理をするプログラムが入ります。
ここで、外部から SIGINT を送り込んでも、
すぐに hoge が表示されるわけではありません。(最悪の場合100秒待ちます(藁))
SIGINT を送り込んだら hoge が即表示されるようにするにはどういう風に
スクリプトを書けばいいですか?
その例だと、コマンドがひとつしかないからじゃないの?
たとえば、sleep 1を100回繰り返してみるとか、にすれば結果も変わってくるんじゃないの?
SIGINTを誰に送ってる?
shだけに送ってたら、sleepが死なないから終了まで待つ。
shとsleep両方に送るには、shのpidがpgidだと思うから、
そこめがけてkill -INT -pgidとか、killpg(-pgid,SIGINT)とか。
219名無しさん@お腹いっぱい。:05/02/04 16:22:35
bashでヒアドキュメントをシェル変数にいれようと思って
cat > $kiee <<EOF
munyamunya
EOF
とすると
-bash: $kiee: ambiguous redirect
とでます。なんでですか?
>>219
$kieeの中身は?
>>220
空です。
お前がやっているのは、EOFまでの標準入力を変数kieeに入っているファイルにリダイレクト、だよもん
$kieeにファイル名が入ってたら、とりあえずエラーにはならない
>>222-223
マジデー('A`) ありがとうごzぁいまひた
>>216
sleep 100

sleep 100 &
wait
の2行にすると、shだけにSIGINTを送っても即処理されるみたい。

何でかって?それがな、一晩考えたが俺も説明できん orz
>>225
考えてもわからんよ。マニュアルかソース嫁
227225:05/02/04 17:00:44
>>226
何回も読んだけど、なお解らなかったの。OTZ

普通にsleep 100だけでも、shはsleepをfork+execして親側でwaitしてるじゃん。
wait中の親はSIGINT捕まえられて即処理できて当然じゃん?
これをsleep 100&waitに変えたからって、この親子の関係は変わってないでしょ?

だれか、俺を導いてちょ。


sleep 100 1行だけの場合、SIGINTでsleepが終了しない限り
シェルに戻らないので、trapも起きない。
sleep 100 & waitの場合、waitはシェルの内部コマンドなので、
SIGINTを送るとwaitが終了してtrapが起きる。
この時、waitが終了してもsleep 100 &はバックグラウンドで動き続ける。
>>227
単純なfork+exec+waitではないのでは?
このへんのことはマニュアルに書いてないのかな?
ソース読むしかないね。
プロセスグループだかセッションだかが関連するんではないだろうか、
と勝手な想像をふくらましてみる
231225:05/02/04 17:29:09
>>228 sleep 100 1行だけの場合、SIGINTでsleepが終了しない限り
シェルに戻らないので、

これ違うよね?だってシェルのプロセスだって動き続けているでしょ?
fork&execしたsleepをwaitして待ってる最中というのが俺の理解っす。
だから、必要な処理があれば実行できる(例えばSIGINTの処理)。
「シェルに戻らないので」といういい方が曖昧だったかな。
sleep 100とフォアグラウンドで記述した以上、
シェルとしては文法上、sleepが終了するまでは次の処理を
することができない。(システムコールレベルでのfork() wait()は
この場合考えないこと)(あくまでシェル文法)
sleep 100 & waitなら、waitだけ終了して、
sleep 100だけバックグラウンドに残すことが文法上可能なので、
sleep 100 &したままtrapを実行できる。
あくまで文法解釈の問題。

あと、シグナルが届くのは、waitが内部コマンドだから、
シェルに送ってもwaitに届く。
>>231
225はシステムコールのこと知ってるくせに実際にプログラム書いたことは
あまりないだろ? ブロックするシステムコールを呼ぶときは、EINTRは
無視するループを組むことが多いのよ。
普通にforegroundで実行してるときはwaitの間はSIGINTが来ても無視するわけ。
だけどwaitビルトインを使うときはSIGINTが来たらさくっと抜けるように
shというのは書かれているわけだ。
詳しくはソース読め。これくらいなら簡単だからせいぜい2,3分で追える。

>>232 はなんかいいかげんな説明というかこじつけっぽい気が。本末転倒っつーか。
つまり、sleep 100の1行だけの場合、
内部的にシェルがwait()システムコールで待っている時に、
SIGINTでwait()が中断されたとしても、
フォアグラウンドのsleepが未完なので、
あえてtrapの処理をせずに、再度wait()を呼び出して、
あくまでもsleepを待つようにしている(それが仕様)ということかな?
trap 文が実行されるのは、あくまで現在実行してるコマンドの終了後。
なので解決策としては、>>218 が正しい。

実装によっては挙動を変えられる。たとえば、FreeBSD の sh の -T オプション。
http://www.jp.freebsd.org/cgi/mroff.cgi?subdir=man&man=sh&dir=jpman-5.2.0%2Fman
うわ!! 直リンしちまった。。。m(__)m
>>236
勉強になったわ。
>>236
しても問題ないと思うが。
240名無しさん@お腹いっぱい。:05/02/07 17:02:14
http://pc5.2ch.net/test/read.cgi/linux/1107692207/l50

↑から誘導されてきました

親シェルから下記のようなシェルを起動させて動かしています。
下記シェルを単体で動かすとちゃんと動くのですが、他のシェルか
ら呼び出すとcase文を無視されてしまいます。
なぜなんでしょうか?ご教示下さい

#/bin/sh
WEEK=`date | awk '{print $4}'`
TIME=`date +%H%M`

case $WEEK in
月曜日)
if [ $TIME -gt 1200 ] && [ $TIME -lt 1300 ]; then
echo "お昼休み"

cronで動かしたときのみcase文を無視されてしまいます。
手動の場合は正常に動作します。
何が原因なのでしょうか?
・シェルスクリプトのことをシェルってゆーな by >>1
ま、おおかた、cronの中では LANG が設定されてないとかそんなもんだろ。
echo $WEEK してみろ
>>240
直接の原因は、cronから起動した場合、
LANG=Cになっているから、dateの出力が英語表示になる、
しかも、順番も変わることだが、
そもそも、dateをawkしてprint $4などとするのは邪道。

WEEK=`date +%w`

としなさい。すると、WEEKには、0(日曜)〜6(土曜)が数字で入るから、
case文ではこの数字で場合分けする。
>>240
今Linくだ質に回答したよ。
6時間ぶりに2chに来て見た瞬間にわかったよ。
次スレからは

・テンプレ読まない奴禁止

ってのも>>1に入れた方がいいんだろうか。
246240:05/02/07 18:18:11
レス頂いた皆さん有難うございます。
今は帰宅して240の環境にいないので確認できないのですが、>>244さんのご回答で
直りそうですね。それが理由だったら恥ずかしいこの上ないです。
それと>>243さん勉強になりました。それに変更します。
初心者のスレ汚しすみませんでした。
皆さん有難う
>>244
その、Lin板の管質に回答したってやつ、違うと思うよ。

>>243 の答で合ってる。

#/bin/sh のところは単なるtypoだと思うし、
もし本当に #/bin/sh って書いてあっても、
デフォルトで /bin/sh スクリプトと解釈されて動くはず。
(chmod +x さえされてれば)
>>247
244だけど、多分その通りだろうね。
和紙はスレの流れのほんの一部しか読んでない状態だし、
和紙の言うとおりだとしたら、その際エラーも出てる筈
>>248言語障害?
cronで生成しているファイル(日付.log)の1行目に
日付(2005/05/08)を挿入したいのですが書き方が分かりません。

ご教授願います。
>>250
>>1曰く
>  manを見ましょう。

man date
>>251
日付を取り出すフォーマットじゃなくてさ、
日付.logという(日付に依存して決まる)ファイル名の方で悩んでるんじゃない?

>>250
today=`date ...`
echo $today > $today
とかしてみ。`date ...`の部分は、>>251 の助言にしたがって自分で考えようね。

``の意味がわからないなら、そのときはman shだな。
253252:05/02/08 00:54:17
あ、日付にスラッシュが入る形式なのか。
そのままじゃファイル名に使えんな。
orz
ともかく、質問のしかたが悪いということで。
もう、日付は、飽きた。

この手のスレのうちの確実に1割以上は date の話だろ。
ならば、リダイレクションの話。

freshclam > /home/update.log
freshclam 2>&1 > /home/update.log
freshclam 2>&1 | tee /home/update.log

どれも結果は同じ

cat /home/update.log | mail -s "`/bin/hostname` test" root

此れで、/home/update.logの内容をメールに受け渡し。

ダルゥ。。。
257252:05/02/08 21:23:26
redirectionの代わりに何故catをかませるのかという議論で荒れたのって、
このスレだっけ?
258250:05/02/08 23:26:46
sedで削除したり置換したりすることにしかシェルを使ったことがないので
質問の仕方に変な箇所があるかもしれませんがご了承ください。

ということで、やりたい事を書き直します。
1日に1度、wgetでデータをダウンロードして
日付.logというファイル名で保存しています。
このファイルの1行目に日付を挿入したいと考えて最初の質問をしました。

現在はダウンロードしているだけですが
このファイルの1行目に(date --date '1 days ago' +%Y/%m/%d)を
挿入する方法をご教授ください。
#!/bin/sh
log1=`date --date '1 days ago' +%y%m%d.log`
log2=`date --date '1 days ago' +%y%m%d.log2`
cd ログ保存ディレクトリ
wget ttp://www.hogehoge.com/log/$log1
mv $log1 $log2
sed -e '/要らない文字/d' $log2 > $log1
rm $log2
cd
>>258
やってることがイマイチわからんが mv の後に
echo `date --date '1 days ago' +%Y/%m/%d` > $log1
sed -e '/要らない文字/d' $log2 >> $log1
じゃ駄目なのけ?
sed の行を↓
(date --date '1 days ago' +%Y/%m/%d; sed -e '/要らない文字/d' $log2) > $log1
$log2 って一時ファイルなのね、、、分かりにくい。。。
日付のみが書かれたファイルに>>するとかじゃだめか?
おう、遅かった
263259:05/02/08 23:52:35
>>260見て気付いた、echo 要らないね(;´Д`)
264名無しさん@お腹いっぱい。:05/02/09 00:09:21
質問です。born shで、
catした結果、grepした結果をstderrに吐く、ということはできるのでしょうか?
できるとしたらやり方を教えた下さい。
man読む
>>259-260
ありがとうございます。

期待通りの結果で出力されました。
今晩はぐっすり眠れそうです。
267264:05/02/09 00:17:44
ごめんなさい、bourne shねんですね。
初めて知りました。

>>265
ネットではイロイロ探してみたのですが、
manでは何をキーに探せばいいのか見当がつきませんでした。
xxxの使い方、オプションとかならmanも見るのですが。
>>256
>どれも結果は同じ
freshclam がエラーメッセージも標準出力に出すのなら、
それでいいけど、
> /home/update.log
2>&1 > /home/update.log

2>&1 | tee /home/update.log
はちがうよ。
26907041050335728_ac:05/02/09 00:36:57
>&2
>>267
man sh
あなたの見るのがどのOSの何語のmanかは知らないが、
redirectかredirection (日本語ならリダイレクト/リダイレクション)で
検索してそれっぽいところを読むといいでしょう。

でもリダイレクトはシェルの使い方の基本中の基本なので、
テンプレから適当な入門ページを見てみるのがいいと思います。

>>267
> ネットではイロイロ探してみたのですが、

次からは質問前にテンプレを見てみるというのも探し方に入れてください。
271264:05/02/09 00:49:10
>>270
すみません、テンプレにあるサイトは一通り
流し見たのですが。。。正直、すべてのページを目が乾くまでは
じっとりと診てないです。

あと、私が質問している内容は、
「stderr を ファイルにリダイレクトする」のではなくて、
「ファイルの中身を、stderrに出力したい」のですが、ということなんですが。
("シェルの基本"の部類に入るのでしょうか?)
じゃあ諦めろ。
>>271
ちょっと確認してみました。

>>2 の先頭にある「Bourne Shell自習テキスト」の2.3とか、
2番目にある「シェルを使おう」の2.2.2などはどうでしたか?

全部を全部舐める必要はありませんが、入門テキストっぽいところで
ご自分にあってそうなところを一つ選んで、学習してみてください。

> 「ファイルの中身を、stderrに出力したい」のですが、ということなんですが。
> ("シェルの基本"の部類に入るのでしょうか?)

まごうことなき基本中の基本です。
274264:05/02/09 01:16:51
>>273
ありがとうございます。
ヒントとしては、「シェルは標準入力・標準出力・標準エラー出力の
3つのファイルをオープンしており、それらはファイルディスクリプタ
「0 .. 3」として管理しています」
のところなのだろうか・・・というところまでは理解しました。

ここ1年ほどシェルを触りはじめましたが、まだわかっていないことが多すぎたようです。
ご丁寧にありがとうございました。
シェル言うな
シェルでも問題なかろう?
ていうか、274の文章に限っては
「シェルスクリプト」は標準入力...をオープンしており...管理しています
としてしまうと逆にヘンだろ。
個人的にはパイプとかリダイレクションが何をやってるのか分かったのは
APUEを読んでからだった
file descriptor って何だよってかんじで
>>278
APUE とは?
>>279
Advanced Programming in the UNIX(R) Environment
http://www.amazon.com/exec/obidos/ASIN/0201563177/
詳解UNIXプログラミング
http://www.amazon.co.jp/exec/obidos/ASIN/4894713195/
APUEは最高のUNIX入門書
昔はUPEだったなぁ
UNIXプログラミング環境は紀伊國屋に売ってたなぁ
欲しかったけど Life with UNIX 買っちゃってお金がなかった
284名無しさん@お腹いっぱい。:05/02/10 22:16:05
wgetかcurlで
http://nylon.hostfuck.com/index01.html
の画像を落とすスクリプトを書いてください
専用スレでどーぞ

連番のH画像を一気にダウンロードする
http://pc5.2ch.net/test/read.cgi/unix/979106537/
286初心者:05/02/10 22:55:28
スレ違いでしたらごめんなさい。
alias でコマンドに別名をつけたとします。
.bashrc に 'ls -aF'  を l で別名つけました。
この別名をシェルスクリプトから呼ぶことができないのは
なぜなんでしょうか?
よろしくお願いします
シェルスクリプトが.bashrcを読まないから。
288名無しさん@お腹いっぱい。:05/02/10 23:02:29
.bashrcはログイン時に実行されてるのですが。
コマンドラインでalias設定してもスクリプトから
別名をよぶことができませんでした。
なんでですか??
ログインシェルが覚えてるalias定義は、そこから起動されるスクリプトには受け継がれません。
290286:05/02/10 23:13:12
そーなんですか、そういうものなんですね。
レスサンクス!!
シェルスクリプトの中で自分のalias使いたきゃ、
シェルスクリプトの先頭で . ~/.bashrc とか書いとけばできるが、
そんなことをするのは超邪道。

どうしてもやりたければ代わりにシェル関数使え。
それ以前にプロセスというUNIXの基本を理解してない。
おれも邪道だと思うが、
Linuxのいくつかのディストロがデフォルトで . ~/.bashrc ってやっているのがあるなぁ。
せめて、
$grep alias ~/.bashrc|while read l;do eval $l;done
とするとか。
>>294

\ でつないで複数行になってたらどぉするよ
テキストファイルの各行で先頭5文字を削除したいのですが
どのように書けばよいか教えていただけませんか?

以下適当な文字列
aiueokakikukeko
sasisuseso
tachituteto
naninuneno

kakikukeko
useso
tuteto
uneno
のように、先頭5文字を削りたいのですがお願いします。
sed -e 's/.....//'
>>297
ありがとうございます
sed ':label;/\\$/{N;s/\\\n/ /;b label}' ~/.bashrc |grep alias |while read l;do eval $l;done
>>296
cut -c6- file_name
>>300
おーなんかすげー
>>301
それやめてくれ、>>300は基本中の基本だ
303名無しさん@お腹いっぱい。:05/02/14 14:43:42
>>296
colrm 1 5
>>303
そんなコマンドがあったのか。
colrmはSolarisで使えないから避けるが吉。
Solarisってうざすぎ
307名無しさん@お腹いっぱい。:05/02/14 15:06:35
>>296
sed -e "s/^.\{5\}//;"
308名無しさん@お腹いっぱい。:05/02/14 15:41:38
文字列を区切文字で行に変換する方法を教えて下さい。
例えば
abc de fgh ijk

abc
de
fgh
ijk
にしたいのです。
sed 's/ /\n/g'
awk '{for(i=1;i<=NF;i++)print$i}'
311名無しさん@お腹いっぱい。:05/02/14 16:03:02
>>309
全部くっつきました。
abcndenfghnijk
echo 'abc de fgh ijk' | xargs -n1
>>311
\n を n にしてると思われ
釣?
echo 'abc de fgh ijk' | tr ' ' '\n'
>>313
sed で \n は使えないよ。

sed 's/ /\
/g'

だな。シングルクォート中で改行するので、
B-shell系のコマンドラインで実行すること。
316名無しさん@お腹いっぱい。:05/02/14 16:48:44
>>309-315
ありがとう!みんな大好き!
317309:05/02/14 16:50:28
使えました。
$ sed --version
GNU sed 4.0.5版
sed の \n だけど、

GNU 3.x の sed では NG
FreeBSD 4.x の sed でも NG
試してないけど多分 Solaris の sed でも NGでは?
Linux 板じゃないから GNU 前提は避けた方がいいな
>>299とかも
48時間データを24時間データにしたいのですが良い方法はありませんか?
行数を指定して削除しようと考えていたのですがデータ欠損時に行数が狂ってしまうため
date --date 'today' +%y/%m/%d;に該当する行を削除したいのですがお願いします。

05/02/13 00:00 123 118
05/02/13 01:00 124 200
05/02/13 02:00 129 195
 (中略)
05/02/13 18:00 124 210
05/02/13 19:00 124 210
05/02/13 20:00 118 194
 (中略)
05/02/14 02:00 128 212
05/02/14 03:00 127 181
05/02/14 04:00 125 192
 (中略)
05/02/14 18:00 121 172
05/02/14 19:00 125 183
05/02/14 20:00 126 182

少し前のレスにdateは・・・とありますがお願いします。
悪いが意味わからん
と思ったが、
sed /^`date '+%y\/%m\/%d'`/d
のことだろうか
323名無しさん@お腹いっぱい。:05/02/14 22:41:53
>>320
TODAY=`date +%y\\\/%m\\\/%d`

sed /"^$TODAY"/d infile > outfile


↑でできます。
正規表現の中の/をエスケープするために\が要り、
さらに、` `で取り込むために\が\\に、\/が\\/になって、
結局\\\/という、禿げしく複雑なフォーマットになりますが、
これでできますよ。


>>321
わからない君は答えなくていいよ。
うはwwwwwwwzshでwwwwやってみたwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww

#!/bin/zsh

typeset -r DATE=$(date --date 'today' +%y/%m/%d)

while read -r line; do
[[ "$line" != "$DATE"* ]] && print "$line"
done
うはwwwwwwwしかもwwwwwwwwwwwwwwwwかぶってwwwwwwるwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
326勉強になります:05/02/14 23:00:29
>>296
ほほぉ。

eelsPBG4:~ sheel$ echo "1234567890" | colrm 6
12345
eelsPBG4:~ sheel$ echo "1234567890" | cut -c6-
67890
eelsPBG4:~ sheel$ echo "1234567890" | sed -e "s/^.\{5\}//;"
67890

>>308
ほほぉ。
eelsPBG4:~ sheel$ echo 'abc de fgh ijk' | xargs -n1
abc
de
fgh
ijk
eelsPBG4:~ sheel$ echo 'abc de fgh ijk' | tr ' ' '\n'
abc
de
fgh
ijk
>>323
ありがとうございます
3回もエスケープする必要があったんですね
質問させてくださいませ

bash で 関数内にヒアドキュメントって使えますか?

やりたいことは定時FTP転送で、中に変数も使いたいから
関数にしようとしたんだけど、ヒアドキュメントっていう
か「<<」がだめっぽくてエラーが出ちゃいます。

なんかいい方法ないでしょうか?
>>326
なんか良いね
いろんな解法があって
>>328
bashに限らず、シェル関数内でもヒアドキュメントは使える。
うまくいってないのは別の原因と思われ。
やったことをもう少し詳しく書け。
331328:05/02/14 23:15:52
>>330
ごめんすぐわかった。

ftp -n >> _EOF

< COMMAND >

_EOF 2> xxx.log

ってやってたのがだめだったんですね。
COMMANDをファイルにまとめて書いていたときは、上記の感じで
エラー出力してFTPが成功したかどうかを判別してたのです。

シェルのftpコマンドでFTPが成功したかどうかを調べるいい方法
はありますか?
>>331
expect 使うとかそういう話?>>4
おい、顔出すのはMac版だけにしとけ。>>326

Paperが相手してくれてんだろ?
334328:05/02/15 00:37:44
>>332
うおお…ありがとう。

これでできます。ほんとにありがとう!
335名無しさん@お腹いっぱい。:05/02/15 07:36:39
1行に不定個の文字列がありそれを逆順にする方法を教えて下さい。
例えば
abc de fgh ijk
ijk fgh de abc
にしたいのです。
(A=;for i in ab cd ef;do A="${i} $A";done;echo $A)
小出しに宿題をやらされている気がするのは猛霊だけだろうか
>>336
それじゃ標準入力から読めない。
↓にしとけ。

while read line
do
str=
for s in $line
do
str="$s $str"
done
echo "$str"
done
339名無しさん@お腹いっぱい。:05/02/15 08:34:32
sedじゃ無理ですか?
perlならこうか?
perl -ane 'print join(" ",reverse @F),"\n"'
awkならどうやるんだろ。
341名無しさん@お腹いっぱい。:05/02/15 09:27:22
>>339
sedでやるなら↓
ただし、
* 文字列中に%が含まれていないこと
* スペースは1個のみで区切られていること

Copyright by me.


sed '
:loop
/ /{
s/^\(.*\) \(.*\)/\2%\1/
s/%\(.*\) \(.*\)/%\2%\1/
b loop
}
s/%/ /g
'
awk ならこんな感じか。区切文字まで面倒みないが

awk '{for (i=NF; i>=1; i--) {if (i==1) print $i; else printf $i" "}}'
すまん。
>>341 は一部ミスってる。発想はこんな感じなのだが・・
宿題っぽいのであとはお前らへの宿題にしとく。
344名無しさん@お腹いっぱい。:05/02/15 09:40:42
>>341
ありがとうございます。 すげー! 腰がぬけました。
sed,awkって人を幸せにしてくれるな
346名無しさん@お腹いっぱい。:05/02/15 09:44:07
今度こそできた。

sed '
:loop
/ /{
 /%/{
  s/\(.*\)%\(.*\) \(.*\)/\1%\3%\2/
  b loop
  }
  s/^\(.*\) \(.*\)/\2%\1/
  b loop
  }
 s/%/ /g
'
もっと簡単になった。

sed '
:loop
 / /{
  s/\([^%]*\) \(.*\)/\2%\1/
  b loop
 }
 s/%/ /g
'
348名無しさん@お腹いっぱい。:05/02/15 10:42:20
>>347
またまたありがとうございます。

ちょっと弄ってみました。
sed '
:loop
  s/\([^%]*\) \(.*\)/\2%\1/
  t loop
 s/%/ /g
'
shだけ使って無駄に複雑に

foo () {
local s
case $# in
0) ;;
*) s=$1
shift
foo "$@"
echo -n "$1 "
;;
esac
}
while read line; do
foo $line
echo
done
>>349
「shだけ」というなら、
local使っちゃいかんだろ。
シェルスクリプトの中で
処理状況をログファイルに書き込む場合、
echo "状況" >> ログファイル
としていますが、
ファイルの末尾に追加していく方法ではなくて、
逆に先頭行に挿入していく方法を
ご教示下さい。

今はテンポラリファイルに最初状況を書いて、
今までのログをcatで入れていますが、
ログファイルが大きくなるにつれ、遅くなりそうです。

今のファイルシステムでは、
仮にシェルがそんな機能をサポートしていたとしても、
巨大なファイルを扱えば重くなる。
速い方法はない。どうやっても遅くなる。
そもそも先頭に挿入したいってのが変すぎる。
真の要求は別にあって、やり方を間違えてる
だけなんじゃないの?
>>352-353
早速の回答ありがとうございます。
分かりました。ないですか。

ファイルシステム関連で無理な話なら、
対象処理を優先させるのが常識なので、
ログファイル書き込みでは追記書込をし、
最終的にそのログをtacを使って
別の逆順ログファイルを作成することにしました。

>>353
仕様云々ではなくて、技術的な面から純粋に
書込時にファイルの先頭にデータを挿入するのに
(てっとり)早い方法があるかどうか聞いてみただけです。

もしあれば、データのみのファイルに
ヘッダーを付ける場合も、
自分でテンポラリファイルの作成なしに、
リダイレクト感覚で(内部ではテンポラリを使うかもしれないですが)
できると思いましたが、そうは問屋がってやつですね。
ページサイズごとにファイルくっつけると速くなるかも
てゆうか、なんで逆順ログファイルなんてものが
必要なのかしら? 普通不要。
実は tail コマンドを知らんとか、そういう落ち
だったりして。
>>357
なのに head だけは知ってる(笑)
>>356
そこまで逆順のログファイルが何故必要なのか
知りたいのなら、トータルで一番良い方法を
教えて下さい。

そのログをイントラ内でWebにより公開するのですが、
仕様決議で、(ブラウザのスクロールの操作無しに)
新しい情報であればあるほど、最初に見ることが出来た方が
良いから、逆順に表示されたものが見たい、とのことです。
要求がそうしたいとのことなので、どうしようもないです。

あと、ちょっとかけ離れますが、逆順のログということでは、
よくWebページの更新ログも逆順が多いですよね。
それが、変かどうかは人によって違うわけですしね。

Servlet内で正順のログを動的に逆順に読むと、
その処理で、Webページの表示が遅くなるので、
それなら元から逆順のデータがあれば、
コードも簡潔になるし、早く表示できるからです。

それか、DBでテーブル化しちゃうかかな...
そこまでのことでもないのだけどな。

>>357-358
念のため、tailを使わなかった。
-rオプション可能なtailとtacを調べてみたら
何故tailを使わないかが分かるよ。
>そこまで逆順のログファイルが何故必要なのか
>知りたいのなら、トータルで一番良い方法を
>教えて下さい。
俺なら、ブラウザの1ページに収まる程度の内容だけ
tail -40 くらいで切りとって、それを servlet で
逆順に表示するね。ログが長い場合、この方が tac
を使うよりも計算量がはるかに少なくて済む。

全ログを見たい場合には、逆順じゃなくて正順のまま
で表示。最後にアンカーを置いておいて、そこに飛ぶ
ようにはしておいてもいいかもしれん。
>>359
ログは追記しか考えられないな。
表示は1画面分(当然仕様で決まってるよね?)を
tailしてきて表示時にひっくり返す。
なぜファイルレベルでひっくり返さなきゃならんのか不明。

要求する人は中の人がファイルの尻に追記してたって、
頭に挿入してたって関係ないわけで、詳細設計や実装する人は
要求定義をそのままコーディングするんじゃなくてコンピューターが
やりやすいようにやんなきゃダメよん。
363362:05/02/15 17:06:13
>>361
あらかぶったわ。まあ常識ってことで。
364361:05/02/15 17:06:59
>>362
お、被ってる。
ふつうこうするよなぁ。
ま、要求が変というのもあるがな。
ログなんて時間順に上から下に並ぶのが一番自然なわけで、
たまたま今のブラウザが、ページを開いたときに一番上を
最初に見せることしかできないからといって、
そっちに合わせてログを逆順にしなきゃという発想がそもそもいかん。
一番下が最初に現れるようにするのが正統。
>>359
正順で記録しといて、rotate の際に逆にするとか。
rotate されてない分は表示するときに逆順にする。

それかがんばって逆順で記録。

何がトータルで一番良いかは状況によるのでなんとも。

>>365
そんなに変でもないと思うよ。
367悩める20代:05/02/15 17:33:35
はじめまして、「悩める20代」です。
Kシェルの初心者ですが、皆様のお知恵をお借りしたく投稿しました。

Kornシェルのスクリプトでログを出力するシェルを作成しました。

しかし、ログが改行されて出力されてしまいます。
原因はスクリプト内でdateコマンドを実行しているのですが、最後に改行文字が負荷されてしまうようです。
調べているのですが、何か良い方法をご存知ありませんか?

<実際のスクリプト>

#!/bin/ksh
# 日付を出力
date "+%Y-%M-%d %H:%M:%S" >> a.txt
# ログメッセージを出力
echo " [INFO ] : 〔GQE1001I〕 テーブル名 TTTTT のリフレッシュが正常に終了しました。" >> a.txt


<出力結果>

2005-58-15 16:58:30
[INFO ] : 〔GQE1001I〕 テーブル名 TTTTT のリフレッシュが正常に終了しました。

<本当は以下のようにしたいです>

2005-58-15 16:58:30 [INFO ] : 〔GQE1001I〕 テーブル名 TTTTT のリフレッシュが正常に終了しました。
変とかそういうあいまいな話じゃなくて、
逆順に記録するならたかがログにファイルロックとかせなあかん。
ちょーマンドクセ

表示の時にちょいと工夫すりゃいい話。
極端な話、表示順を逆順にする程度のことは
javascript等(=クライアント側)にやらせてもいいわけで。
・シェルスクリプトのことをシェルってゆーな by >>1
>>367
echo -n `date hogehoge`
>>361-366
どうもありがとうございます。
説明がまずかったです。
スクロール無しというのは、
最新データを見たい場合のことです。

イントラ内なので、転送速度は問題なく、
別ページに遷移は面倒だから、
1回の処理=1ファイルでを
全部表示させる仕様です。
(ファイルはrotateします。)

関係ないかもしれませんが、
私も2chはかちゅだけど、全部表示ですしね。
それはそれでユーザに同意してます。

あと、最初の文章は煽っているわけでも
ありません。
すみません後から見るとそう見えますね。
処理を洗い出すので、どこか良い改善策が
あれば教えて下さいと言う意味でした。

リンクで(逆順の)ファイルを表示させる
のが一番シンプルで効率的なので、
今のところその方向でいきます。
正順で表示し、javascriptで最後尾にスクロールも
試してみます。(要件としては最初に最新のものを
見たいということなので)
それで、昇順、降順をどっちも実装します。

いろいろありがとうございました。
そもそもtacで重くなるようなサイズのログをwebで出されても
>>367
echo には >>370さん がかいてるように -n がある。

そういったオプションが無いコマンド(date など)は
コマンド | tr -d "\n"
で \n を削除。

とりあえず、man tr を。
>>367

# 日付けとログメッセージを出力
echo `date "+%Y-%M-%d %H:%M:%S"` " [INFO ] : 〔GQE1001I〕 テーブル名 TTTTT のリフレッシュが正常に終了しました。" >> a.txt
date '+%Y-%M-%d %H:%M:%S [INFO ] : 〔GQE1001I〕 テーブル名 TTTTT のリフレッシュが正常に終了しました。' >>a.txt
cp $FILES $DIR
ってかくと$FILESが空の時にエラーになってしまい
Makefile等など途中で終了してしまうのですが、
どう回避するのが手軽でよいしょうか。

よろしくお願いします。
>>376
空にならないようにする
空の時に実行しないようにする
test -z "$FILES" || cp $FILES $DIR
>よろしくお願いします。

何を?
っつか、ウェブで閲覧するっていうんなら、
そんなぐだぐだリネームしなくっても、
Options Indexes
で即解決なんじゃないの?
ソートできるよね?
Makefile でそこでエラーが出ても後続の処理に問題がないのなら、
頭に-を付けて無視すればいい

-cp $FILES $DIR
>>380
どれへのレス?
既存のCシェルスクリプトに対して、
trapにより、 trap 'exit 3' 15
して、kill信号のみをtrapしたいんですけど、
使うと、そのコマンドはないです。 と怒られます。

しかし、Cシェル用のonintr で、goto先指定すると、
全ての割り込みに対して、gotoしてしまうので、×です。

できれば、既存のCシェルスクリプトをあまり変えることなく
trap 'exit 3' 15 したいんですけど、 いい案はないでしょうか?
>>383
いい案はない。
cshは捨てろ!
以上。
385380:05/02/17 13:45:38
>>382
>>359 あたりの一連のポストへのレスのつもり
だとすると逝ってよい
awkで困ってます。


n.datの中身
----------------------------------------
a,0,A,AAAAA,BBBBBBBB,wait,,,,
a,0,A+0217,AAAAA,BBBBBBBB,wait,,,,
a,0,A=0217,AAAAA,BBBBBBBB,wait,,,,
a,0,A+0218,CCCCC,BBBBBBBB,disable,,,,
a,0,A+0219,AAAAA,BBBBBBBB,hold,,,,
a,0,B+0217,BBBBB,BBBBBBBB,disable,,,,

ここから、+0217が含まれる行を取り出して。。。と考え、

awk -F, '$3~\+0217 {print $4,$6}' n.dat

としたのですが、エラーでうまくいきません。

ご教授いただけますでしょうか。
リダイレクトに関する質問です。
メッセージを標準出力とファイルの両方に出力するにはどうすればいいでしょうか。
Makefileの生成コマンドに記述したいのですがエレガントな方法が思いつきません。
具体的には、次のようなことがしたいのです。

cc -c hoge.c 2> err; cat err; cat err >> error

エラーを標準出力に表示しつつも、errorファイルに記録したいのですが、
なんかかっこ悪いし、makeを-jオプション付で実行したときの一時ファイルerrの
排他なんかも気になります。
特別なコマンドを使う等の環境依存はないようにしたいのですが、よい方法はないでしょうか。
>>387
awk -F, '$3~/\+0217/ {print $4,$6}'
>>388
標準出力も標準エラー出力も、画面とファイルに出力するなら、

cc -c hoge.c 2>&1 | tee err
391387:05/02/18 12:00:51
>>389
ありがとうございます。うまくいきました。

で、今度は応用として、変数も使いたいと思いまして、

MMDD=+0217
nawk -F, -v TDAY=$MMDD '$3 ~TDAY{print $4,$6}' n.dat

としたのですが、エラーになります。。。

+がネックになるみたいです。
教えて君で申し訳ありません。ご教授いただけるとありがたいです。。。
>>391
そういう場合は、awk側の変数を使わずに、
シェル変数として展開させる。

MMDD=+0217
awk -F, '$3 ~/'$MMDD'/ {print $4,$6}' n.dat

シングルクォートを一回閉じてから $MMDD を挟み込んでいることに注意。
393388:05/02/18 12:18:35
>>390
うを、teeなんてコマンドが。
ありがとうございます。抜群でした。
394387:05/02/18 12:49:35
>>392
MMDD="\+0218"
awk -F, '$3 ~/'$MMDD'/ {print $4,$6}' n.dat

これでいけました。
ありがとうございます!ほんとうに助かりました!
1つのファイルを2つに別けたいのですが
その方法をご教授ください。

[test.txt]
AAAAhogeBBBBB
ABCDEFGhogeHIJKL
12345hoge67890
maehogeusiro

1行にhogeが1回しかないことを前程にして

[mae.txt]
AAAA
ABCDEFG
12345
mae
[usiro.txt]
BBBBB
HIJKL
67890
usiro

mae.txtとusiro.txtに別けたいのですがお願いします。
スクリプトと関係ない話が続く。
シェルスクリプト書くための要素技術なんだからいいんじゃない?

>>395
sed 's/hoge.*//' test.txt
sed 's/.*hoge//' test.txt
>>395
awk -F hoge '{print $1}' test.txt > mae.txt
awk -F hoge '{print $2}' test.txt > ushiro.txt
おや、このスレはえらい親切モードだね。
400名無しさん@お腹いっぱい。:05/02/18 17:06:53
教えない君は何ごとにも小さい奴。職人に多い。
シェルスクリプトに関する質問なら俺様がいくらでも答えてやる。
どんどんかかってこい。
ていうかさ、いろんなコマンドを組み合わせるglueとして働くのが
シェルスクリプトの便利なところ強力な所で、>>395などは適切な質問だろ。

(もし)それをわからないというなら、スクリプトの便利さ強力さを理解してない。
(もし)それをわかってて>>396みたいなレスしたなら、人に誤解を植えつける意地悪。
403402:05/02/18 17:18:20
あーそうか、簡単すぎてスクリプトにならんだろ(glueいらんだろ)という話か。
それはそうだったかもな...
404名無しさん@お腹いっぱい。:05/02/18 17:25:33
では、
10進数を2から16進数各々に変換する、
また、逆を行うスクリプトでかなりイケてる
ものを教えて下さい。
>>404
別にイケてないけど、漏れの.bashrcに↓こう書いてある。
function 2to8 () { dc -e "8o 2i $1 p"; }
function 2to10 () { dc -e "2i $1 p"; }
function 2to16 () { dc -e "16o 2i $1 p"; }
function 8to2 () { dc -e "2o 8i $1 p"; }
function 8to10 () { dc -e "8i $1 p"; }
function 8to16 () { dc -e "16o 8i $1 p"; }
function 10to2 () { dc -e "2o $1 p"; }
function 10to8 () { dc -e "8o $1 p"; }
function 10to16 () { dc -e "16o $1 p"; }
function 16to2 () { x=`echo $1|tr '[a-z]' '[A-Z]'`; dc -e "2o 16i $x p"; }
function 16to8 () { x=`echo $1|tr '[a-z]' '[A-Z]'`; dc -e "8o 16i $x p"; }
function 16to10 () { x=`echo $1|tr '[a-z]' '[A-Z]'`; dc -e "16i $x p"; }
406名無しさん@お腹いっぱい。:05/02/18 17:35:38
たぶん、最強
echo "obase = $ot; ibase = $in; print $un, \"\n\"" |bc;
% cat calc.sh
#!/bin/sh
num=$1
base=$2
w3m 'http://www.google.com/search?q='${num:=10}'+in+'${base:=binary}

% ./cals.sh 10
% ./cals.sh 10 octal
% ./cals.sh 10 hexadecimal
% ./cals.sh 0x10 decimal
% ./cals.sh 0b10 decimal
...
>>407
面白いな
翻訳機能板とかも持ってるだろ?それも出せ
>>404
何をイケてるというかによるが、適材適所なら>>406のbc使うのがいいだろうな。
expr使って桁ごとにがんばるのは馬鹿げてるし、
ましてやテーブル作ってexprの真似ごとをshでやるのはもっと馬鹿げてる。
馬鹿げてるから楽しい。
>>408
いや、持ってない(w。でも、普段はコマンドラインや w3m では使ってるから、手抜きの
スクリプトを作ってみた。

% cat ./tarns.sh
#!/bin/sh
TMPFILE=/tmp/trans.$$
trap 'rm -f $TMPFILE' 0 1 2 15

w3m='w3m -no-proxy -o use_history=0 -o confirm_qq=1'
t_or_u=$1
from=$2
to=$3

if echo $t_or_u | grep '^http' >/dev/null 2>&1; then
$w3m http://translate.google.com/translate_c'?u='${t_or_u}'&langpair='${from:=en}%7C${to:=ja}
else
echo -n 'text='${t_or_u:=text}'&langpair='${from:=en}%7C${to:=ja}'&ie=EUC-JP' > $TMPFILE
$w3m http://translate.google.com/translate_t -post $TMPFILE
fi

% ./trans.sh test
% ./trans.sh 'My name is unknown' en ja
% ./trans.sh 'Ich liebe dich' de en
% ./trans.sh 名無しさん@お腹いっぱい ja en
% ./trans.sh http://www.yahoo.com
% ./trans.sh http://www.yahoo.de de en
...
ごめん、confirm_qq=0 の間違い
413405,408:05/02/18 20:22:40
>>411-412
thanx!すごく楽しめそう

漏れの環境のw3m 3.22ではuse_history=0はエラーになった。


414405,408:05/02/18 20:26:19
礼として漏れが使ってるのをうpする。

X上の端末でhtmlファイルを見つけた時に、mozillaで開く為のスクリプト

#!/bin/sh

if [ $# -gt 0 ]; then
ARG1=${1}
if [ ! -f "${ARG1}" ]; then
echo "${ARG1} was not found."
exit 1
fi
PATH1=`echo "${ARG1}"|cut -b 1`
if [ ${PATH1} = '/' ]; then
mozilla "file://${ARG1}"
else
PWD=`pwd`
mozilla "file://${PWD}/${ARG1}"
fi
else
mozilla
fi
exit 0
415413:05/02/18 20:40:15
質問です。
以下のスクリプトを動かそうとすると、[: -le: unary operator expected と怒られます。
ぐぐったら、UNLIMITをどうのこうのと書いてありましたが、良くわかりません。
ちゃんと自分の考えた通りに動くのですが、このエラーメッセージを消すためにはどのような
ことをすればよろしいでしょうか。よろしくお願いします。
#! /usr/bin/bash

ulimit -c 0  #これをするとcoreファイルを作らない。

byeps(){ #選択したプロセスの番号が正しいかチェックする関数
read BYE
if [ $BYE -le $NUM ]; then
GO=1
elif [ $BYE -le $NUM ]; then
GO=0
echo -n "Please type the number you want kill,not ps number."
elif [ "$BYE" = "exit" ]; then
echo done
exit
else
GO=0
echo -n "Please type the number you want kill,not ps number."
fi
}
416413:05/02/18 20:40:58
yn(){  #yかnかを聞く関数。
echo -n "${KILL[$BYE]} ${PROC[$BYE]} OK?(y/n)"
read REP
if [ "$REP" = "y" ]; then

PASS=1
kill -HUP ${KILL[$BYE]}
echo -n ${PROC[$BYE]} "is killed"
echo -e \\t

#elif [ !$REP ]; then

elif [ "$REP" = "n" ]; then

PASS=1
echo "Good bye."

else

PASS=0
echo -n "Please type y/n"
fi
}

###############メイン###################
NUM=`ps auwx | grep $USER | sort | wc | awk '{print $1}'` #自分のプロセスをwcした行の数字
ps auwx|grep $USER > $HOME/proccess.dat     #proccess.datにpsの結果を代入
KILL=(`cat $HOME/proccess.dat|awk '{print $2}'`)   #killするプロセス番号をkill[]に入れる
PROC=(`cat $HOME/proccess.dat|awk '{print $11 $12 $13 $14}'`)  #パスをある程度分までPROC[]に入れる

echo -n "your ps auwx|grep" $USER "are ...."
echo -e \\v

for i in `seq 1 $NUM`; #C言語ふうのfor

do
echo -n "$i"
echo -e -n \\t
echo -n "${KILL[$i]}"
echo -e -n \\t
echo "${PROC[$i]}"
done
echo -n "Please enter the number you want to kill:"
GO=0
while [ $GO -eq 0 ];do
byeps #関数byeps
done
PASS=0
while [ $PASS -eq 0 ];do
yn #関数yn
done
rm -rf proccess.dat
exit
これは、kill プロセス番号とやるのにpsしてプロセス番号を調べないといけないのを億劫に思って、
スクリプトの勉強も兼ねて作ったスクリプトです。つたないですが、よろしくおねがいします。
418415:05/02/18 20:44:10
すいません。さっき見てたときに412でレスがストップしていたので、413とかいてしまいましたが、>>413さんとは
別の人です。ごめんなさい。
419405,408,413,414:05/02/18 20:59:12
>>418
今、抗議しようと思ってたところだ

確かめずに番号書くなよ
416では
> if [ "$REP" = "y" ]; then
って書いてるのに、どうして415では
> if [ $BYE -le $NUM ]; then
にしちゃうんだよもん?。
421418:05/02/18 21:08:56
>>419様 申し訳ありませんでした。

>>420様 関数をひとつにまとめるということですね。
>>420

頭がこんがらがってひとつにまとめることができませんでした。
ってか、こんな小さなプログラムなのに関数を作るなんてわたしはなにを考えているのでしょう。
ごめんなさい。少し時間を下さい。
seqをjotに変えて動かしてみたけど、エラー出ないぞ

ところでtopって知ってるかい
424418:05/02/18 22:41:45
>>423

はうあ!!! topでk押したら大変なことが起きました。
ありがとうございますだ。m(_ _)m
>>378,381
ありがとー^^おかげで解決しました。
427名無しさん@お腹いっぱい。:05/02/19 17:52:39
aはb,c...から作られていることを表すリストa: b, c, ...から
aからxまでのパスを見付けたい。
例えば
c: a, b
d: a, c
e: b, c
f: d, e

aからfまでのパスは
c: a,b
d: a, c
f: d, e
となるスクリプトを教えて下さい。
シェルスクリプトでやる意味あんの?
ム板のお好きな言語のスレへ行くのが適切では。
>>427
うはwwwwwwwwwww何をww言ってるかwwwwwwwww分からないwwwwwwwwwwwwwwwwwwwwwwwwwww
俺も意味わからん。解読できる>>428はすごい。
>>427
後半の意味がわからないが、make使えばできそう。
>>427
目的は?宿題なら自分で。
>>427
最終端から逆に辿っていけば楽にできるっしょ。
まぁ shell script で書く気にゃなれんがw
たぶん隣接リストでグラフ探索かなと予想
435名無しさん@お腹いっぱい。:05/02/19 18:39:39
>>427
すみません、例題のパス指定を間違えました。
例えば
c: a, b
d: a, c
e: b, c
f: d, e

aからdまでのパスは
c: a,b
d: a, c
を表示するスクリプトを教えて下さい。
436名無しさん@お腹いっぱい。:05/02/19 18:47:53
>>435
#!/bin/sh
echo "c: a,b"
echo "d: a, c"
>>427>>435の違いがわからん(´・ω・`)

説明のどこがどう改善されたの?
なんか元の問題を推測するスレになってるw

> aからdまでのパスは
> c: a,b
> d: a, c

d: a,c だけでいいんじゃねーの? c: a,b が必要になる理由がわからん。
それとも b: a というルールがあるか a,b ともに初期条件なのか。

でもどう考えてもシェルスクリプト関係ねーし、
質問者の説明能力がchallengedだし、
ム板の宿題スレに行った方がいいと思うよ。
439名無しさん@お腹いっぱい。:05/02/19 20:04:55
>>432
最終的にはクリティカルパスを求めたいのです。
440名無しさん@お腹いっぱい。:05/02/19 20:14:52
#!/bin/sh

line1=________
line2=________
line3=________
line4=___OX___
line5=___XO___
line6=________
line7=________
line8=________

というシェルスクリプトで、
オセロの次の一手を求めるにはどう書けばいいでしょうか?

とりあえず、以下のスクリプトで、
現在の番面表示はできています。

echo \
"$line1
$line2
$line3
$line4
$line5
$line6
$line7
$line8"
441login:Penguin:05/02/19 20:16:44
すみません、2つの引数をとるシェルプログラムでその引数を四則演算するにはどうしたらいいですか?
442441:05/02/19 20:23:36
書き忘れました、環境はRed Hat Linux release 7.1です
>>441
まさか、
expr $1 + $2
とか、
echo "$1 + $2" | bc -l
とか、そんな基本中の基本を聞いてるんじゃないよな?
>>440
ネタだよね?
>>439
一行で書けるが宿題っぽいので教えない(AA略
>>440
echo -n "次の手を入力してください: "
read itte
>>446
ネタだよね?
このところいい感じだったのに、今日はひでぇな
>>440
ネタだろうけどマジレスするぞ。

. next_hand.sh

line1=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 1`
line2=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 2`
line3=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 3`
line4=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 4`
line5=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 5`
line6=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 6`
line7=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 7`
line8=`next_hand $line1 $line2 $line3 $line4 $line5 $line6 $line7 $line8 8`

と、書けば、原理的には桶のはず。
あとは、シェル関数の定義が入ったnext_hand.sh の作り方次第だ。がんがれ。
>>450
それだと、シェル関数 next_handがidempotentでなかった場合、
lineごとに矛盾が起きる。
それに、そもそも8回も呼んでコマンド置換するのは無駄。
そもそもシェル関数の変数はグローバルなんだから、
内部で全変数に代入して終り。

よって、

. next_hand.sh

next_hand

でOK。あとはシェル関数次第w
>449
宿題君を甘やかすとどこでも必ずこーゆー流れになるな
ちうか、最初の呼び出しでline1壊しちゃうからダメじゃん。
マジレスといいつつ >>450 自体もネタだな。
454名無しさん@お腹いっぱい。:05/02/19 22:20:52
まぁこのスレもネタなんだけどな
455名無しさん@お腹いっぱい。:05/02/19 22:58:08
少しはMac板のスレを見習えよ・・・。

Macでシェルスクリプト総合 Part 1
http://pc7.2ch.net/test/read.cgi/mac/1105074933/
シェルスクリプトとスクリプト言語(perl, ruby, python等)をどう
使い分けていますか?
シェルでできることなら、シェルスクリプト。
できなかったら、awk, perl 等のスクリプト。(ruby は嫌いじゃ。python は使ったことない。)
それでもだめなら、C とかで組む。
>>455
ワロタ
この板の住人にはムリと思われ
ちょっとだけのつもりだったシェルスクリプトが
肥大化して複雑怪奇になってから
こんなことなら最初からperlあたりで書けばよかったorzと後悔することも多い
460名無しさん@お腹いっぱい。:05/02/19 23:37:43
>>455
Mac板に割にはえらい機能してるスレだな。
Paperとやらのレベルは低そうだが。
461名無しさん@お腹いっぱい。:05/02/19 23:40:54
>>455
ここにあったんだが、
こういうのをシェルスクリプトだけで書こうとするところは
低能なマカらしいなw

http://sheel.mynds.jp/~sheel/temperature.zip
>>460-461
455はそのふたりのための隔離スレなんですが(w
>>461
そいつは向こうでも馬鹿で嫌われてる奴だろう。
例えるなら n=(ry か?
464名無しさん@お腹いっぱい。:05/02/20 00:25:58
ここで良いのか分かりませんが、
sedのコマンドファイルは30行ぐらいしか書けないとの制限がある
と聞いたのですが本当でしょうか?
試してみれば?
特定の文字列と文字列の間の文字列を抽出するスクリプトって無いですか?

'abcdefghijklmn' に対して 'abc' と 'gh' を指定すると 'def' を返すような。


それくらいsed使えば楽勝かと思って取り掛かったら、なんか全然難しくて orz
それくらい楽勝。正規表現を勉強するよろし。
>>466
grep と >>397 さんの組み合わせるだけでできたよ。
sed だと最小マッチがないから単体だとやりにくいかもね。
echo "$1" | sed 's/^.*'"$2"'\(.*\)'"$3"'.*$/\1/'
じゃだめなの?
$ cat hoge.sh
#!/bin/sh

sed -e "s/^.*$1//" -e "s/$2.*$//" "$3"

$ echo 'abcdefghijklmn' | ./hoge.sh abc gh
def
条件にマッチしない行のことを考えると
sed -n "s/...../p"
じゃないとダメだと思う。
マッチするものが一行に複数ある場合も考えてみた

#!/bin/sh
sed -n "/$1/s/[^$1]*$1\([^$2]*\)$2[^$1]*/\1:/gp" "$3"

補足。
引数の$1,$2はそれぞれ1文字じゃないとダメ。
475ななしさん:05/02/20 14:06:46
九九を表示するシェルプログラムをwhileを使って作成するにはどうしたらいいですか?

1 2
2 4
3 6
4 8
5 10
6 12
7 14
8 16
9 18 ・・・・
#! /bin/sh
cat 9x9table.txt | while read tmp
do echo $tmp
done
#!/bin/zsh

for ((i = 1; i <= 9; i++)) {
for ((j = 1; j <= 9; j++)) {
printf "%3d" "$((i * j))"
}
print
}
うはwwwwwwwwwwwwwwwwhile使ってwwwwwwないやwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww
最後に#whileって付け加えりゃいいだろ
480ななしさん:05/02/20 14:28:12
>478
>479
逝ってよし
#!/bin/sh
a=1
while [ $a -le "9" ]
do
b=1
while [ $b -le "9" ]
do
echo $a "x" $b "=" `expr $a \* $b`
b=`expr $b + 1`
done
a=`expr $a + 1`
done
>>479
ワロタ
yes ""|head -9|cat -n|while read a; do yes ""|head -9|cat -n|while read b; do echo $a x $b = $(($a*$b)); done; done
二つの引数の間の数を表示するシェルプログラムを作成してみよう。
回答例
test3.sh 3 5
3
4
5

お願いします
>>475 >>484
いいかげん「シェルプログラム」なんていう自分勝手な用語は改めてください。
>>484
宿題は自分でやれ
同一人物?>>475, >>484
九九の例で出してもらったスクリプトの意味を理解したら、
>>484はすぐできるでしょ。
>>484
#!/bin/zsh
print -l {$1..$2}
>>484
echo -n $1 . ; while true; do echo -n 0; done ; echo 1
490名無しさん@お腹いっぱい。:05/02/20 23:02:06
>>484
#!/bin/sh
seq $1 $2
ファイルサイズが0とそれ以外の場合で
実行結果を変えたいのですが、その方法を教えてください。

現状では
ファイルの編集 $ORIGINALFILE > $TMPFILE
cat < $TMPFILE >> $SAVEFILE
と、なっています。

これを、一時ファイルのサイズが0の場合に
$TMPFILEではなく$NODATAを実行するようにしたいのですが
どのように書き加えたらよいでしょうか?
[ -s
man test
man test

495名無しさん@お腹いっぱい。:05/02/21 03:29:04
縦読み文章を作れるシェルスクリプトの書き方が分かりません。
どなたかご教授願います。

実行例
./aaa.sh "ゆにっくす"

ゆるぎない
にこちん
っつーのは
くそまみれの
するめいか
やなこった
>>495
シェルでやんなきゃいかんの?
たとえば"ゆ"で始まる文がたくさん欲しいよね
それはどうするの?
$ cat aaa.sh
cat <<EOF
ゆるぎない
にこちん
っつーのは
くそまみれの
するめいか
EOF
お題を出して、それに答えが返って来るのを見て喜んでる香具師がいるな
おまいら遊ばれてんじゃね?
501名無しさん@お腹いっぱい。:05/02/21 11:26:08
それはそれで良いんじゃない?
catしただけの答えとか、
本人はそれで気の効いた回答だと思っているのかどうか、気になる。
気を効かせる必要はないので気にするな。
504500:05/02/21 11:43:20
> それはそれで良いんじゃない?
予想外の反応だった…
何か自分の心の狭さを思い知らされたみたいで鬱だ… orz
しばらく消えます
有用でもなく、笑えるわけでもないレスを
なぜわざわざ書くのかは気になるなぁ。
507491:05/02/21 21:58:58
>>493-494
man test 読んでもわかんね・・・・orz


週末にでも本屋に行って>>3の本を探して立ち読みしないとだめかな
個人的には入門bashがおすすめ
>>507
いや、>>492なんかそのまま答えだぞ。if文、書ける?
Learning the bash shellを買った。
なかなか進まんw
>>507
>>2 のサイトを読んでみるといいと思う。本屋まで行かなくても読めるし。
とりあえず、一番上のBourne Shell自習テキストあたりを。

あとは man sh とか man bash とかやって
if list とかで検索すれば、if 文の説明があるはず。
512名無しさん@お腹いっぱい。:05/02/22 10:24:53
イケてる小町算を見せて下さい。
513名無しさん@お腹いっぱい。:05/02/23 10:37:26
>>512
ふつうの
#!/bin/bash
function koma () {
if [ $1 -eq 10 ]; then
if [ $(($2)) -eq 100 ]; then
echo $2 = $(($2));
fi;
return;
fi;
for aa in "" + -; do
koma $(($1 + 1)) $2$aa$1;
done;
}

koma 2 1;
linux板かと思った
質問です。(ここで良いか分かりませんが…)

PHPとか使ってブラウザから特定のシェルを実行させたいのですが、
どこかにサンプルや解説サイトってありませんか?
>>515
>>1
>・シェルスクリプトのことをシェルってゆーな

PHP でやりたいってのならスレ違いor板違いじゃないか?
>>515
「php exec」でググってくれ。
あとは、WebProg板で質問してね。
518515:05/02/24 08:42:24
>>516-517

Thanks. m(_ _)m
最近、シェルスクリプトの本を読み始めたんだけど「^」ってどういう意味?
ググってもいまいちズバって答えてるサイトが見つからなくて(´・ω・`)
優しくてエロい方、教えてください。
>>519
文脈に依存する
521519:05/02/24 19:59:32
>>520
まじまじまじで?
では「learning the bash shell」のP106から引用します。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーー
function lsd
{
date=$1
ls -l | grep -i "^.\{42\}$date" | cut -c55-
}
ーーーーーーーーーーーーーーーーーーーーーーーーーーーー
         ↑
         ここ
522519:05/02/24 20:00:20
ちょっとずれたがご勘弁。優しくてエロい方、お願い!!
エロくないので自粛しよう。
正規表現
文頭
>>521
grep -i "^.\{42\}$date"が^を解釈すべき文脈。
というわけで、grepの引数に^がどう解釈されるか調べるといいよ。
まずはmanだね。

正規表現という話に行き当たるはず。

つか、その関数、期待どおりに動くか?
昔のshは ^ がパイプだったなぁ
528519:05/02/24 20:30:38
>>523
(`・ω・´)

>>524,525
ありがとうございます。実はmanも読んだし、正規表現や文頭というキーワードも
掴んでいるんですが。

man grepから引用。
ーーーーーーーーーーーーーーーーーーーーーーーー
The caret ^ and the dollar sign $ are metacharacters that respectively
match the empty string at the beginning and end of a line.
ーーーーーーーーーーーーーーーーーーーーーーーー
この「the empty string at the beginning」という表現が分からないんです(´・ω・`)
the empty stringってのがなんの為にあるのか。
これは標準出力の文頭には必ず存在するものっていう解釈でいいんですかね?

>>526
動きますよ。
一応、「learning the bash shell」からさらに引用します。
ーーーーーーーーーーーーーーーーーーーーーーーーー
If this isn't the case in your version of UNIX, you will need to adjust the column numbers.
ーーーーーーーーーーーーーーーーーーーーーーーーー
>>528
「行頭」という特定の文字は存在しないよ
ってことを言っているのでわ。

"$" で言えば,
"$" は改行コードにマッチするわけじゃなく,
行末という概念的な(?)位置にマッチするんだよ,と。
530519:05/02/24 21:00:12
>>529
なるほど。
grep -i "^.\{42\}$date"
の場合の^は、「行頭から数えて」という意味のようですね。
もやもやが晴れました。ありがとうございました。
#読むとほのぼのするスレだなぁ
>>527 エラク昔の話だねw
>>528
>この「the empty string at the beginning」という表現が分からないんです(´・ω・`)

'^' や '$' にマッチした部分文字列をあとで参照した時,空文字列になるということを
明示的に表現している。
極端な例だと,sedで「s/¥(^¥).*/¥1/」とか。
...って,余計分かりにくいか。要するに>>529の理解で実用上問題ない。
^は、cshだと文字列痴漢だな。
^痴漢^置喚
534名無しさん@お腹いっぱい。:05/02/25 16:03:49
アナルは性器表現?
卑猥な表現
536名無しさん@お腹いっぱい。:05/02/25 20:25:20 ID:??? BE:26133247-#
あるファイルの特定の場所に特定の文字を記入するシェルスクリプトをかこうとしています。
自分で考えた方法は、

食事.shというファイルがあるとすると
echo "食べ物「/""$1"」を食べる
飲み物「/""$2"」を飲む" > menu.txt

とリダイレクションを利用し、
$ ./食事.sh カレー 水

$ cat menu.txt
食べ物「カレー」を食べる
飲み物「水」を飲む

として成功しました。
でもこれは、menu.txtをまるまる上書きしているだけです。
どうにか$1、$2の変数代入値を、直接menu.txtの「」内のみ
更新できるようなスクリプトを組みたいなと思い悩んでいます。
cutコマンドやgrepコマンドを使えばいいのかといろいろ考えてみたのですが、
どうもうまくいかないのです。
参考ページやアドバイスなどがありましたら、どうぞよろしくお願いします。
>>536
もしmenu.txtの「」内の変更で長さが変わったらそれ以降をすべてずらさないといけないので
"直接menu.txtの「」内のみ更新"は無理では?
叩き台ぐらいにはならないかな…

#!/bin/sh
ed menu.txt <<EOF
/「[^」]*」/s/「[^」]*」/「$1」/
/「[^」]*」/s/「[^」]*」/「$2」/
w
q
EOF
perl
540名無しさん@お腹いっぱい。:05/02/25 21:30:52
ruby
いろいろ調べてみたのですが、シェルスクリプトで別ファイルの
文字列を編集するのは少々手間がかかるみたいですね。
perlかrubyか、何か言語を勉強してみようと思います。
>>538にも出てるけどedかsedでええやん
まず正規表現の勉強をしろや
>>541 こんなのは?

##shokuji.sh
#!/bin/sh
INPUT=menu.txt
OUTPUT=menu.out
export TABE=$1
export NOMI=$2
sh -c "cat <<EOF > $OUTPUT
`cat $INPUT`
EOF
"

##menu.txt
食べ物「$TABE」を食べる
飲み物「$NOMI」を飲む
m4という選択肢もあるぞ。
546名無しさん@お腹いっぱい。:05/02/27 23:40:54
Xwindow GUIプログラムをシェルスクリプトで制御する
やり方を教えて下さい。
killとか
>>3にも出ている『UNIXシェルプログラミング徹底解説』 p145
「whileとuntilの違いは、いつ条件が評価されるか、という点です。whileでは、ループを繰り返すかどうかが
最初に評価されます。そしてtestやコマンドの結果が真であればループのなかの処理が実行されます。
これに対して、untilでは、ループの中の処理が実行された後で、条件が評価されます。つまり、untilの
なかの処理は、最低でも必ず1回は実行されるわけです」

信じてたよ、4,800円も出したから(今は5,200円するらしいけど)… orz
危うく恥かくところだった…

正誤表探したけどないみたいだったので、ここに書き留めておきます
>>548
俺もそう思ってたけど違うみたいだね
user's guide to the z-shell にそう書いてあった記憶がある
ファイル名を一括して変更するのに

#!/bin/sh
for i in `ls *.dat` ; do
j=`echo $i | sed s/2004/H16/`
mv $i $j
done

こんな感じで書いたのですが、ファイル名にスペースが入ってると正常に動きません
でした。shからcshやtcsh、bashに変えて(shell依存部分はちゃんと書き換えて)みて
もやっぱりスペースがあると誤動作します。

forとかforeachでこんな感じでファイル名を一括部分変更するのは無理?
for i in *.dat でどうよ
あああとmv
>>550
j="`echo 略`" のように " " で囲んで、
mv のところの $i $j もそれぞれ "$i" "$j" と。

スペースで問題がでるときは " " で。
>551, 553
アドバイスありがとうございます。
両方の修正を行う事で期待通りの挙動になりました。
氏名と得点の表tokuten.txtがあります。
---- tokuten.txt ----
波田陽区 23
青木さやか 35
---- tokuten.txt ----

別途、氏名と学籍番号の対応表gakuseki.txtがあります。
---- gakuseki.txt ----
青木さやか 4001
波田陽区 4002
---- gakuseki.txt ----

やりたいことは、氏名に対応する学籍番号でソートして得点表を表示することです。
例で言えば、青木さやか 23、波田陽区 35、という順に表示したいのです。

学籍番号のように、ソートのキーが外部への参照になっている場合、
単純にsortコマンドを使うことができないと思います。
どうすれば外部のキーでソートして、青木さやか、波田陽区の順に出るでしょう?

なお、氏名が同一の者はいないという仕様でお答えいただいて結構です。
556555:05/02/28 16:26:56
青木さやかの得点ちごうとる、35点やんか>自分

青木さやか 35
波田陽区 23

のような出力が得られればと思います。
宿題だろう。少しは自分で考えろよ。
join(1)ってコマンドがあるから、それ使えばできるよ。
555じゃないが初心者なので考えてみました。
下のようなのじゃ美しくない?

#!/bin/sh
for i in `awk '{ print $1 }' gakuseki.txt`
do
grep $i tokuten.txt
done
558じゃないが初心者なので考えてみました。
下のようなのじゃ美しくない?

sort -n -k 2 gakuseki.txt | \
sed "s/[ \t]\+[0-9]\+$//;s/.*/& &/;`sed 's|[ \t]\+\([0-9]\+\)$|$/\1/|;s|^|s/|' tokuten.txt`"
557で答が出てるのに558-559のようなのじゃ美しくない。
join(1)ってさ、natural join(RDB用語)じゃないんだよ。
natural joinしたい時には自分でバンバンしなきゃならんと思う。

ここでいうnatural joinとは、例えば青木さやかに関する得点行が
2つ以上あるときに、両方とも学籍番号4001を結び付けてくれることね。
join(1)は1つの行だけ4001を結びつけて、他の青木さやか行は捨てちゃうぞ。

555に関しては氏名が同一の者がいないからいいんだが、
一般にはnatural joinしたい場合の方が多くて(当社比)、とても困る。
例挙げると、得点表じゃなく、顧客への部品配送表だった時なんかだな。

joinってソートしたファイルでないとあかんのでないの?
>>561
当然氏名が同一じゃないっていう仮定を踏まえてるわけだが。
つーかああいう場合普通は学籍番号をユニークキーとして使うんであって、
同姓同名がありえる場合に氏名なぞキーとして使うわけない。
今気付いたけど「お答えいただいて結構です」てな凄い言いぐさだな。
565555:05/03/05 23:06:11
>>564
すみません。「---という仕様でお教えください」と書けばよかったです。

557さんを始めとするみなさん、join勉強になりました。
確かにnatural joinもあるといいと思いました。
566名無しさん@お腹いっぱい。:05/03/06 07:59:07
zshを使ってるんですが、cdした後にlsするのが面倒なのでいっそのこと
$alias cd='cd $1;ls'
としたのですが
$cd hoge
するとhogeには移動せずにhogeの中身をlsしやがります。ちなみに
$alias cd='cd $1;ls;'
して
$cd hoge
するとhogeに移動するけど ~/の中身をlsしやがります。
なんでですか。
>>566
なら初めから zsh のスレに書きたまえ

csh 系とは違って alias に引数を取れないよ。そういうときは関数を使う。
cd () { builtin cd $1; ls }

でも、この場合は関数 chpwd を定義するのが流儀にかなう。
568566:05/03/06 16:27:07
>>567
スレ違いにも関わらずレスありがとうございます。
もしかしたらスクリプトではなくaliasの問題かなとうすうす思ってたんですが。
勉強になりました。
ディレクトリをfindつかって消すスクリプトってどう書いたら簡潔に書けるの?

find . -mtime +4 -type d -exec rm -rf {} \;

で消えてくれないのは仕様?
4日以前のバックアップのディレクトリを消したいんだけど。

shか bashでやれ。
-mtime +4
ここが間違ってるから。man 1 findしる。
-depth つけろというのが根本だろ
>>571
-mtime +4 は間違ってないよ。
GNU findなら。
574572:05/03/07 22:27:02
いやそういう問題じゃないな、これ
非GNU findでも-mtime +4は使える。

多分、ファイルシステムががNFSマウントと思われ。
NFSの場合、あるディレクトリ以下のファイルを消しても、
それがオープン中だと、本当には消えず、
.nfsXXXX みたいなファイルが残り、
親ディレクトリが消せない。
たとえ rm -rf {} \; しても消えないよ。
>>573
ごめん、素で勘違いしてた。
GNU findでもBSD findでも同じ。
>>571=576ですが、読み返したら誤解を招きそうだったので補足。
-mtime +4は正しいです。
>>569ごめん。
パーミッションだったりして。
579569:05/03/08 11:50:47
みなさんありがとう。
環境はSolaris9でUFSです。

rmでなくってlsにしたらちゃんと目的のディレクトリを表示できたんですけ
どrmにしたら消えてくれないんですよね・・・なんでだろ?
ファイルの整理は問題無くできてるけど、ディレクトリが消えてくれないから
tarにして纏めちゃおうかと思ってみたりもしてますw
ディレクトリ以下が2G以上あるんですけどね。
if 今いるディレクトリにあるファイル($FOO)が存在したら
  rm $FOO

の if の箇所はどう書けばいいのでしょうか?

よろしくお願いします。
>>580

if [ -f "$FOO" ]; then
rm "$FOO"
fi

ただし、
rm -f "$FOO"
にすればそもそもif文は要らない。
どうもありがとうございます。
両方で確認しました。
>>579
find . -mtime +4 -type d -print | xargs rm -rf
でどう?変わらんかな?
# これでOKなら、>>572の-depthでもOKなはずだが...。
584583:05/03/09 00:46:08
> # これでOKなら、>>572の-depthでもOKなはずだが...。
でもないや。この部分だけ前言撤回で。スレ汚しすまそ
>>583
本題には関係ないけど、
find (略) | xargs rm -rf
すると、
findで見つかったファイル名の中に、
「hoge . hoge」みたいに、
<space>.<space>を含むファイル名があると、
rm -rf . が実行されてしまうのでvery危険。

なので、おれはxargsは使わない派。
-print0
% man xargs
OPTIONS
--null, -0
Input filenames are terminated by a null character
instead of by whitespace, and the quotes and back-
slash are not special (every character is taken
literally). Disables the end of file string, which
is treated like any other argument. Useful when
arguments might contain white space, quote marks,
or backslashes. The GNU find -print0 option pro-
duces input suitable for this mode.
findの-print0や、
xargsの-0は、
GNU find, GNU xargsでしか使えないんだよ。
589名無しさん@お腹いっぱい。:05/03/09 09:21:18
GNUマンセー
>>588
FreeBSD の man だと以下なので, posix 準拠な OS の場合は
xargs -0 は使えそうだが...

man xargs
-0 Change xargs to expect NUL (``\0'') characters as separators,
instead of spaces and newlines. This is expected to be used in
concert with the -print0 function in find(1).
STANDARDS
The xargs utility is expected to be IEEE Std 1003.2 (``POSIX.2'') compli-
ant. The -J, -o, -P and -R options are non-standard FreeBSD extensions
which may not be available on other operating systems.

man find
-print0
This primary always evaluates to true. It prints the pathname of
the current file to standard output, followed by an ASCII NUL
character (character code 0).

STANDARDS
The find utility syntax is a superset of the syntax specified by the IEEE
Std 1003.1-2001 (``POSIX.1'') standard.

All the single character options except -H and -L as well as the -iname,
-inum, -iregex, -print0, -delete, -ls, and -regex primaries are exten-
sions to IEEE Std 1003.1-2001 (``POSIX.1'').
少なくとも{Free,Open,Net}BSDでは使えるな
592名無しさん@お腹いっぱい。:05/03/09 13:10:15
質問元です。Solarisは該当するオプションはなさそうです。Installしてもいいんですけど、もうちょっと考えてみますね。
素直に xargs -i rm -rf {} すればイイんじゃないのかね。
問題になりそうなファイル名のファイルがなかったら
気にしなくてもよいかと。
シェルスクリプトのことをシェルってゆー人が多いのが不思議です。
携帯電話をケータイって言うようなもんだ
携帯電話を電話って言うようなもんだ
JavaScriptをJavaって言うようなもんだ
シェルスクリプトはシェルが実行するが、
JavaScriptはJava(VM)が実行するわけじゃない。
PerlスクリプトをPerlって言うようなもんだ。
rubyスクリプトをrubyって言うようなもんだ。
もういいから。
ポストスクリプトをポストって言うようなもんだ。
ポストスクリプトをポストって言うようだなもん。
ポストスクリプトをポストって言ううなだよもん。
NullPointerExceptionをヌル(ry
ガッを力"(ry
608名無しさん@お腹いっぱい。:05/03/11 08:36:32
send + more = money
を解いてください。
>>608
ググった方が早い。答えどころか、解くためのプログラムもでてるし。
>>608
【解答】パズルのプログラミング【作成】
http://hobby5.2ch.net/test/read.cgi/puzzle/1092459010/
611名無しさん@お腹いっぱい。:05/03/11 16:46:53
>>609-610
シェルスクリプトでは無理ですか?
シェル変数に入れてexprしまくればできるんじゃない?
bash限定なら (( 算術式 )) 使いまくれば高速かも。
613名無しさん@お腹いっぱい。:05/03/11 18:19:36
/home/test以下にある幾つかのシェルスクリプトから文字列1・文字列2・文字列3を削除
したく思い、下記のようなスクリプトを作成したのですが、何故か文字列3しか削除されま
せん。
文字列1・2・3ごとにそれぞれ3つのスクリプトを作成し、順番に実行すると文字列1が削除
できた後に文字列2を削除するスクリプトを流すと文字列1が復活して文字列2が削除され
てしまいます。
何が悪いのでしょうか?教えて下さい

#!/bin/sh

for i in *.sh
do
sed -e "s/文字列1//g" $i > /home/test/$i
done


for i in *.sh
do
sed -e "s/文字列2//g" $i > /home/test/$i
done


for i in *.sh
do
sed -e "s/文字列3//g" $i > /home/test/$i
done
$iから読んでいながら、$i(/home/test/$i)に書いてもいるのが悪いと思う。
615613:05/03/11 19:44:06
>>614
レス有難うございます。
何となくそれが理由っぽいですね。

このように、ある文字列を複数のファイルから削除したい場合はどんな方法が良いので
しょうか?
ファイルを加工する時は、別のファイルに出力して最後にファイル名を付け替えるのが常道。
テンポラリファイルの名前を作るのに$$(=シェルのプロセスID)を使ったりとか。
>>614
同じファイルだと空っぽになるだろう。
>>613
> /home/test以下にある幾つかのシェルスクリプトから
といいながら別のディレクトリで作業してると思われ。
>>615
言ってることとやってることが違うようだが、
sed のスクリプトをまとめれば欲しい結果になるんじゃないのか?

sed 's/文字列1//g;s/文字列2//g;s/文字列3//g' $i > /home/test/$i
>>615
まあ常套手段としては、読み込み元を〜.origとか付加してリネームしてから、
オリジナルのファイル名に書き出すな。
丁寧にやるなら、〜.newとかに書き出して、書き出し成功(-fなどで存在確認)
したら、オリジナルを〜.origにリネームするなり削除するなりしてから
〜.newを元のファイル名に戻すとか。
#!/bin/sh
fl=/home/test/*.sh
for i in $*
do
for j in $fl
do
sed -e "s/$i//g" $j > $j.new
if [ -f $j.new ]
then
#オリジナルを残す場合
mv $j $j.orig
# オリジナルを削除する場合
# rm $j
mv $j.new $j
fi
done
done

で、sh hoge 文字列1 文字列2 文字列3・・・ とか。
あとは/tmpとかに書き出して上書きして戻すとか。
最近思い付いた技だがどうよ
shar * | sed '/^X/s/hoge/moge/g/' | sh
>>611
できたよ。m=1,o=0はとりあえず決め打ちで $(( )) だと30秒、exprだと4分かかるのが。
shar って初めて知ったよ。なかなか面白いね。
/bin/shellのソースってどこらへんから落とせばよいでしょうか。
プロセス制御まわりを読みたいだけなのでbashとかじゃなくて
簡単・短いやつを探しています。
どっかでcvswebとかで公開してないでしょうか。
/bin/shellって、/bin/shのこと?
ashでよければ、 http://www.freebsd.org/cgi/cvsweb.cgi/src/bin/sh/ かな。
>>>624
半分寝ながら書いてたのでボケてました。
アリガトです。
626名無しさん@お腹いっぱい。:05/03/12 13:20:16
>>626
プロセス制御まわりはないとおもうぞ.
>>623 の言う「プロセス制御」が、ジョブコントロールのことなら、
元祖Bourne Shellにはジョブコントロールは無い。
ashにはジョブコントロールがあるので、手頃に小さいソースなら、
ashが適してるかな。
>>628
ジョブコントロール元祖の csh の方が(ry
script コマンドをスクリプト内で使って
そのまま処理するのって無理?

script
script コマンドをスクリプト内で使って
そのまま処理するのって無理?

#!/bin/sh
script
 #保存中
 echo 処理結果
 #保存抜ける
XXX

630-632 連投ゴメン
こんな処理は可能ですか?
XXXは scriptコマンド終わらせる何かを…
find の -exec に関数を使いたいんですけど,実行すると

find: ff: No such file or directory

というエラーになります。できればスクリプトファイルを
分けずに処理したいのですが,良い方法があったら教えて
くださいませ。

#!/usr/bin/bash
#GNU bash, version 2.05b.0(1)-release (i686-pc-cygwin)
function ff ()
{
        echo $1
}
export -f ff
find . -true -exec ff {} \;

上記は記述例です。echo したい訳ではないです。
>>633
本質的に-execにシェルの関数は使えません。
findからさらに子プロセスを起こすわけだから。

find -printした結果のパス群をwhile readで受け、そのループ内で
関数を呼び出すというのは解法の一つかと思います。
-exec 内で function 定義するという愚直な方法もあるね。
list=`find . -true`
for i in $list
do
ff $i
done
とか
>>631
script hoge
>>634, >>636
THX
639637:05/03/13 20:13:33
>>637は間違い。正しくは
SHELL=hoge script
識者のみなさん質問させてください。
csh でワイルドカードを認識して処理させるにはどうしたら良いでしょうか?

たとえば
> ls
AAA/ AA7/ AAA/ AAC/
AB9/ BGS/ BBF/ DDD/
DEF/ EEE/ EEG/ GGG/

というフォルダがあったとします。
ここでhogehoge というスクリプトを作って

hogehoge A* で
AAA/ AA7/ AAA/ AAC/ AB9/
hogehoge A?A で
AAA/ AAA/ AAC/
の配下に存在するファイルを編集するといった事が目的です。

------hogehoge.csh
#!/bin/csh -f
set folder = "`ls $1`"
echo $folder
-------

> hogehobe.csh A?A
> AAA/ AAA/ AAC/

となってくれれば良いのですが、
no match
となってしまいます。お知恵をお貸しくださいませm(*-*)m
641640:05/03/16 23:37:56
すいなせん。思いっきりまちがえました
> ls
AAA/ AA7/ AA9/ AC9/
AB9/ BGS/ BBF/ DDD/
DEF/ EEE/ EEG/ GGG/

てフォルダがあって

> hogehobe.csh A?9
> AA9/ AC9/ AB9/

といったことがやりたいです。説明下手ですいません。


フォルダか…
>>640
ワイルドカードを誰が展開してるのか
おれおれ。
645640:05/03/17 00:28:03
>>643
ん?直訳するとC-SHELLでは不可能ということなのですか?
すいません知識不足なもので。
>>641
echo A?9
>>640 >>645
#!/bin/csh
echo $#
ってスクリプトを実行してみるといいと思う。
#!/bin/csh
echo $#argv
649640:05/03/17 01:09:03
>>643-648
みなさん短時間に沢山のレスありがとうございます!

#!/bin/csh
echo $#argv
hogehoge.c A?9
とやってみたら
> 3
だと!そして
#!/bin/csh
echo $#argv
echo $argv[1]
echo $argv[2]
echo $argv[3]
echo $1
echo $2
echo $3
だと
hogehoge.c A?9
> 3
> AA9
> AB9
> AC9
> AA9
> AB9
> AC9
!!おお!!勝手にむちゃくちゃ感動してますw
ありがとうごさいました!m(*-*)m
特定の文字列がある行から文字列までを表示するいい方法はありませんでしょうか?

例えばfoo、barの間

foo
aaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaa
bar

というファイルの aaaaaaaaaa を表示したいのです。
sgrep
awk '/foo/{p=1;next} /bar/{p=0} /.*/{if(p==1){print $0}}' file
とか。
この場合再びfooが現れたらまた表示し始めるが、一回で終わらせたければ
awk '/foo/{p=1;next} /bar/{exit} /.*/{if(p==1){print $0}}' file

fooの行を表示に含めたい場合はnextを外す。
barの行を表示に含めたい場合は/bar/のルールを一番後ろに持ってくる。
sgrepがあればいいんだけど、漏れは次のようなスクリプトを $HOME/bin に投げ込んでいる。

#例外処理と拡張機能は省略
start=$1
end=$2
read_flag=0

while read line; do
if [ "$read_flag" = 1 -a "$end" = "$line" ]; then
read_flag=0
break
fi
if [ "$read_flag" = 1 ]; then
echo $line
fi
if [ "$start" = "$line" ]; then
read_flag=1
fi
done
sed '/^foo$/,/^bar$/p;d' <file> | sed '/^foo$/d' | sed '/^bar$/d'
655654:05/03/19 15:26:16
あ、表示したい文字列の中に開始文字列が含まれてたらダメだな。
シェルスクリプト修行中の身なのですが、
時々、${1+"$@"} というのを見掛けますが、これって何でしょうか?
何故単に "$@" と書かずにこう書くのでしょう?
そもそも { } の中の「1+」って?そんな書き方があるのでしょうか?
(エラーにならないということはあるのでしょうが…)

Google先生は記号の検索はできないみたいで困ってます。
ヒントを頂けないでしょうか?

常識も無いのかよ、クズが
>>656
${parameter:+word} で parameter が 1,2,... の時の省略形
あとは man sh すれば書いてあるはず.
659656:05/03/19 17:09:52
>>657
すみません。もっと勉強します

>>658
> parameter が 1,2,... の時の省略形
ありがとうございます。すっきりしました。
聞いてみてよかったです
連番ファイル (A.000 A.001 A.002〜A.023) を結合して A.DAT にしたいんですが
foreachなりforって必ずファイル名の若い順に処理されると決まってるんでしょうか?

それともファイル名のソートは自分でちゃんと行わないとダメですか?

foreachで (a*.dat) で引っかかるファイルをcatで結合させるスクリプトを
cat $(ls -1 A.0??|sort) > A.DAT
662650:05/03/20 00:27:04
ありがとう。参考にさせていただきます。 sgrepなんて初めて聞きました
>>650
別解として
printf '/foo/+;/bar/-p' | ex -sR file
あ、ごめん。最後に\nがいるわ。
665名無しさん@お腹いっぱい。:2005/03/21(月) 10:38:28
乱数を発生させる方法ってある?
いい加減なのでいい。
zsh 不可。
666665:2005/03/21(月) 10:41:29
www.faqs.org/faqs/unix-faq/

echo $RANDOM
を見つけたけど、range を指定できると嬉しいんだけどなぁ…
667名無しさん@お腹いっぱい。:2005/03/21(月) 11:31:56
>>665
/dev/urandomを使う。ddで読んでmd5にでも渡す。
668名無しさん@お腹いっぱい。:2005/03/21(月) 17:48:00
>>666
余りをとるとか
669名無しさん@お腹いっぱい。:2005/03/21(月) 18:03:34
なんで/dev/にあるんだろう
理解不能
670名無しさん@お腹いっぱい。:2005/03/21(月) 18:10:15
/dev/random は環境ノイズのみで
/dev/urandom は数学的に計算した乱数も返すことがある

だっけ?
671名無しさん@お腹いっぱい。:2005/03/21(月) 18:13:48
>>669
他に適任な場所がなかった
ぶっちゃけ何処でも良かった
今は反省している
672名無しさん@お腹いっぱい。:2005/03/21(月) 19:36:26
>>656
${1+"$@"}と書く必要はない。
"$@"でじゅうぶん。
${1+"$@"}の意図は、パラメータの個数がゼロの場合に、
空文字列にすら展開させないようにするためと思われるが、
"$@"と書いても、空文字列には展開されず、
何もなかったものと同じになる。
${1+"$@"}と書くのは恐らく、超古いシェルのバグかその辺に対応するためと思われる。
"$@"
でよろし。
673656:2005/03/21(月) 21:24:06
>>672
ありがとうございます
674名無しさん@お腹いっぱい。:2005/03/21(月) 21:39:55
ところで、${1+"$@"}と書かなければならない(引数なしの時、空文字列が残る)
シェルのバージョンってどの辺?
675名無しさん@お腹いっぱい。:2005/03/21(月) 23:44:29
でも csh で動かされると、${1 + "$@"} って動かねぇよな。
676名無しさん@お腹いっぱい。:2005/03/22(火) 21:47:41
>>669
(仮想的に) デバイスだから。

汎用機なら仮想じゃないやつもある。
677名無しさん@お腹いっぱい。:2005/03/22(火) 23:21:27
PC 用の USB な乱数発生器もあるよ。
678名無しさん@お腹いっぱい。:2005/03/22(火) 23:32:47
こういうのって
http://www.fdk.co.jp/cyber-j/pi_ic_rpg100.htm
計算による補正みたいなのがなくても真にランダムな結果が保証されてるの?
679名無しさん@お腹いっぱい。:2005/03/23(水) 06:10:19
真にランダムとはなんですか?
680名無しさん@お腹いっぱい。:2005/03/23(水) 07:52:19
例えば、ps aux | cut -d ' ' -f1 とかした後、
root プロセスが何個とか、統計を取りたい場合、いい方法って無いですか?
681名無しさん@お腹いっぱい。:2005/03/23(水) 07:56:39
man uniq
682680:2005/03/23(水) 07:59:56
>>681
それだ!thanx
683http://www.geocities.com/tokyufubai/:2005/03/23(水) 11:31:17
ページングとは、主記憶の容量より大きいプログラムを実行する場合に
   用いられる処理方式です。

   ページング方式では、プログラムをページ(page) という固定長の単位に
   分解して、ハードディスク(補助記憶装置)に置いておきます。
684名無しさん@お腹いっぱい。:2005/03/23(水) 12:14:04
サブシェル内で変数フラグを立てて、while文が終了したあとに
そのフラグの値を参照したい場合はどうすればスマートでしょうか?
例えば、while文中で

flag=0
echo "hogefuga" | while read line; do flag=1; done

としたとき、サブシェルが終了したあとに、
$flagが1になっていることを確認したいのです。
685名無しさん@お腹いっぱい。:2005/03/23(水) 12:35:53
サブシェルの変数を参照したいというのは喉の奥に手を突っ込みたいというような
無理な話。
サブシェルの戻り値をみるか、サブシェルの最後で文字列を出力させて
それをみる。
686名無しさん@お腹いっぱい。:2005/03/23(水) 18:10:33
シェルじゃなくてsedの質問。連続する2つの行が同じ場合それらを削除する
にはどうしたらいいですか?例えば

1
2
2
3

という入力の場合

1
3

と出力させたい。
sed -E 's/^(.+)$\n\1//'
としたら全然だめでした。改行文字はどうやればいいんですかい?
687名無しさん@お腹いっぱい。:2005/03/23(水) 18:27:53
uniq -c して、^ *1 でなければ消す、だとどーよ?
688名無しさん@お腹いっぱい。:2005/03/23(水) 18:34:28
こういう質問って uniq とか他のコマンドを使わないで
sed だけでやる方法が知りたいのか
たまたま sed でやろうとしているだけで目的が達成できれば
どんな方法でもいいのかはっきり言うべきだと思う
689686:2005/03/23(水) 18:35:06
> ^ *1 でなければ消す
あほなんでこの部分が理解できませんが,man uniq で調べてみます。

後学のために聞きたいんですが,sed や grep で改行文字を扱うのは
無理?複数行の正規表現はperlかawkじゃないとできないんですか?
690686:2005/03/23(水) 18:36:17
>> 688
できればsedだけでやりたいです。
691名無しさん@お腹いっぱい。:2005/03/23(水) 18:43:26
「なぜ」sedだけでやりたいのかを言わないと。
692名無しさん@お腹いっぱい。:2005/03/23(水) 18:53:36
sed だけでやりたい理由。

今までこのような処理はperlかあるいはemacsに読み込んでやっていた。
今たまたまperlもemacsも入ってないマシンを使っている。awkは詳しく
ない。sedでやろうと思ったがうまくできないので質問しました。

ちなみにいちばん聞きたいことは,正規表現の中に改行文字を入れるには
どうしたらいいのか,あるいは不可能なのか,ということです。複数行
にまたがる正規表現はsedで可能なのかということです。だから上に書いた
入力を処理したいということではありません。上の例は問題を単純化して
分かりやすいように例を出しただけです。
693名無しさん@お腹いっぱい。:2005/03/23(水) 18:58:01
>>692
> 正規表現の中に改行文字
\n

> 複数行にまたがる正規表現はsedで可能
可能

これだけの質問に>>686は複雑過ぎ
694名無しさん@お腹いっぱい。:2005/03/23(水) 19:04:54
あ,普通に \n でいいんですか?さっき \n でやって
うまくいかなかったので質問してしまいました。俺の勘違いか。
スレ汚し失礼。
695名無しさん@お腹いっぱい。:2005/03/23(水) 19:07:26
>>694
s しか知らない奴は \n を使えない
696名無しさん@お腹いっぱい。:2005/03/23(水) 19:08:19
sedによっては\nは解釈できないかも。
その場合、逆に改行文字をそのまま入れればよい。
s/xxx/
/
みたいな感じ。
昔はこの方が普通だった。
697名無しさん@お腹いっぱい。:2005/03/23(水) 19:14:06
>>696
今は正規表現中の話。
698名無しさん@お腹いっぱい。:2005/03/23(水) 19:14:50
ま、改行を含めた正規表現を扱うには、あらかじめ、
N コマンドで次の行を読み込むとか、
パターンスペースの概念が要るわけだな。

それより、sed/awkとかは別スレにしないか?
シェルスクリプト自体の話から外れてくるから。
699名無しさん@お腹いっぱい。:2005/03/23(水) 19:15:09
uniq なら uniq -u (3行以上連続してても消していいんだよね?)
sed なら...難しいけど、現実逃避で考えてみる。
700名無しさん@お腹いっぱい。:2005/03/23(水) 19:16:12
> それより、sed/awkとかは別スレにしないか?
> シェルスクリプト自体の話から外れてくるから。
別にここでいいと思う
701名無しさん@お腹いっぱい。:2005/03/23(水) 19:23:59
>>675
cshじゃ、${1+"$@"}以前に、"$@"自体が使えねぇだろ。
csh厨うぜぇ。
702名無しさん@お腹いっぱい。:2005/03/23(水) 20:38:16
>>686
作ってみた

#n
H
g
s/\n//g
1!{
/\(.\)\1/!{
s/\(.\)./\1/p
g
s/\n//g
s/.\(.\)/\1/
h
}
/^\(.\)\1*$/!{
s/.*\(.\)$/\1/
h
}
}
${
/^.$/p
}
703名無しさん@お腹いっぱい。:2005/03/23(水) 23:06:43
bsh糞
704名無しさん@お腹いっぱい。:2005/03/23(水) 23:09:19
>>700
そして忘れ去られるsedスレ
705名無しさん@お腹いっぱい。:2005/03/23(水) 23:49:32
ほんまや。あるわ。sedスレ。
http://pc8.2ch.net/test/read.cgi/unix/1085730992/

706名無しさん@お腹いっぱい。:2005/03/24(木) 00:24:51
>>702
短くしてみた

#n
H
1!{
x
s/\n//g
/\(.\)\1/!{
s/\(.\)./\1/p
ba
}
/^\(.\)\1\{1,\}$/{
h
}
}
:a
${
/^.$/p
}
707706:2005/03/24(木) 00:35:46
ミスってた

#n
H
x
s/\n//g
/\(.\)\1/!{
s/\(.\)./\1/p
ba
}
/^\(.\)\1\{1,\}$/{
h
}
:a
${
g
/^.$/p
}
708名無しさん@お腹いっぱい。:2005/03/24(木) 06:56:44
sed については以降は sed スレへ↓
http://pc8.2ch.net/test/read.cgi/unix/1085730992/l50

・・だから sed は別スレに書けとあれほど、、
709名無しさん@お腹いっぱい。:2005/03/24(木) 23:21:09
ファイルからスペース区切りの行を1行ずつ読み込み、変数に格納し、
ファイルエンドまで繰り返すという処理をさせたいのですが、
どう記述すればいいですか?
Cシェルで教えてくれたら嬉しいのですが、それ以外でも構いません。
710名無しさん@お腹いっぱい。:2005/03/24(木) 23:27:00
>>709
格納してどうすんの?
711名無しさん@お腹いっぱい。:2005/03/24(木) 23:33:21
>>709です
言葉足りないかもしれないので、イメージで補足します。

【入力ファイル(スペース区切り)】
SUN 5
HP 10
IBM 9

【処理イメージ】
ループ
 ファイルより1行読み込んで変数Aと変数Bに格納
 ECHO 変数A 変数B
エンド


【画面出力】
SUN 5
HP 10
IBM 9
712名無しさん@お腹いっぱい。:2005/03/24(木) 23:35:10
ちょー基本だから、その辺のスクリプト解説本には大抵載っているはずだ。
713名無しさん@お腹いっぱい。:2005/03/24(木) 23:45:30
例題がくだらなさ過ぎ
714名無しさん@お腹いっぱい。:2005/03/24(木) 23:48:37
cat しろって言いたくなったが我慢した
715名無しさん@お腹いっぱい。:2005/03/24(木) 23:49:01
すいません(>_<)
Cシェルに関する良いサイトがあったら教えて下さい。
ぐぐってもなかなか見つからなかったもので。。
716名無しさん@お腹いっぱい。:2005/03/24(木) 23:50:43
>>715
ファイルの中身を表示するのが聞きたいわけではないんです。
すいません。
717名無しさん@お腹いっぱい。:2005/03/24(木) 23:51:16
間違えました。
>>715>>714
718名無しさん@お腹いっぱい。:2005/03/24(木) 23:55:55
719名無しさん@お腹いっぱい。:2005/03/25(金) 00:05:07
CシェルはC言語ライクを謳っているのに何故readがないんすか?
720名無しさん@お腹いっぱい。:2005/03/25(金) 00:06:28
>719
Cにもreadはない。
721名無しさん@お腹いっぱい。:2005/03/25(金) 00:33:22
>>709です
これでいいのかな?
foreach $* (INPUTFILE)
ECHO $1 $2
end
722名無しさん@お腹いっぱい。:2005/03/25(金) 00:37:12
Cにread関数はあるけどソケットからの一行読み込みでファイルリードではないけどね。
723名無しさん@お腹いっぱい。:2005/03/25(金) 00:40:48
>>722
Unix 系 OS では read はシステムコール.
ファイルからでもソケットからでもデバイスからでも
読める.
確に「一行読み込み」ではないけどね.
724名無しさん@お腹いっぱい。:2005/03/25(金) 15:27:14
>>709
#! /bin/bash
for i in $(seq 1 $(cat file | wc -l)); do
set $(cat file | head -n $i | tail -n 1)
echo $1 $2
done
725名無しさん@お腹いっぱい。:2005/03/25(金) 15:52:57
使用言語の仕様を満たしていませんが。
726名無しさん@お腹いっぱい。:2005/03/26(土) 21:28:02
標準入力から読み込まれたファイルを、行をランダムにシャッフルして、
標準出力に出すコマンドはありますか?

a
b
c

c
a
b
727726:2005/03/26(土) 21:32:53
とりあえず、
cat file | while read line; do echo $RANDOM $line; done | sort -n | cut -f 2- -d " "
というのを考えたのですけれども、これだと先頭のスペースが消えてしまう(行頭に
複数のスペースが入っていても無視されてしまう)ので、困ってしまいました。
728726:2005/03/26(土) 21:36:52
すいません。
cat file | while read line; do echo "$RANDOM $line"; done | sort -n | cut -f 2- -d " "
でした。
729名無しさん@お腹いっぱい。:2005/03/26(土) 21:55:55
OSを書かんとあるかどうかは分からんわな。
730名無しさん@お腹いっぱい。:2005/03/26(土) 21:56:22
うわageてしまった
731名無しさん@お腹いっぱい。:2005/03/26(土) 22:29:48
>>728
入力がテキストファイルなら、
cat file | while read line; do echo "$RANDOM^A$line"; done | sort -n | cut -f 2- -d "^A"
とかにしとけばいいじゃん。(^AはCTRL-A)

しかし、$RANDOMって一般的じゃないような気がするぞ。
732726:2005/03/26(土) 22:36:23
>>731
アドバイスありがとうございます。while read で読み込むと、変数lineがマッチするのは
各行の空白文字列(スペースやタブなど)以外の文字以降になるようです。

各行の先頭に空白文字列がある場合(そしてその空白を維持する必要がある場合)は、
どうしたらよいのでしょう?

a
b
c

c
a
b
733名無しさん@お腹いっぱい。:2005/03/26(土) 22:39:03
>>732
echo $line と echo "$line" は同じじゃないぞ。
734726:2005/03/26(土) 22:45:19
>>733
test.txtに
a
b
c
と記述したとき、
cat test.txt | while read line; do echo $line; done

cat test.txt | while read line; do echo "$line"; done
は同じ結果になりませんか?
735731:2005/03/26(土) 22:52:39
>>734
んじゃ、その行頭にIFS=''つけてみて。
736名無しさん@お腹いっぱい。:2005/03/26(土) 22:53:13
このスレは awk はいかんのかいのう
awk 'BEGIN{srand()}{print rand()" "$0}' file | sort -n | sed 's/[^ ]* \(.*\)/\1/'
737726:2005/03/26(土) 23:09:48
>>735
できましたっ!!
IFSを''にするという発想がありませんでした。
感謝しきりです。

>>736
ありがとうございます。
awkは自分にはまだ暗号なものでして。。。
本を読んで出直してきます。
738726:2005/03/26(土) 23:18:20
報告を兼ねて。結果的にこうなりました。
cat file | while IFS='' read line; do echo "$RANDOM $line"; done | sort -n | cut -f 2- -d " "

でも、$RANDOMが使えるのは、bashかtcshのようですが。。。
739名無しさん@お腹いっぱい。:2005/03/27(日) 00:12:08
>>726
bogosort ってのがあるよ。
http://www.lysator.liu.se/~qha/bogosort/
740名無しさん@お腹いっぱい。:2005/03/27(日) 00:40:37
$ cat File
# comment
A:1:0
B:2:10
C:1:5
# comment

というようなファイルがあったとき、各列を代入するのにうまいやり方ないでしょうか?

for i in `grep "^[^#]" File`;do
X=`echo $i | awk -F: '{print $1}'`
Y=`echo $i | awk -F: '{print $2}'`
Z=`echo $i | awk -F: '{print $3}'`
done

このやり方だと、列が増えたときに面倒になるので。
変数名にカウンタを使うという方法もあるけど、変数名は別にリストを作っておくなどして、
わかりやすいものにしたい。
741名無しさん@お腹いっぱい。:2005/03/27(日) 00:56:04
>>740
すなおに他の言語で書いたほうがよさげ。
742名無しさん@お腹いっぱい。:2005/03/27(日) 01:12:13
何に使うのか気になる
743名無しさん@お腹いっぱい。:2005/03/27(日) 01:54:43
>>740
こんなんどう?
自分も勉強中なんでもっとかっこいい方法があるなら知りたい。

VARS="X Y Z"
setup_vars() {
for i in $VARS
do
eval $i=$1
shift
done
}
sed '/^[ ]*#/d;s/:/ /g' File | while read line
do
setup_vars $line
done
744名無しさん@お腹いっぱい。:2005/03/27(日) 01:54:58
>>740
これできるのbashだけかな?

#!/bin/sh
declare -a XXX
for i in `grep '^[^#]' testfile`; do
  IFS=':' XXX=($i)
  echo ${XXX[0]}
  echo ${XXX[1]}
  echo ${XXX[2]}
done
745名無しさん@お腹いっぱい。:2005/03/27(日) 12:20:14
grep -v "^#" File | tr ":" " " | while read x y z; do echo $x; echo $y; echo $z; done
746名無しさん@お腹いっぱい。:2005/03/29(火) 17:48:06
directory ディレクトリィより下層にある
すべてのライブラリに対して symbol シンボルを
nm で検索する方法はありますか?
747名無しさん@お腹いっぱい。:2005/03/29(火) 17:55:54
きっとあります
748>>746:2005/03/29(火) 18:02:15
てーかエレガントな方法はありますか?
749726:2005/03/29(火) 18:03:07
rpmを使う。
750726:2005/03/29(火) 18:04:23
find directory -type f | while read file; do
echo $file
nm $file | grep symbol
done
とか言うこと?
751名無しさん@お腹いっぱい。:2005/03/29(火) 18:14:47
>>750
そうそう
それです
シェルスクリプトは魔法のようですね
752名無しさん@お腹いっぱい。:2005/03/29(火) 19:27:13
高度に発達したシェルスクリプトは魔法と区別がつかない
753名無しさん@お腹いっぱい。:2005/03/29(火) 20:52:06

awkはダメせいぜいsedまでで
754名無しさん@お腹いっぱい。:2005/03/29(火) 21:03:24
>>751
それはシェルスクリプトではありません。
755名無しさん@お腹いっぱい。:2005/03/29(火) 21:13:05

nm directory/**/*.a

とか?
756名無しさん@お腹いっぱい。:2005/03/29(火) 21:13:48
directory/**/*.a(.)
のほうがいいよ
757名無しさん@お腹いっぱい。:2005/03/30(水) 17:15:53
zsh 厨ウザイ。
758名無しさん@お腹いっぱい。:2005/03/30(水) 17:27:08
>>756
>>1
□みんなのお約束:
・特記なき場合はbourne shがデフォルトです。
 bash/csh/zsh/kshなどに依存する場合は明示しましょう。
759名無しさん@お腹いっぱい。:2005/03/30(水) 23:22:18
てゆーかみんななんでzsh使わないの?
760名無しさん@お腹いっぱい。:2005/03/30(水) 23:37:44
zsh厨=LD堀江
761名無しさん@お腹いっぱい。:2005/03/30(水) 23:41:16
性能的には

zsh>bash>tcsh>csh>sh

かな?kshとかashとか知らない
762名無しさん@お腹いっぱい。:2005/03/30(水) 23:51:29
>>759
読み方がわからないから
763名無しさん@お腹いっぱい。:2005/03/30(水) 23:55:27
ぜっとしぇる
764名無し募集中。。。:2005/03/30(水) 23:57:37
ぜっしゅ って言ってる人もいるけど
絶対にぜっとしぇるって言う

zsh ぜっとしぇる
bash ばっしゅ
tcsh てぃーしーしぇる
csh しーしぇる
ksh けーしぇる
ash あっしゅ
sh えすえいち
765名無しさん@お腹いっぱい。:2005/03/31(木) 00:04:48
がーん。ティッシュちゃうんや。
766名無しさん@お腹いっぱい。:2005/03/31(木) 00:08:04
>>759
私が使い始めた環境では、デフォルトが bash でした。
とくに考えること無く使ってきて、だいぶ慣れたし、特別困るようなこともない。

他のシェルを使おうと思うようなきっかけがなかったし、
変えなきゃいけないって状況にもなったことがないから、
bash を使ってます。

なんで zsh 使いはじめたのですか?
zsh 関係でテンプレにいれるようなページがあったら、
次スレたてるころに紹介してください。
767名無しさん@お腹いっぱい。:2005/03/31(木) 00:40:03
好きなの使えばいいと思うよ。だけど
ろくに使ったことないのに他のシェルをおとしめちゃ駄目だよ。
768名無しさん@お腹いっぱい。:2005/03/31(木) 02:10:42
>>766
> zsh 関係でテンプレにいれるようなページがあったら、
> 次スレたてるころに紹介してください。

別にいらんだろ。シェルの使い方のスレじゃねーんだから。
769名無しさん@お腹いっぱい。:2005/03/31(木) 02:29:00
> sh 関係でテンプレにいれるようなページがあったら、
> 次スレたてるころに紹介してください。

だと問題なさそう

それとも>>768はシェルといえばzsh?
花と言えば桜みたいな
春は曙みたいな
それはそれでいいけど

shの使い方はあっても良いと思う?

入門Kornシェルが紹介されてるならzshもOK?
けど csh & tcsh が無いのは何故?
770名無しさん@お腹いっぱい。:2005/03/31(木) 04:28:52
スレ違いを認識しろキティ。
おまえさんに適切なスレはこっち。

おまえら! shell は何を使っているんですか?
http://pc5.2ch.net/test/read.cgi/unix/1012330865/

【Shell】どのシェル使ってる?【Script】
http://pc5.2ch.net/test/read.cgi/linux/1067330754/


場の空気が読めない奴は現行スレに加えて過去スレも嫁。
771名無しさん@お腹いっぱい。:2005/03/31(木) 06:25:08
for i in ` seq 1 40 ` ; do echo $i ; done
だと桁が揃いません。
出力を、01 02 03 04 05 06 07 08 09 10 ... にする方法はありますか?
ループの中でcaseで処理を分ければできますが、もっと簡単な方法で。
772名無しさん@お腹いっぱい。:2005/03/31(木) 06:35:14
>>771
for i in `seq 1 40`; do j=`printf "%02d" $i`; echo $j; done
とかじゃだめ?
773名無しさん@お腹いっぱい。:2005/03/31(木) 07:04:00
>>771
seq を使っていいのなら、

for i in `seq -f %02g 1 40`; do echo $i; done

で一発だよ。
ただ、seq はLinux以外では標準じゃないので、
いつも使えるとは限らないのが難点。
774名無しさん@お腹いっぱい。:2005/03/31(木) 07:26:23
>>771
zsh を使っていいのなら、

echo {01..40}

で一発だよ。
ただ、zsh は標準じゃないので、
いつも使えるとは限らないのが難点。
775名無しさん@お腹いっぱい。:2005/03/31(木) 07:41:39
zsh始めたのは長老が使っていたからかな
776名無しさん@お腹いっぱい。:2005/03/31(木) 10:11:16
seq -w
とすれば勝手に桁が揃うよ。
777名無しさん@お腹いっぱい。:2005/03/31(木) 10:14:10
>>772-774
ありがとうございました。
j=`printf "%02d" $i`
こんな使い方ができるなんてWinと違って奥が深いですね。

>>773-774
こちらの環境では動作しました。
echo {01..40} は
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
と出力されました。
778名無しさん@お腹いっぱい。:2005/03/31(木) 10:16:15
( ´,_ゝ`)プッ
779名無しさん@お腹いっぱい。:2005/03/31(木) 10:39:09
>こんな使い方ができるなんてWinと違って奥が深いですね。
バッククォートは知ってたようだが…今さらどこが深かったんだろう。
感心する前に基本からやれって。
780名無しさん@お腹いっぱい。:2005/03/31(木) 13:13:37
>>779
バッククォートはどっかのサイトで見つけてコピペで使ってただけです。
781名無しさん@お腹いっぱい。:2005/03/31(木) 13:20:45
>>777
WindowsのForとSetのヘルプも見てみな(自分も覚えてないけど)

|for /F "usebackq delims==" %i IN (`set`) DO @echo %i
|この例は、現在の環境の環境変数名を列挙します。

まあ、このVMS式のオプション指定方法とUNIXから持ってきた構文の
混ざり具合が気持ち悪いのは確かだが。
782名無しさん@お腹いっぱい。:2005/03/31(木) 13:32:59
ほんとモイキーな書式だ
783名無しさん@お腹いっぱい。:2005/03/31(木) 14:05:17
>>770
s/pc5/pc8/

次スレ立てるときはテンプレ修正忘れないようにしないと。
こういうときって過去スレのURLも一括して変えるものなのかな? そのままですか?

784ウサチャソ:2005/03/31(木) 20:21:38
>>765
オナニーばっかしてる君にはその読み方がぴったりだね!!
と無意味に煽ってみる。

いや、悪意はないんだがなんとなく煽ってみたかったんだ。
2ch初煽り記念あげ
785名無しさん@お腹いっぱい。:2005/03/31(木) 20:29:21

ちくしゅ
786名無しさん@お腹いっぱい。:2005/03/31(木) 20:44:23
シェルスクリプトを使って、文字列を標準出力に出しているとき、
スクリプトの途中でEOFをおくることはできますか?具体的には

1. echo hoge
2. sleep 5
3. echo fuga > foo

というスクリプトにて、echo hogeを実行した直後に標準出力は
閉じて(←この表現が適切かどうか不安ですが、プログラムが
自動的にバックグラウンドに回る、という感じのことを言いたい
のです)、sleep 5から先は標準出力に出すような作業は一切ない
ので、自動的に残りの処理がバックグラウンドに回るように
したいのです。

1. echo hoge
2. sleep 5 && echo fuga > foo &

とすれば、一応は解決しますが、&& でつなぐ処理は、途中で
終了コード0以外になるプログラムがあるとそこから先が実行
されません。なので、

1. echo hoge
2. (標準出力を閉じる何かの動作)
3. sleep 5
4. echo fuga > foo

という形で書ける書式があれば教えてください。
787名無しさん@お腹いっぱい。:2005/03/31(木) 20:50:52
春だな
788名無しさん@お腹いっぱい。:2005/03/31(木) 20:57:55
> 標準出力を閉じる何かの動作
exec >&-
789名無しさん@お腹いっぱい。:2005/03/31(木) 21:09:08
>>786
標準出力のことは、質問に無関係なようにに読めます。

sleep 5
echo fuga > foo
と書いたらこれらが自動的にバックグラウンドに回って欲しい
ということじゃないんですか?()を使ってGroupingでOK、かな。
here documentで並べたコマンド列をshにパイプで渡しても
いいんだろうけど。

いずれにせよ、これと標準出力との関係がよくわからなかったヨ。
790名無しさん@お腹いっぱい。:2005/03/31(木) 21:18:30
>>788で満たされるんじゃないかな。
バックグラウンドに回っても標準出力に出力あったら意味なさそう
791名無しさん@お腹いっぱい。:2005/03/31(木) 21:18:55
>>784
偽者だな。本物のウサチャソはいつも煽ってるぞ。
792790:2005/03/31(木) 21:22:40
と思ったけどやっぱりわかんないや。
閉じようが閉じまいが出力はないって言ったはるし。
793名無しさん@お腹いっぱい。:2005/03/31(木) 21:24:01
標準出力が端末に出ちゃうってのを気にしてるんじゃないのか?
794名無しさん@お腹いっぱい。:2005/03/31(木) 21:29:22
シェルスクリプト中からstat
を取るのになにかよい方法ってありますか?
795名無しさん@お腹いっぱい。:2005/03/31(木) 21:29:27
単に「sleep 5」以降は(出力を確認する必要はないから?)
プロンプトが返ってきてほしい
ってだけなんじゃ…
796名無しさん@お腹いっぱい。:2005/03/31(木) 21:34:26
>>786
ろくに読まないで答えるとnohupでいいんちゃうか
797名無しさん@お腹いっぱい。:2005/03/31(木) 21:38:27
つーか全部そのままで
&で実行させたらいいんじゃないの?
798名無しさん@お腹いっぱい。:2005/03/31(木) 22:06:17
>>792
echo foo
(
echo bar
echo baz
) > output-file &

って, ことか?
799名無しさん@お腹いっぱい。:2005/03/31(木) 22:13:31
目的が不明だ
800名無しさん@お腹いっぱい。:2005/03/31(木) 22:43:01
>>794
何が知りたいの?
とりあえずFreeBSDやNetBSDにはstat(1)があるけど、
汎用的にはperlなんかのonelinerにファイルを渡すのがいいんじゃないかな。

801名無しさん@お腹いっぱい。:2005/03/31(木) 23:43:01
ここにおる奴には常識なんだろうが、
bshの場合、
while〜do〜done 文と while read LINE;do〜;done < FILE 文
とでは、whileループの外の変数の見え方が変わるんだね。
いや〜今まで全く気がつかなかった。
客に嘘教えてもうた(藁
802名無しさん@お腹いっぱい。:2005/03/31(木) 23:44:04
>>801
どうちがうの?
803名無しさん@お腹いっぱい。:2005/03/31(木) 23:56:43

$ cat test1
#!/bin/sh
CNT=0
while read LINE
do
CNT=`expr $CNT + 1`
echo "$n: $LINE"
done < FILE
echo $CNT
$ ./test1
0

$ cat test2
#!/bin/ksh (bash、zshでも)
CNT=0
while read LINE
do
CNT=`expr $CNT + 1`
echo "$CNT: $LINE"
done < FILE
echo $CNT
$ ./test2
5 ・・・FILEの行数
804名無しさん@お腹いっぱい。:2005/03/31(木) 23:59:12
余分な行が入ったので、訂正
$ cat test1
#!/bin/sh
CNT=0
while read LINE
do
  CNT=`expr $CNT + 1`
done < FILE
echo $CNT
$ ./test1
0

$ cat test2
#!/bin/ksh
CNT=0
while read LINE
do
  CNT=`expr $CNT + 1`
done < FILE
echo $CNT
$ ./test2
5 ・・・FILEの行数(bash、zshでも同じ結果)
805名無しさん@お腹いっぱい。:皇紀2665/04/01(金) 00:30:44
えー?サブシェルになるの?そうじゃなけりゃローカルな変数なんて変ジャン
806名無しさん@お腹いっぱい。:皇紀2665/04/01(金) 00:32:57
なんだよ、その日付(w
807名無しさん@お腹いっぱい。:皇紀2665/04/01(金) 00:39:46
どうせ今日だけじゃないか?

>>804
FreeBSDのashだとちゃんと行数カウントしてくれるけど、そいつはどこのsh?
808名無しさん@お腹いっぱい。:皇紀2665/04/01(金) 00:51:42
solaris2.6と9で確認。
いろいろ調べた結果、bshの大昔からのバグだったものが、
長い間使われてきているので、現在では仕様として扱われているらしい。
809名無しさん@お腹いっぱい。:皇紀2665/04/01(金) 06:45:48
かなりのシェルスクリプト初心者なんですが、htmlファイルから
URLを抜き出すスクリプトってどう書けばいいのでしょうか?
http://foo/bar.html
http://foo/
http://foo/bar.jpg
などを全部抜き出したいんです。
できればスクリプトの解説つきでお願いします。
810名無しさん@お腹いっぱい。:皇紀2665/04/01(金) 06:47:07
grep 'http://'
811名無しさん@お腹いっぱい。:皇紀2665/04/01(金) 06:56:06
ただ url を抜き出すだけなら http:// にマッチさせれば良さそうだけど

リンクを抜き出したいとかだと
相対url も絶対url で出力したいだろうし
wget とか w3m で何かあるのかな?
812名無しさん@お腹いっぱい。:皇紀2665/04/01(金) 07:35:22
lynx -dump hoge.html
で、下の方に References でリンクURL一覧が出るので、
これを利用すればいい。
813名無しさん@お腹いっぱい。:皇紀2665/04/01(金) 11:36:56
lynx -dumpは相対リンクがイヤンなことになるので
やっぱりそれなりのスクリプト言語のライブラリを使うのが早くて確実。
814名無しさん@お腹いっぱい。:UNIX時間(+0900)35/04/01(金) 16:56:32
>>813
lynx -dump で、相対パスはちゃんと絶対パスに直してくれるけど、
それでは不満なのか?
あと、lynx -image_links -dump にすると、
<img src="..."> とかのタグ内の画像リンクとかもすべて
リストしてくれるから便利だけど。
815名無しさん@お腹いっぱい。:UNIX時間(+0900)35/04/01(金) 17:11:05
>>814

>>809
> htmlファイルから
って書いてるから、たぶん、HD に保存してあるファイルが対象なんじゃないかな?
それだと、相対リンクだと、 http://foo/ が file://localhost/ になっちゃうから、
書き換える必要がでてくる。
>>813 はそのことを言ってるのだと思う。
816名無しさん@お腹いっぱい。:UNIX時間(+0900)35/04/01(金) 18:21:18
特殊な例:
$ cat test.html
<a href="../index.html">foo</a>
<a href="/index.html">bar</a>
$ lynx -dump -force_html /dev/stdin < test.html | grep file
1. file://localhost/index.html
2. file://localhost/index.html
817名無しさん@お腹いっぱい。:UNIX時間(+0900)35/04/02(土) 10:42:15
すんまそん。別スクリプトを読み込むのてどうやるんですか?
よくわからないので、必ず ; をつけるようにしたやつを

eval `cat /${HOME}/.hoge`

って読みこませとるのですが、なんかエレガントなかんじがしません。
818名無しさん@お腹いっぱい。:UNIX時間(+0900)35/04/02(土) 10:57:57
”. ${HOME}/.hoge”・・・サブシェルとして実行
”exec ${HOME}/.hoge”・・・現シェルの一部として実行
819名無しさん@お腹いっぱい。:UNIX時間(+0900)35/04/02(土) 12:06:07
>>818
違う
"${HOME}/.hoge"・・・サブシェルで実行
”. ${HOME}/.hoge”・・・現シェルとして実行
”exec ${HOME}/.hoge”・・・現シェルの引継ぎとして実行
820名無しさん@お腹いっぱい。:UNIX時間(+0900)35/04/02(土) 12:06:19
エレガントとかほざく前にman読め
821名無しさん@お腹いっぱい。:UNIX時間(+0900)35/04/02(土) 12:07:42
>>818
おいおいおい。何大嘘ついてんのよ。


822名無しさん@お腹いっぱい。:UNIX時間(+0900)35年,2005/04/02(土) 16:03:24
lynx -image_links -dump
809ではないが便利だ。サンクス
823名無しさん@お腹いっぱい。:UNIX時間(+0900)35年,2005/04/02(土) 16:37:20
sourceは?
824名無しさん@お腹いっぱい。:UNIX時間(+0900)35年,2005/04/03(日) 11:37:41
クローラの動きを把握するためにgoogleでの検索結果を保存したいのですが
どのように書けばいいのかご教授願います。

例えばsite:www.2ch.netで検索した結果を取得するには、どのように書けばいいですか?
825名無しさん@お腹いっぱい。:UNIX時間(+0900)35年,2005/04/03(日) 14:10:42
lynx -dump 'http://www.google.co.jp/search?q=www.2ch.net'
こうですか?わかりません
826名無しさん@お腹いっぱい。:UNIX時間(+0900)35年,2005/04/03(日) 23:45:07
>>825
ありがとうございます。

lynx -dump 'http://www.google.co.jp/search?q=www.2ch.net' > test.html
とリダイレクトしてみたのですが、l
ynxで整形されて表示されたテキストの状態で保存されるんですね。


整形されたものではなく、取得したHTMLソースを保存するにはどうすればいいですか?
827名無しさん@お腹いっぱい。:UNIX時間(+0900)35年,2005/04/03(日) 23:46:20
>>826 訂正
× ynxで
○ lynxで
828名無しさん@お腹いっぱい。:UNIX時間(+0900)35年,2005/04/03(日) 23:53:13
wget とか?
829名無しさん@お腹いっぱい。:2005/04/04(月) 01:54:20
>>826
s/dump/source/
830名無しさん@お腹いっぱい。:2005/04/05(火) 00:50:08
>>829
ありがとうございます。
831名無しさん@お腹いっぱい。:2005/04/05(火) 23:09:43
シェルの変数の命名慣習について聞きたいんですが、
大文字にするのは環境変数で、
スクリプト内や関数内での変数は小文字、
という使い方が普通ですか?
832名無しさん@お腹いっぱい。:2005/04/06(水) 00:19:55
そんな感じ。
833名無しさん@お腹いっぱい。:2005/04/06(水) 00:28:40
どうもです。
rc の設定に引きずられて、
実はつい最近まで何も考えずに
スクリプトの変数にまで大文字使ってました。
834名無しさん@お腹いっぱい。:2005/04/06(水) 00:39:29
シェルを実行しようとしたところ、下記のエラーが出て実行できません。
「The fork function failed. Too many processes already exist.」

最初は同じシェルを実行できたのですが。。
何度か応答が帰ってこないので、×でセッションを落としましたがそれが原因でしょうか?

どなたか解決作のわかる方教えて下さい。
835名無しさん@お腹いっぱい。:2005/04/06(水) 00:44:01 BE:182429069-
>>834
ps で調べて kill
836名無しさん@お腹いっぱい。:2005/04/06(水) 10:20:55
テキストデータの整形で困っています。

0404 AAA 111
0404 BBB 222
0404 CCC 333
0405 DDD 111
0405 EEE 777
0405 FFF 222

↑これらを

0404 AAA 111 BBB 222 CCC 333
0405 DDD 111 EEE 777 FFF 222

↑このように整形したいのですが、うまくいきません。
もしよかったら、どなたかご教授お願いします。
837名無しさん@お腹いっぱい。:2005/04/06(水) 10:22:11
毎年恒例の宿題か
838名無しさん@お腹いっぱい。:2005/04/06(水) 10:26:29
>>836
それだけじゃルールが分からないよ
839名無しさん@お腹いっぱい。:2005/04/06(水) 10:29:59
>>836
自分ではどこまでできたの?
840836:2005/04/06(水) 10:38:28
一番左の日付をキーとして、AAAはいくつ、BBBはいくつ、という感じで1レコードにしたいのです。
恥ずかしながら、やり方が見当もつかない状態でして。。。すみません。
841名無しさん@お腹いっぱい。:2005/04/06(水) 11:08:55
ルールがわからないというのは、同じキーは必ず連続するのかそうでないのか
とか、同じキーは三つなのかどうかとか、典型的な状況説明だけでありうるす
べての状況を説明していないということ。

ともかく、シェルでなんとかするというより、awk なり perl なり使っとけと。
842名無しさん@お腹いっぱい。:2005/04/06(水) 11:26:37
>>836
#!/usr/bin/awk -f
{
if (r[$1]=="")
r[$1] = $0;
else
r[$1] = r[$1]" "$2" "$3;
}
END{
for ( i in r )
print r[i];
}

# あとで sort しないとだめかも
843名無しさん@お腹いっぱい。:2005/04/06(水) 11:47:05
>>840
来年はちゃんと授業に参加しような。
844836:2005/04/06(水) 12:40:02
>>842、皆さん
ありがとうございました!何とかなりそうです。
845名無しさん@お腹いっぱい。:2005/04/07(木) 17:04:37
ディレクトリ内のファイル(ログ)が現在から一ヶ月以上
アクセスしていないファイルを削除するようなシェルを
作成しようと考えてます。
簡単にできますか?
846名無しさん@お腹いっぱい。:2005/04/07(木) 17:07:13
>>845
シェルごと自作するのは難しいが
シェルスクリプトならそれほど難しくない。
847名無しさん@お腹いっぱい。:2005/04/07(木) 17:10:38
logrotate 使えば?
848名無しさん@お腹いっぱい。:2005/04/07(木) 17:13:36
find 使うのが定石?
私は zsh だけど
849名無しさん@お腹いっぱい。:2005/04/07(木) 17:22:42
>>847
logrotateを考えたのですがアプリが勝手に毎日、日付をつけてログを
残してしまいます。
>>846
難しくないシェルスクリプトでお願いします。
>>848
findでやってみます。
850名無しさん@お腹いっぱい。:2005/04/07(木) 17:31:18
find log_dir/ -atime +30 -a -type f -exec rm {} \;
851名無しさん@お腹いっぱい。:2005/04/07(木) 17:32:22
find $DIR -mtime +30 | xargs rm で出来ました。
852名無しさん@お腹いっぱい。:2005/04/07(木) 19:43:13
>>849
> 難しくないシェルスクリプトでお願いします。
シェルとシェルスクリプトの区別はついているか
853名無しさん@お腹いっぱい。:2005/04/07(木) 21:41:59
DDD 7
AAA 1
AA 10
DD 35
DDDD 34
AAA 11
AAAA 7
DDD 4

という内容のファイルがあって

AAA 1
AAAA 7
AA 10
AAA 11
DDD 4
DDD 7
DDDD 34
DD 35

とソートしたいです。どうすればよいでしょうか?
要は$2でlsのようなソートをしたいです
854名無しさん@お腹いっぱい。:2005/04/07(木) 21:43:46
手で並び替える
855名無しさん@お腹いっぱい。:2005/04/07(木) 22:00:42
>>854
いやいや、確かに現状はそうなんだけどね。
そこをなんとかw
856名無しさん@お腹いっぱい。:2005/04/07(木) 22:01:27
>>853
一文字目だけで sort する -> 文字を選ぶ
選んだ文字で grep する -> 数字で sort する

for CHAR in `cut -b 1 file | sort -u` ; do grep "$CHAR" file | sort -n -k 2 ; done
857名無しさん@お腹いっぱい。:2005/04/07(木) 22:04:52
おれなら perl でやっちゃうな。
sort でやるとしたら何段階か処理しないといけなさそう。
858名無しさん@お腹いっぱい。:2005/04/07(木) 22:09:20
>>856
そう、これです!ありがとうございます。
$1は問題ないのですが$2がどうしても
1
10
11
7
とソートされて困ってました ← 手作業の手間が

今後、私の中で >>856 ”神”となりましたw
859名無しさん@お腹いっぱい。:2005/04/07(木) 22:13:45
>>857
perlとか Cで作るならできるんですよ。
ただ、客先とか自分で作業する環境が限られているところで
どんなWSでも実行できるsort でやりたかったんです
860名無しさん@お腹いっぱい。:2005/04/07(木) 22:14:58
客先…
861名無しさん@お腹いっぱい。:2005/04/07(木) 22:17:20
これ、第一フィールドの整列の方が実はキモだろ。
数字順はsortのオプションで何とかなるとすぐわかる。
862名無しさん@お腹いっぱい。:2005/04/07(木) 22:32:35
担当される客が可哀想になる
863名無しさん@お腹いっぱい。:2005/04/07(木) 22:33:14
aaa 1
aab 11
aba 3
abb 2
baa 3
bab 1
こんなのだとどうする?
864名無しさん@お腹いっぱい。:2005/04/07(木) 22:53:37
>>853
cat file | sort -k 1.1,1.1 -k 2,2n
865名無しさん@お腹いっぱい。:2005/04/08(金) 19:11:26
>>864
おいらも便乗させてください

C<4>
BB4BBB<5>
AAA<14>
AAA<1>
DDD
BB4BBB<52>
EE<3>
C<41>
EE<30>

  ↓

AAA<1>
AAA<14>
BB4BBB<5>
BB4BBB<52>
C<4>
C<41>
DDD
EE<3>
EE<30>

できればsortだけでなんとか出来ればベストなんですけどね。
866名無しさん@お腹いっぱい。:2005/04/08(金) 19:40:21
こういうこと?
sort -t '<' -k 1,1 -k 2,2n
867865:2005/04/08(金) 20:04:38
>>866
サンクスですこれでばっちりです。
ちなみに < > が無くても簡単にできるものでしょうか?
868名無しさん@お腹いっぱい。:2005/04/08(金) 21:23:13
仕切りさえあればいい、んじゃないか?
869名無しさん@お腹いっぱい。:2005/04/10(日) 15:53:24
log 05.4.8
log 05.4.9
log 05.4.10
という感じの間に空白のあるファイルがあります。
これを古いのから順にcatでつなげたいのですが、どうすればいいでしょうか?
870名無しさん@お腹いっぱい。:2005/04/10(日) 18:15:45
>>869
cat `ls | sort -n -k 2`
みたいなかんじでがんばって
871名無しさん@お腹いっぱい。:2005/04/10(日) 19:50:57
cat `ls -tr`でやってたんですが、空白があってだめなんですよ。
872名無しさん@お腹いっぱい。:2005/04/10(日) 19:54:11
がんばって
873名無しさん@お腹いっぱい。:2005/04/10(日) 20:09:06
#!/bin/sh
IFS='
'
for f in `ls -tr`; do cat $f; done
874名無しさん@お腹いっぱい。:2005/04/10(日) 20:43:56
>>873
おー、IFSなんていう環境変数があったんですね。これで何とかなりそうです。
875名無しさん@お腹いっぱい。:2005/04/10(日) 20:54:54
変数ではあるが環境変数ではない。

空白が1個だけと確定してるなら
ls -tr | xargs -n2 cat
そうでないなら
ls -tr | sed 's/^/cat /' | sh
876名無しさん@お腹いっぱい。:2005/04/10(日) 21:05:59
こうじゃないとダメかorz
ls -tr | sed 's/.*/cat "&"/' | sh
877名無しさん@お腹いっぱい。:2005/04/11(月) 02:02:50
ls -tr|tr '\n' '\0'|xargs -0 cat
878名無しさん@お腹いっぱい。:2005/04/11(月) 18:52:07
シェルスプリプト相談室 スレより誘導されて着ました。

ファイルを読み込んで、各行の先頭文字を判定し、コメント文でなければ表示
をするというものを作っています。現在、以下のようにして判定しているので
すが、これでは、「空行があるとファイルはそこで終わり」だと判断されてし
まい、最後までいってくれません。全行を見るためには、どう書けば良いので
しょうか?bsh使いです。

while read KEY
do
#判定
done < test.dat

お願いします。
879名無しさん@お腹いっぱい。:2005/04/11(月) 18:55:29
>>878
スクリプトにしなくても grep でいいじゃん。
880878:2005/04/11(月) 19:08:06
>>879
それを言われると辛いのですが…。
シェルスクリプトを勉強を始めたばかりで、力をつけるためにやっているものです。
1行1行判定させて、その都度出力するというものは出来ないのでしょうか?
881名無しさん@お腹いっぱい。:2005/04/11(月) 19:09:22
誘導元の美味しんぼワロタ
882名無しさん@お腹いっぱい。:2005/04/11(月) 19:21:43
シェルスクリプト相談室
http://pc8.2ch.net/test/read.cgi/tech/1112553783/
883名無しさん@お腹いっぱい。:2005/04/11(月) 20:40:10
>>878
判定の書き方が間違っているんじゃないの?
変数をクォートしていないため、そこでtest文がエラー起こしていたり。
884632:2005/04/11(月) 21:19:55
>>639
亀レスで失礼します。
hogeは/bin/sh とかですか?
885名無しさん@お腹いっぱい。:2005/04/11(月) 21:20:34
>>880
ネタが悪いな。
perl 等の他のスクリプト言語の練習なら >>878 でいいんだが。
886名無しさん@お腹いっぱい。:2005/04/12(火) 00:23:48
>>880
> 1行1行判定させて、
こんなこと実際のシェルスクリプトでもしないと思うなあ。
練習にしても練習内容の方向が間違ってる希ガス。

887名無しさん@お腹いっぱい。:2005/04/12(火) 01:51:32
awkとか使っちゃダメなんだろうなぁ
888名無しさん@お腹いっぱい。:2005/04/12(火) 07:01:33
IFSと言ってみる
889名無しさん@お腹いっぱい。:2005/04/12(火) 07:46:37
>>878
やってみたけど、空行あっても終わんないよ。
readは空行でもtrue返すので当たり前な気がする。
(GNU bash, version 3.00.14(1)-releaseだけど、こんな基本的な
挙動はshによって変わったりするようなもんじゃないと思う)
890878:2005/04/12(火) 08:18:34
>>883, >>885, >>886, >>889氏、レスありがとうございます。
中身を替えずに再実行したところ、>>878氏の言う通り、空行があっても終わりませんでした。
でも、確かにあのときは空行で終わってしまったのですが…。
お騒がせしました。
891890=878:2005/04/12(火) 08:21:33
>>890
×…再実行したところ、>>878氏の言う通り
○…再実行したところ、>>889氏の言う通り

orz
892名無しさん@お腹いっぱい。:2005/04/12(火) 11:10:42
Bourneシェルです。
特定文字列をファイル名に含むファイルの中身を、連続表示するものを作りたいです。
拡張子がtxtのもののみの中身を見たいのですが、どう記述すれば良いのでしょうか?
ファイル名昇順の順番で読むことにしています。
ls *.txt | sort
とすれば、ファイル名昇順で表示はされるのですが、この順にファイルを読むには…。
おながいします。
893名無しさん@お腹いっぱい。:2005/04/12(火) 11:36:42
>>892
for i in `ls *.txt | sort`
とかそういう話?
単に全部表示するだけなら cat `ls *.txt | sort`
894名無しさん@お腹いっぱい。:2005/04/12(火) 12:07:23
普通globの展開は辞書順に並べられるので何も考えずに cat *.txt でも
いいように思うのだが。

あと、ファイルのリストをとるためにlsを安易に使う人がいるけど、
あまり望ましくはない。使うなら、せめて
名前に空白等が含まれる可能性やglobにディレクトリが引っ掛かる可能性を
考慮しような。
895名無しさん@お腹いっぱい。:2005/04/12(火) 20:45:24
今時の ls は空白や改行が入ったファイル名でも問題無いよ。
896名無しさん@お腹いっぱい。:2005/04/12(火) 20:46:55
>>895
>>893でも問題ない? 本当に?
897名無しさん@お腹いっぱい。:2005/04/12(火) 21:13:44
>>896
スマン、勘違い。忘れてくれ。
898名無しさん@お腹いっぱい。:2005/04/12(火) 22:04:12
ファイル名に / を入れたいです。
899名無しさん@お腹いっぱい。:2005/04/12(火) 22:15:55
それがshell script とどういう関係が?




ちなみにKDEでfoo/barという名前のDirectoryをDesktop
に作成してlsしたらfoo%2fbarって名前になってた。
900名無しさん@お腹いっぱい。:2005/04/13(水) 09:14:50
ファイル名に / があるとシェルスクリプトで動かないです。
901名無しさん@お腹いっぱい。:2005/04/13(水) 09:52:27
シェルスクリプト以前にそんな文字入れるな。
902名無しさん@お腹いっぱい。:2005/04/13(水) 13:45:35
エスケープすりゃええだけじゃないのか
903名無しさん@お腹いっぱい。:2005/04/13(水) 16:06:39
シェルで、ファイルから1行づつ読み込んで、
それを区切りごとに分けてそれぞれを配列に代入する、
ということはできるのでしょうか?
Perlを使えればいいのですがそれができない状況でして困っています。
どなたか知恵をお貸しください。
904名無しさん@お腹いっぱい。:2005/04/13(水) 16:10:51
>>903
詳しく
905名無しさん@お腹いっぱい。:2005/04/13(水) 16:13:51
Bシェルには配列がない
906名無しさん@お腹いっぱい。:2005/04/13(水) 16:21:16
>>904
やりたいことというのは、
今手元に'ls -l'の出力を記録したファイルがあるのですが、
このファイルから1行づつ内容を読み出して、
タブで区切られたフィールドごとにその内容をそれぞれ別の変数に入れて、
(必ずしも配列である必要はありません>>905さん)
その変数の内容に基づいて処理を行った後、
次の行を読み込んで同様に・・・
ということです。

perlだったら<>で読み込んでsplitすれば一発なのですが、
同様のことをシェルではどうやればいいのかわからなくて
質問に来ました。
907名無しさん@お腹いっぱい。:2005/04/13(水) 16:24:50
>>906
read
908 ◆O46J5xixH. :2005/04/13(水) 17:06:12
>>902

ネタにマジレス+スレ違いだが、dd か何かで無理矢理ディレクトリ
エントリ中のファイル名に "/" を突っ込んだら、やっぱりうまく
動かなかったとかって、fj.unixか何かの話しであったよ。
909名無しさん@お腹いっぱい。:2005/04/13(水) 19:09:21
あたりめえじゃん。
カーネル様が/のとこでぶったぎってから、ディレクトリ検索するんだから
910名無しさん@お腹いっぱい。:2005/04/13(水) 19:56:16
DOSまたはWindowsを使う。
911名無しさん@お腹いっぱい。:2005/04/13(水) 20:51:10
質問できそうなところがここしかないので質問させてください。
syslogを日時を指定して吐き出すようなシェルスクリプトはどのような記述ですか。
また、変数でエラーlogとそうでないlogを分けて吐き出したいです。
よろしくおねがいします。
912名無しさん@お腹いっぱい。:2005/04/13(水) 21:03:33
>>910
DOSやWindowsでもファイル名に/は使えない。
DOSやWindowsでも、カーネルレベルでは
ディレクトリの区切り文字に/を使っている。
\を使うのは、おもにcommand.comが/をオプション記号として
使うために、\をディレクトリ区切り文字の代用として
使っているに過ぎず、実はディレクトリは/で区切られているのだ。
その証拠に、Shift-JISの漢字の2バイト目は、
決して/にならないようにコードがちゃんと避けられている。
一方、\の方は避けられておらず、Shift-JISの2バイト目が
\になる漢字があって、シェルスクリプトやC言語で時々問題になる。
913名無しさん@お腹いっぱい。:2005/04/13(水) 21:05:08
なぜシェルスクリプトでそれをできると思ったのかが疑問だが、
自分ならめんどうなことを考えずに syslog-ng に乗り換える。
914名無しさん@お腹いっぱい。:2005/04/13(水) 21:25:24
表\示
915名無しさん@お腹いっぱい。:2005/04/13(水) 21:58:23
でもさ「05/4/13 21:58:24」とかいうファイル名を使いたいときってない?
916名無しさん@お腹いっぱい。:2005/04/13(水) 22:11:35
「050413215824」でおk
917名無しさん@お腹いっぱい。:2005/04/13(水) 22:17:03
05ディレクトリの下の4ディレクトリの下に、
'13 21:58:24'というファイルを作成すれば無問題。
ちゃんと「05/4/13 21:58:24」というパス名でアクセスできる。
スペースが含まれるので、ちゃんとクォートすること。
918名無しさん@お腹いっぱい。:2005/04/13(水) 22:39:53
>>906
perl とかでやった方が早いと思う。

>>915
ない。
919名無しさん@お腹いっぱい。:2005/04/13(水) 22:42:20
なぜ、その程度でperlが出てくる・・・。
920名無しさん@お腹いっぱい。:2005/04/13(水) 22:42:23
perlが使えない環境って書いてあるやん。

なのでawk
921名無しさん@お腹いっぱい。:2005/04/13(水) 22:48:59
>>907 がすでに答え書いてるじゃん。

read perm block user group size date filename

みたいに書けば、$perm とかで変数参照できる。
これをwhileループで回せば良い。

タブを区切り文字にするなら、
IFS=' ' ←この中はタブ
にすればいい。
922名無しさん@お腹いっぱい。:2005/04/13(水) 23:06:17
ここってさシェルでひとまとめにしてるのが良くない
shでなら出来るけどcshなら出来ないんだよねとか。
shはcshより高機能?だと思うけど使いずらいからCライクなcshとか
俺はlinuxだからbashがいいとかなる。
でもsolariaとかだとシステム管理者を丸め込まないとtcsh止まり。

923名無しさん@お腹いっぱい。:2005/04/13(水) 23:30:11
>>922
独り言なら他所にいけ。
924名無しさん@お腹いっぱい。:2005/04/13(水) 23:58:28
>>922
solaria なんて無名OSを使ってるのが悪い。solaris使え。
925名無しさん@お腹いっぱい。
>>922
スクリプト書きに csh を使うのがそもそもの間違いなので
別に問題ない。
それに Solaris は、いまでは最初から bash も zsh も
tcsh もついてくるので、管理者をまるめこむまでもなく
最初から使えるだろ。