シェルスクリプト総合 その13
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
2008/10/16(木) 00:48:38スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
前スレ
シェルスクリプト総合 その12
http://pc11.2ch.net/test/read.cgi/unix/1218277263/
0007名無しさん@お腹いっぱい。
2008/10/16(木) 01:03:42(2005/07) UNIX シェルスクリプト辞典 川井 義治 (著)
http://amazon.co.jp/o/ASIN/4798109231/
(2005/08) シェルスクリプト ポケットリファレンス bash編 宮原 徹 (著), 川原 龍人 (著)
http://www.amazon.co.jp/o/ASIN/4774124818/
(2005/12) 図解でわかるLinuxシェルスクリプト・正規表現 小泉 修 (著)
http://www.amazon.co.jp/o/ASIN/4534040067/
(2006/01)詳解 シェルスクリプト アーノルド ロビンス (著), ネルソン・H.F. ベーブ(著), Arnold Robbins (原著), Nelson H.F. Beebe (原著), 日向 あおい (翻訳)
http://www.amazon.co.jp/o/ASIN/4873112672/
(2007/3) Linuxシェルスクリプトユーザー便利帳―bash2/bash3対応 伊藤 幸夫 (著), 寒川 陽美(著)
http://www.amazon.co.jp/o/ASIN/4798015954/
(2007/9) ゲームで極める シェルスクリプトスーパーテクニック 山森 丈範
http://www.amazon.co.jp/o/ASIN/4774132020/
(2007/10) UNIX/Linuxシェルスクリプトマスタリングハンドブック 野川 准子
http://www.amazon.co.jp/o/ASIN/4798017957/
0008名無しさん@お腹いっぱい。
2008/10/16(木) 01:06:02FreeBSD Hypertext Man Pages
http://www.freebsd.org/cgi/man.cgi
Linux JF (Japanese FAQ) Project.
http://www.linux.or.jp/JF/
Unix Programming Frequently Asked Questions 日本語訳
http://www.adl.nii.ac.jp/~moro/unix-programmer/faq-j_toc.html
UNIXプログラミング環境
http://www.amazon.co.jp/exec/obidos/ASIN/4871483517/
0009名無しさん@お腹いっぱい。
2008/10/16(木) 01:06:58・このスレはシェルスクリプトについてのスレです。
シェルの対話的な利用についての話やスクリプトと関係ないコマンドの
使い方の質問などはスレ違いなので無用に願います。
□シェルスクリプトでよく使うコマンド:
制御・条件判定系: [,test,expr,true,false,yes,getopts
テキスト処理系: cat,awk,sed,tr,sort,uniq,grep,wc,head,tail,cut,paste,comm,join
ファイル検索系: find,xargs
(スペースなどを含むファイル名を正しく処理するため、
findは -print0、xargsは -0オプションを常に付けることを推奨
ただし、Solarisでは未対応。どうするんだろ?)
ディレクトリ系: basename,dirname
出力系: echo,printf
対話コマンド制御系: expect
http/ftpの処理自動化: wget,curl
0010名無しさん@お腹いっぱい。
2008/10/16(木) 04:18:200011名無しさん@お腹いっぱい。
2008/10/16(木) 07:06:51(スペースなどを含むファイル名を正しく処理するため、
findは -exec command {} + を推奨。
他に -print0、xargsは -0オプションという方法もあるがSolaris非対応)
0012名無しさん@お腹いっぱい。
2008/10/16(木) 09:35:20追加
FreeBSDユーザは/bin/shの正体がashなので注意。
v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。
http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/
http://heirloom.sourceforge.net/sh.html
0013名無しさん@お腹いっぱい。
2008/10/16(木) 10:49:58に改名したらどうだ。スレタイ。
0014名無しさん@お腹いっぱい。
2008/10/17(金) 00:29:51echo 乙 > /dev/null
0015名無しさん@お腹いっぱい。
2008/10/17(金) 00:44:250016名無しさん@お腹いっぱい。
2008/10/17(金) 00:49:170017名無しさん@お腹いっぱい。
2008/10/17(金) 00:52:090018名無しさん@お腹いっぱい。
2008/10/17(金) 10:20:48SCO OpenServer
0019名無しさん@お腹いっぱい。
2008/10/18(土) 01:55:15grep -v でも引数の文字列が存在すれば0、存在しなければ1に見えます。
でも
ps -ef | grep hoge | grep -v grep
のときプロセスhogeが存在すれば、0存在しなければ1を返すのはなぜでしょう?
そのリターンを返してるはずの最後の grep -v grep ではは毎回
文字列"grep"がひっかかってると思うんですけど・・・
0020名無しさん@お腹いっぱい。
2008/10/18(土) 02:11:441 # grep以外の行はないよ
$ (echo grep; echo foo) | grep -v grep; echo $?
foo
0 # grep以外の行があったよ
要するに-vの時に「ヒットする」のは"grep"にマッチ「しない」行。
0021名無しさん@お腹いっぱい。
2008/10/18(土) 08:58:28関係ない文字列にマッチする可能性とかがあるから。
pgrep使え。
0022名無しさん@お腹いっぱい。
2008/10/18(土) 10:01:59理解しました!
0023名無しさん@お腹いっぱい。
2008/10/18(土) 10:11:28>>21 は理解しないのかよw
0024名無しさん@お腹いっぱい。
2008/10/18(土) 10:29:35>>19の頭に「grep の戻り値で疑問なんすけど」と書いてある。
>>21は知識をひけらかしたくてしょうがない中二病。
0025名無しさん@お腹いっぱい。
2008/10/18(土) 10:33:36それは手段であって、目的ではないことはエスパーすればわかる。
前スレで、command1 | command2 とやった時、
command2の終了ステータスのみが反映されますよね? と聞いてた人と
同一人物だということも、エスパーすればわかる。
0026名無しさん@お腹いっぱい。
2008/10/18(土) 10:35:030027名無しさん@お腹いっぱい。
2008/10/18(土) 10:35:340028名無しさん@お腹いっぱい。
2008/10/18(土) 10:45:180029名無しさん@お腹いっぱい。
2008/10/18(土) 10:59:50ls -l とかもね。
0030名無しさん@お腹いっぱい。
2008/10/18(土) 11:08:580031名無しさん@お腹いっぱい。
2008/10/18(土) 11:11:490032名無しさん@お腹いっぱい。
2008/10/18(土) 11:59:18どっちかというと扱いやすい方。
0033名無しさん@お腹いっぱい。
2008/10/18(土) 13:17:070034名無しさん@お腹いっぱい。
2008/10/18(土) 13:25:53これはあたまいいっすね
0035名無しさん@お腹いっぱい。
2008/10/18(土) 13:27:47アフォか。vi hogeとかに引っかかる。
0036名無しさん@お腹いっぱい。
2008/10/19(日) 08:06:41pgrepが無い環境は私の周りにはほとんど無いから、pgrep使ってるよ。
0037名無しさん@お腹いっぱい。
2008/10/20(月) 21:13:59デリミタを : に変更して対処する方法がありますでしょうか。
sed ':/usr/local/hoge:d' hoge.txt のように処理したいのですが、
デリミタの変更は s や y の無い構文では変更できなくて苦悩中です。
sed 's:dummy:dummy:; :/home/hoge.txt:d' hoge とやれば処理可能です。
やりたい事は、sed 's:/usr/local/hoge::' で文字列を削除しても
改行が残ってしまうので、改行まで削除したいと思っています。
何か良案ありませんでしょうか。
0038名無しさん@お腹いっぱい。
2008/10/20(月) 21:21:37他なら知らん。
0039名無しさん@お腹いっぱい。
2008/10/20(月) 21:23:52POSIXにもある
0040名無しさん@お腹いっぱい。
2008/10/20(月) 21:29:44ファイルタイプ dとかfとかlとか出せないですかね?
0041名無しさん@お腹いっぱい。
2008/10/20(月) 21:34:170042名無しさん@お腹いっぱい。
2008/10/20(月) 21:49:26-type f -exec echo f {} \; -or \
(省略)
っていう糞みたいな案が思いついた
0043名無しさん@お腹いっぱい。
2008/10/20(月) 21:52:40名前,ユーザ,タイムスタンプ,権限,リンクならリンク先,ディレクトリとかファイルとかリンクとかの種類
みたいな感じのCSVを出力したいわけですよ
しかしファイルタイプの取り方が分からず
あとリンク切れだったら教えて欲しいですね
0044名無しさん@お腹いっぱい。
2008/10/20(月) 21:54:43GNU findなら、
find /dir -printf '%y %f?n'
0045名無しさん@お腹いっぱい。
2008/10/20(月) 22:26:05man に記載がありましたか。失礼しました...
>>39
ありがとうございます。
試してみます。
0046名無しさん@お腹いっぱい。
2008/10/20(月) 22:26:59/ /.; ; . | .; ヘ ;`i
/ .; ,; . .; | .; .; .; i
ヽ._/ . .; .; .; | .; ヾ_/ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
i´ . ; | .; .; `i |
`x ,. _ヽ | /----x'=-+ | 純正 find でヨロ
| 6〉,/ 。i._|_|/。 `ヽ,| #l) |
└-ヽ;ー‐'__└---===-┘ <
c==<< ̄ ̄ ̄ ̄>>.===o゛ \_________
/ ヾ二二//ゝ、 ___, ----―
 ̄i⌒/´ ヾ  ̄ ̄/ `i⌒ヽー、 ̄ ̄| | |
ヽ ゝー─---、_/---─ノ ノ | | | _ -‐
0047名無しさん@お腹いっぱい。
2008/10/20(月) 22:39:14あたりで、出力をsedかawkで加工。
0048名無しさん@お腹いっぱい。
2008/10/20(月) 22:48:43-exec ls -dl {} \; -exec ls -dlL {} \; して、
比較とか含めてawkあたりで加工するしかなさそうね
0049名無しさん@お腹いっぱい。
2008/10/20(月) 23:15:170050名無しさん@お腹いっぱい。
2008/10/20(月) 23:31:41今は手元のLinuxのGNU findでしか試せてないんですが、
>>44の%yでf,d,lとかが取れるのはありがたいですね
実際に動かしたいのはsolaris(詳細は忘れた)も混ざってるので、使えないのかもしれませんが。
使えなかったら>>42>>47>>48を参考に-exec ls加工でやりたいと思います。
ちなみにリンク切れというのはGNU findでも検知できないんでしょうか?
0051名無しさん@お腹いっぱい。
2008/10/21(火) 07:48:01あと「検知」した後どうしたいのか書いた方がいい。
0052名無しさん@お腹いっぱい。
2008/10/21(火) 10:20:21bbb.example.com
aaa.example.com
example.com
example.co.jp
↓
example.com
aaa.example.com
bbb.example.com
example.co.jp
のようなことは出来ますか?
ピリオドを区切り文字にして、右側のフィールドから順に評価してくれればイイのですが。
0053名無しさん@お腹いっぱい。
2008/10/21(火) 10:31:35Perl か何かで書いちゃえば?
http://d.hatena.ne.jp/peanutsjamjam/20080108
0054名無しさん@お腹いっぱい。
2008/10/21(火) 11:41:03> http://d.hatena.ne.jp/peanutsjamjam/20080108
ここの例だと、ハイフンがあると破綻するな。
0055名無しさん@お腹いっぱい。
2008/10/21(火) 21:43:35awk -F. '{ for (i=NF; i>0 ; i--) { printf("%s ", $i) }; print("") }' | sort | awk '{ for (i=NF; i>0 ; i--) { printf("%s.", $i) }; print("") }' | sed 's/\.$//'
0056名無しさん@お腹いっぱい。
2008/10/21(火) 22:04:400057名無しさん@お腹いっぱい。
2008/10/22(水) 11:02:44005852
2008/10/22(水) 11:13:00sortコマンドだけでは無理っぽいので、>>55さんの方法でやることにします。
"sort --sort=domainname"とか出来ればイイのですが。
>>56
> sort -i にした方がたぶん目的にはかなってるとおも
???GNUのsortだと -i は印刷不可能な文字を無視するだけのようです。
0059名無しさん@お腹いっぱい。
2008/10/22(水) 13:16:57006055
2008/10/23(木) 12:03:26> "sort --sort=domainname"とか出来ればイイのですが。
コマンドを組み合わせてやっつけるのがシェルスクリプトの妙味ですので。
特殊な処理をコマンドに埋め込み始めるときりがないので。
0061名無しさん@お腹いっぱい。
2008/10/23(木) 12:29:040062名無しさん@お腹いっぱい。
2008/10/23(木) 12:41:48スレタイ読めよ
0063名無しさん@お腹いっぱい。
2008/10/23(木) 13:22:170064名無しさん@お腹いっぱい。
2008/10/23(木) 13:38:55sortの行指向をうまく利用しているからかなり簡潔になってるよ。
0065名無しさん@お腹いっぱい。
2008/10/23(木) 14:45:30import sys
def sort_key(line):
L = line.split('.')
L.reverse()
return L
for line in sorted(sys.stdin, key=sort_key):
sys.stdout.write(line)
0066名無しさん@お腹いっぱい。
2008/10/23(木) 15:17:580067名無しさん@お腹いっぱい。
2008/10/23(木) 16:45:590068名無しさん@お腹いっぱい。
2008/10/23(木) 17:01:13> L = line.split('.')
< L = line.lower().split('.')
0069名無しさん@お腹いっぱい。
2008/10/23(木) 17:06:27> 〜 x.split(〜
< 〜 x.downcase.split(〜
以上スレ違い話終了
0070名無しさん@お腹いっぱい。
2008/10/24(金) 02:17:580071名無しさん@お腹いっぱい。
2008/10/24(金) 02:39:340072名無しさん@お腹いっぱい。
2008/10/24(金) 08:46:37比較時に数値化(rubyなら to_iとか)
0073名無しさん@お腹いっぱい。
2008/10/25(土) 01:06:59[e.gsub(/\d+/, '#'), e.scan(/\d+/).map {|e| e.to_i}]
}
メンドクサ
0074名無しさん@お腹いっぱい。
2008/10/25(土) 01:20:420075名無しさん@お腹いっぱい。
2008/10/25(土) 09:18:57pieces = re.split(r'(\d+)', s)
pieces[1::2] = map(int, pieces[1::2])
return pieces
ary.sort(key=embedded_numbers)
0076名無しさん@お腹いっぱい。
2008/10/25(土) 21:56:24最後の文字を変数 LAST_LETTER に,残りの文字列を FIRST_LETTERS に代入するように
してもらえるとありがたいです。
0077名無しさん@お腹いっぱい。
2008/10/25(土) 22:03:53expr "$s" : "\(.*\)."
expr "$s" : ".*\(.\)"
0078名無しさん@お腹いっぱい。
2008/10/25(土) 22:12:09方法は2つ
1。正規表現
2。文字列の長さを測って、1引いた長さと、その場所から1文字をとる
0079名無しさん@お腹いっぱい。
2008/10/25(土) 22:20:34惜しいね。そこまでわかってても、最後に LAST_LETTER FIRST_LETTERS に
代入するのができてないから、満点あげられないね。
>>78
77に具体的な答が(不完全だけど)出てるのに何言ってんだか。
具体的な答がないので点はあげられないね。
0080名無しさん@お腹いっぱい。
2008/10/25(土) 22:29:44FIRST_LETTERS=${S:0:${#S}-1}
LAST_LETTER=${S:${#S}-1}
0081名無しさん@お腹いっぱい。
2008/10/25(土) 22:34:53bash依存
0082名無しさん@お腹いっぱい。
2008/10/25(土) 22:38:38FIRST_LETTERS=${STRING%?}
LAST_LETTER=${STRING#"$FIRST_LETTERS"}
echo "$FIRST_LETTERS"
echo "$LAST_LETTER"
0083名無しさん@お腹いっぱい。
2008/10/25(土) 22:50:35>>82 は、正規表現も使っていないし、文字列の長さも測っていない。
よって、方法は3つ(以上)あることになる。
0084名無しさん@お腹いっぱい。
2008/10/25(土) 22:52:580086名無しさん@お腹いっぱい。
2008/10/26(日) 00:14:49正直、ここらの文字列操作はどれがbash拡張なのかどうか、
/bin/shがbashな環境にいると判別できないな。
0087名無しさん@お腹いっぱい。
2008/10/26(日) 00:56:43http://detail.chiebukuro.yahoo.co.jp/qa/question_detail.php?qid=1220150877
506 :目のつけ所が名無しさん:2008/10/26(日) 00:47:20
大手ECサイトで、ここまで派手なリリース失敗は初めて見た。
エンジニア向けIT情報誌や関連サイトは、ぜひ取材して原因を明かして欲し
いは。
0088名無しさん@お腹いっぱい。
2008/10/26(日) 08:36:19UNIXで/bin/shがbashな環境なんてあるの?
あ、opensolarisとか??
0089名無しさん@お腹いっぱい。
2008/10/26(日) 09:00:58MacOS X
0090名無しさん@お腹いっぱい。
2008/10/26(日) 11:02:55LinuxはUNIXじゃないという煽りなんですね お疲れ様です
0091名無しさん@お腹いっぱい。
2008/10/26(日) 12:57:35LinuxをUNIXにしたらLinuxが嫌なんじゃない?
UNIXじゃ無いのがアレの誇りなんじゃないの?
0092名無しさん@お腹いっぱい。
2008/10/26(日) 12:58:13linuxというくくりでは/bin/shが何なのかは明確じゃないからな。
0093名無しさん@お腹いっぱい。
2008/10/26(日) 13:45:380094名無しさん@お腹いっぱい。
2008/10/26(日) 14:30:56なぜ?
LinuxやFreeBSDと違って、れっきとしたUNIXだよ。
0095名無しさん@お腹いっぱい。
2008/10/26(日) 14:43:570096名無しさん@お腹いっぱい。
2008/10/26(日) 21:27:04あったと思うけど、
zshで、setopt shwordsplit してる環境だと、
${1+"$@"} ではスペースが不本意に解釈されてしまって、引数がそのまま引き継げない。
やはり、単純明快に "$@" と書いた方が良いという結論。
$ zsh
zsh$ setopt shwordsplit
zsh$ set 'hoge boke'
zsh$ for i in ${1+"$@"}; do echo "$i"; done
hoge ← 2つに分かれてしまう
boke ← 2つに分かれてしまう
zsh$ for i in "$@"; do echo "$i"; done
hoge boke ← 正常
0097名無しさん@お腹いっぱい。
2008/10/26(日) 21:35:29> zshで、setopt shwordsplit してる環境だと、
当たり前やんw
すげえピンぼけ
0098名無しさん@お腹いっぱい。
2008/10/26(日) 21:43:22なんで当たり前?
zsh以外では setopt shwordsplit状態がデフォだよ。
それで、${1+"$@"} は "$@"と同様に動作する。
で、${1+"$@"} が、word split されるのは zshのバグと言える。
0099名無しさん@お腹いっぱい。
2008/10/26(日) 22:50:20-name のかっこいい正規表現でいけないですか?
0100名無しさん@お腹いっぱい。
2008/10/26(日) 22:52:41findの -name は正規表現ではありません。はい次
0101名無しさん@お腹いっぱい。
2008/10/26(日) 22:54:30-regex '[^0-9]*'
0102名無しさん@お腹いっぱい。
2008/10/26(日) 22:59:07-regex '.*/[^0-9]*'
0103名無しさん@お腹いっぱい。
2008/10/26(日) 23:18:570104名無しさん@お腹いっぱい。
2008/10/26(日) 23:25:04-regex を使うなら、フルパスでしか指定できない。そういう仕様。
0105名無しさん@お腹いっぱい。
2008/10/26(日) 23:27:37-regex '.*/[^/0-9]*$'
0106名無しさん@お腹いっぱい。
2008/10/26(日) 23:28:22というか>>102でファイル名だけになってますね
ありがとうございました
■ このスレッドは過去ログ倉庫に格納されています