シェルスクリプト総合@LINUX Part3
■ このスレッドは過去ログ倉庫に格納されています
0001login:Penguin
2007/07/10(火) 23:17:13ID:qGthZdMEまあそれはそれとして、BASHウゼーとか言われる心配なく
平和にLINUX的スクリプト談義しましょうよ。
初めての自作スクリプト、自信ないから見てください。な初心者から
トリッキーな技を駆使した作品を披露したい、蘊蓄を語りたい上級者まで
いろいろな人に参加して頂けると嬉しいです。
perlやらPythonやらの話が混ざっても良いんでない?
【sed】シェルスクリプト総合@LINUX Part2【awk】
http://pc11.2ch.net/test/read.cgi/linux/1154578200/
http://pc8.2ch.net/test/read.cgi/linux/1121994321/
>>2-5あたりに色々と。
0402login:Penguin
2008/01/07(月) 00:59:34ID:Lq+3ioDoawk -Fなにか '{for (i=2;i<NF;i++){printf("%s%s", $i, FS)};print $NF}'
0403397
2008/01/07(月) 02:29:17ID:SZZlXYY6最初 >>387 さんと同じことを思ったのですが他に
オプションか何かで用意されていると思ってました。
402さんのを使わせていただきます
0404397
2008/01/07(月) 02:29:58ID:SZZlXYY60405login:Penguin
2008/01/07(月) 17:21:59ID:CzyB4/IBこれだと複数の空白が一つになって表示される
0406login:Penguin
2008/01/07(月) 18:30:26ID:DBTZ8VT20407login:Penguin
2008/01/07(月) 18:59:30ID:AGg2gknUaho,choaho,kusoaho,doaho
∴
awk '{print substr($0,length($1)+2)}'
0408login:Penguin
2008/01/07(月) 20:07:07ID:81ckgAQ5gawk 'gsub(/^[[:blank:]]*[^[:blank:]]+/,"")'
かな。
0409login:Penguin
2008/01/07(月) 20:13:04ID:DBTZ8VT20410login:Penguin
2008/01/07(月) 23:07:24ID:6d+dex8Hbar=234
[file2]
foo=123
Bar=987
と2つのkey=valueな内容が入ってるファイルがある。ここで、file1には
ないがfile2にはあるkeyのみ(case-insensitiveな比較で、また、valueは
違っていてよい)を拾いkey=valueを出力したいのだけど、一行で書けないかな?
どういう出力になってほしいかというと
$ myuniq --split-char='=' --field-index=1 --print-unique file1 file2
foo=123
というような実行イメージ。awkで
awk -F= '{ line[toupper($1)]=$0; seen[toupper($1)]++; } END { for (key in line) if (seen[key] == 1) print line[key]; }' file1 file2
みたいなのはでっち上げたんだけど、正直汚い。
0411login:Penguin
2008/01/07(月) 23:30:18ID:6RYIn4eu2ファイル通して1回しか現れなかったものを表示するから、
「file1にはないがfile2にある」ものだけでなく
「file2にはないがfile1にある」も出てこないか?
0412login:Penguin
2008/01/07(月) 23:35:18ID:6RYIn4eufor w in `cut -d= -f1 file1 file2 |tr A-Z a-z|sort|uniq -c|sed -n 's/ 1 *//p'`; do grep "^$w=" file2; done
0413login:Penguin
2008/01/07(月) 23:52:40ID:DBTZ8VT2重複は無考慮
0414login:Penguin
2008/01/07(月) 23:54:29ID:6d+dex8Hあ、すみません。バグです。が、元の仕様が厳しすぎで、
どちらかにしかないエントリを出す
でも大丈夫でした。
file1かfile2のどちらかにのみあるkeyに対応するkey=valueを出力する
に仕様を訂正させてください。
何をしたいのかというと、Windowsの環境変数を手元のUNIXな環境に
取り込みたいのですが、その際に自分で定義している分については
上書きされないようにしたいのです。
hostA$ env > hostA.env
hostB$ env > hostB.env
hostB$ myuniq ... hostA.env hostB.env > diff.env
hostB$ . ./diff.env
みたいなことをしたいと。で、片方の環境が Windows なもので、
case insensitiveな比較とかも必要になってます。
行全体ではなく特定のフィールドのみ見て uniq/diff 処理して出力って
簡単そうで微妙に面倒です。
0415login:Penguin
2008/01/07(月) 23:59:58ID:6d+dex8Hおおー。grepのexprに改行入れるとそんな動作になるとは!
エレガントです。勉強になりました mOm
0416login:Penguin
2008/01/08(火) 18:35:59ID:0P1F18Bp2つ目に実行したコマンドに、1つ目に実行したコマンドの引数を
そのまま渡したい場合の記述方法がわからず、困っています。
$ vi hogehoge; echo ??
*??が不明箇所*
上記の例の場合は2つ目に実行しているecho文の出力結果でhogehogeを表示させたいのですが。。
対処方法はないでしょうか?
よろしくお願いいたします。
0417login:Penguin
2008/01/08(火) 18:38:30ID:k6k1za9Ni="hogehoge"; vi $i; echo $i
じゃだめなん?
0419login:Penguin
2008/01/08(火) 23:12:30ID:OqUgF6yk0420login:Penguin
2008/01/08(火) 23:26:00ID:5sg6/WvNそれタイプしたタイミングではまだ!$は前行のコマンドの。
0421login:Penguin
2008/01/08(火) 23:33:15ID:A2IkwjENvi hogehoge; echo $_
でもいけるな。
0422login:Penguin
2008/01/10(木) 13:02:51ID:9dVYtTPeその呼び出したJava内部で例外が発生した場合、
以降のシェルの処理を続行させたくありません。
どの様にすればよいのですか?
Javaのcatch節でSystem.exit(1);とかで処理を終了させて、
cshでそれを検知する方法があるのかなぁ?
と漠然には思うのですが・・・
0423login:Penguin
2008/01/10(木) 19:51:46ID:qThypT9TSystem.exitが何をするのか分かっているなら、
Javaコマンドの終了値を普通にifなりswitchなりで受けて、csh側からもexitすれば良いだけでは?
単純に例外=即終了と決め打ちなら良いけど、例外によって複数の処理をさせたくなると、
System.exitの終了値を多数用意して管理しなければならなくなって面倒だけどね
ここからはポリシーの問題になるけど、System.exit等を使ってコマンドの終了値を利用するよりは、
どんな例外で終了したのかを前もって文字列等でstderrにでも吐き出したり、
終了した例外を表すような長さゼロのテンポラリファイルでも作ってから、Javaコマンドの方を終了させておいて、
csh側からは、むしろその文字列やファイル名を評価させてexitさせるようにした方が、後からデバッグする時とかは楽だよ
更に言えばシェルプログラミングにcshを使うのは止めるべき
http://www.klab.ee.utsunomiya-u.ac.jp/~hiroki/csh-whynot.euc
http://www.klab.ee.utsunomiya-u.ac.jp/~hiroki/sh-perl-tips/
0424login:Penguin
2008/01/10(木) 21:50:31ID:CJRDs9Ag0425login:Penguin
2008/01/11(金) 14:14:06ID:mrGJLB/gありがとうございます。
シェルスクリプト自体、経験が浅い上に今回の要望がcshというのが
決まっているもので・・・
困っています。。。
2chでの質問自体も初めてなもので・・・
準正常として扱うような例外は全てJava側で処理をしてプログラムは
正常終了として扱っています。
処理続行不可能と判断した、ランタイム系やIO例外などが発生した場合は
後続のシェルを流したくない。
という状況です。
if $JAVA_CMD
then
続き
else
exit 1
fi
以下処理続く
・・・
ってな感じにしたのですが、どうも上手くJavaでexitした値が取れないです。
文法が間違っているのですかね?
もう少し調査してみますが、上記の書き方で間違いがあればご指摘頂きたいです。
後は教えていただいた、テンポラリファイルでの判断も考えてみます。
0426login:Penguin
2008/01/11(金) 15:11:54ID:GLHvzQDj0427login:Penguin
2008/01/11(金) 16:08:44ID:6CIbL1kGcshなら
$JAVA_CMD
if ($? != 0) then
echo "failed"
exit $?
endif
echo "OK"
でどう?
0428login:Penguin
2008/01/11(金) 16:55:30ID:mrGJLB/gありがとうございます。
教えていただいた方法で、想定通りの動作になりました。
0429login:Penguin
2008/01/11(金) 21:11:49ID:OPXAXUzh普通にtreeコマンド使うんじゃだめなん??
findで絞った結果を出したいのかなぁ。
0430login:Penguin
2008/01/11(金) 22:17:07ID:4hqMEkJ5とか。
# 本気にしないように。
0431login:Penguin
2008/01/11(金) 23:02:21ID:aloediIm0432login:Penguin
2008/01/14(月) 11:50:49ID:3iR1bkH0いい方法はありませんか?
0433login:Penguin
2008/01/14(月) 12:00:15ID:ZjONjaHo0434login:Penguin
2008/01/14(月) 12:12:55ID:6n5zEajJ0435login:Penguin
2008/01/14(月) 14:01:26ID:Or9vH7Fnどのような正規表現を使えば良いでしょうか?
@hotmail.co.jp の.jp の部分を見る感じです。
.jp以外は無視する、という感じです。これで日本のメールしか相手にしない事になりますよね。
0436login:Penguin
2008/01/14(月) 14:04:07ID:ZjONjaHo日本からも.comや.netや.orgや.infoや.bizや.acや.tvや.toや(以下略)の
アドレスでメールが送られることはあるぞ。
0437login:Penguin
2008/01/14(月) 14:04:25ID:Or9vH7Fn↑これでいいんでしょうか?正規表現全く知らない状態でネットでちょっと検索してみたのですが・・・
0438login:Penguin
2008/01/14(月) 14:05:05ID:Or9vH7Fn海外のメールを相手にしない方法って無いんですかね・・・
英語でViagraとかうるさいんですよ。
0439login:Penguin
2008/01/14(月) 14:17:08ID:6n5zEajJひらがながないメールは無視してもよかろう。
0440login:Penguin
2008/01/14(月) 14:37:34ID:FCIPzPAY^Content-Type: .*iso-2022-jp
0441login:Penguin
2008/01/14(月) 14:42:36ID:6n5zEajJ0442login:Penguin
2008/01/14(月) 14:54:07ID:JtG94m550443login:Penguin
2008/01/14(月) 22:54:28ID:RfE0b+o0\.jp$
では?
0444login:Penguin
2008/01/16(水) 13:17:12ID:ZRO/FTzi何か良い書き方はないでしょうか。
sed '$d' xxxx | sed '$d' | sed '$d' と書くくらいしか思い付かなくて。
0445login:Penguin
2008/01/16(水) 14:26:14ID:1obpvu1Ahead -n -3 foobar.txt
0446login:Penguin
2008/01/16(水) 17:01:38ID:IKqjky5V0447login:Penguin
2008/01/16(水) 18:25:12ID:ZRO/FTzihead のオプションは見落としてました…ありがとうございます
0448login:Penguin
2008/01/16(水) 21:56:01ID:KAlEWwYc1. $$
2. $RANDOM
3. /dev/urandom
4. 時計
あたりを思いついたんだけど
0449login:Penguin
2008/01/16(水) 22:14:57ID:yh54UVVr0450login:Penguin
2008/01/16(水) 22:16:21ID:KAlEWwYc2. bash依存
3.4. 面倒
という問題点があるから,誰かいい方法教えてくれないか?
0451login:Penguin
2008/01/16(水) 22:19:14ID:KAlEWwYcとりあえずこうしとけ的な汎用的な方法はないんかな.
いちばん手軽な方法が知りたい
0452login:Penguin
2008/01/16(水) 22:47:32ID:HQvmxN1E$$はスクリプト内で複数個必要だと使えない罠
dateのmanを見ていたら、
%N nanoseconds (000000000..999999999)
というのがあった。こんな感じ
% echo -n `date +%N`
431218994 % echo -n `date +%N`
857494685 % echo -n `date +%N`
269031777 % echo -n `date +%N`
803351248 % echo -n `date +%N`
195538275 % echo -n `date +%N`
538357509 % echo -n `date +%N`
058776188 %
0453login:Penguin
2008/01/16(水) 23:09:59ID:PJonPFmQjot -r 10 1 6
/dev/urandomは10進数テキストで得るのがめんどーだろうか。
dd if=/dev/urandom bs=2 count=1 2>/dev/null | od -vd
左カラムがじゃまだな。 sed 1q |cut -f2 -d' ' とかで削るか。
0454login:Penguin
2008/01/16(水) 23:21:36ID:KAlEWwYcなるほど.date +%Nはいい感じ.
jot便利そうだよ,jot.犬にもこんなの欲しいな.
ありがとう
0455login:Penguin
2008/01/16(水) 23:24:18ID:HQvmxN1E0456login:Penguin
2008/01/16(水) 23:33:28ID:PJonPFmQr=`printf %d 0x$r`
ごめんなさいごめんなさい。
0457login:Penguin
2008/01/16(水) 23:51:47ID:puzD1M+G0458login:Penguin
2008/01/16(水) 23:55:16ID:KAlEWwYc0459login:Penguin
2008/01/17(木) 01:30:17ID:xe77Y4ah0460login:Penguin
2008/01/17(木) 01:45:37ID:hGbWYs9Cそういうものが必要な処理はシェルじゃなく、ちゃんとそれなりの言語でプログラムしたほうがいいかも。
0461login:Penguin
2008/01/17(木) 09:08:26ID:MJ2pzO6M0462login:Penguin
2008/01/17(木) 09:18:44ID:wcByJn9i| awk '{hist[int($2%10)]++} END{for (i in hist) {printf("%2d %5.2f%\n",i, hist[i]/NR*100) }; exit}' | sort -k1n
0 9.70%
1 10.70%
2 8.60%
3 11.00%
4 10.40%
5 8.90%
6 11.40%
7 9.70%
8 9.80%
9 9.80%
(´・ω・`)
% i=0; while [ $i -lt 1000 ] ; do echo "$i "`date +%N`; i=`expr $i + 1`; done \
| awk '{hist[int($2%10)]++} END{for (i in hist) {printf("%2d %5.2f%\n",i, hist[i]/NR*100) }; exit}' | sort -k1n
0 9.20%
1 12.30%
2 8.60%
3 11.00%
4 11.20%
5 9.30%
6 11.40%
7 7.80%
8 11.40%
9 7.80%
(゚д゚)
0463login:Penguin
2008/01/17(木) 09:28:02ID:wcByJn9i| awk '{hist[int($2/256.0*10)]++} NR==1000{for (i in hist) {printf("%2d %5.2f%\n",i, hist[i]/NR*100) }; exit}' | sort -k1n
0 9.80%
1 9.50%
2 10.10%
3 9.80%
4 9.80%
5 9.40%
6 10.20%
7 10.20%
8 10.30%
9 10.90%
(´・ω・`)
% perl -e '$MAX=10;$LOOP=1000000; for (1...$LOOP) {$hist[int(rand()*$MAX)]++}; for (0..$MAX-1) {printf("%2d %4.2f%\n", $_, $hist[$_]/$LOOP*100) }'
0 9.98%
1 9.99%
2 9.99%
3 10.02%
4 10.03%
5 10.02%
6 9.92%
7 10.00%
8 10.00%
9 10.04%
(゚∀゚)
date +%Nは、ばらつきはともかく遅いな...
0464login:Penguin
2008/01/17(木) 10:59:36ID:bFGNQCBf0465login:Penguin
2008/01/17(木) 11:37:17ID:LfhUWWyD> 2. bash依存
ksh88由来らしい
tp://www.cs.princeton.edu/~jlk/kornshell/doc/man88.html
ksh互換を期待できるなら使ってもいいんじゃね
0466login:Penguin
2008/01/18(金) 01:58:10ID:S6Zw/ddB0467login:Penguin
2008/01/18(金) 07:42:17ID:YTGcRcKS/usr/gamesってそれ何年前のWSのディレクトリ構成だよ...
0468login:Penguin
2008/01/18(金) 17:40:50ID:wVas3OI30469login:Penguin
2008/01/18(金) 17:50:43ID:YTGcRcKS0470login:Penguin
2008/01/18(金) 22:33:39ID:EJvy1m4kfind (検索ディレクトリ) -type d -printf "%p/\n" -or -print
0471login:Penguin
2008/01/18(金) 22:55:09ID:S6Zw/ddB最新のLinuxの(いやほんと。これだけは伝統的理由で残ってるのかな)
0472login:Penguin
2008/01/18(金) 23:22:22ID:6BHP4h960473login:Penguin
2008/01/19(土) 01:14:55ID:ZLNpfSkQDebian (sid)。まあ bsdgames とかまんまレガシーなパッケージだけだけどね。
0474login:Penguin
2008/01/19(土) 05:58:20ID:JWtUz7T2中みたらbannerとfortuneが入ってた。
0475login:Penguin
2008/01/19(土) 08:07:34ID:njld/y5g0476login:Penguin
2008/01/19(土) 17:07:33ID:NuJUp+KH/start.txt内の記載が
12
254
3678
4
59
621
78
896
、、、、、、
と法則性の無い桁数の数字が2000行近くあるものを
/end.txtに
12,254,3678,4
59,621,78,896
、、、、
A,B,C,Dと4項目で1行に変換したいと思っています
start.txtから4行抜き出して end.txtに1行にする考え方でいい方法を教えていただけないでしょうか
よろしくお願いいたします
0477login:Penguin
2008/01/19(土) 18:46:40ID:ZLMZWyE0余りが出たら最後カンマ付きで出力されちゃうけど
0478login:Penguin
2008/01/19(土) 18:55:41ID:NuJUp+KH完璧な物ありがとうございます
今迄sedばかり使っていたのですがawkすごいですね
awkの勉強させていただきます
0479login:Penguin
2008/01/19(土) 18:59:10ID:IrN8xoLtawk '{printf"%s%s",$0,(NR%4?",":"\n")}' < start.txt
0480login:Penguin
2008/01/19(土) 19:02:55ID:NuJUp+KHありがとうございました
とても参考になります
0481login:Penguin
2008/01/19(土) 19:43:02ID:rxOILVvfq94J↓q10000@9
:%s/ /,/g
:w end.txt
0482login:Penguin
2008/01/19(土) 19:59:13ID:58USgOmqDebianではゲームの実行バイナリは/usr/gamesに置かれるぜ。
最近はポリシーチェッカも警告を出すようになったから、lennyまでには移動完了するんじゃね。
http://lintian.debian.org/reports/Tpackage-section-games-but-contains-no-game.html
http://lintian.debian.org/reports/Tpackage-section-games-but-has-usr-bin.html
0483login:Penguin
2008/01/19(土) 21:00:37ID:ZLNpfSkQなんでだろうね?
FHS誤解してたかと読み直したらそんなことないし。理由がわからん。
0484login:Penguin
2008/01/19(土) 21:04:24ID:ZLNpfSkQAs described in the FHS, binaries of games should be installed in the directory /usr/games.
This also applies to games that use the X Window System.
Manual pages for games (X and non-X games) should be installed in /usr/share/man/man6.
とか書いてあった。FHSをgrepしたら、正式なセクションはないが、optionalとしてgames作っていいと
書いてあった。
0485login:Penguin
2008/01/19(土) 21:14:55ID:Xt/fDApdそういうのが全て悪の元凶。
0486login:Penguin
2008/01/19(土) 22:06:40ID:ZLNpfSkQそれだけでも推進されてしかるべき。
0487login:Penguin
2008/01/20(日) 02:02:52ID:dexE1e0mディトリビュータはゲームなんか提供すんな、ということなのだよ。
つまりゲームを提供しているDebianは人々を堕落させる悪のディストリビュータなのだ!
0488login:Penguin
2008/01/20(日) 02:23:04ID:kH+ebKTAなにその陰謀史観(w
単に /usr/ 直下はディストリの管轄だし自分で決めろ、
一方で /usr/local/* は空フォルダ切っておく以上は認められないから
代わりとして、せめて誘導できるように切っておけ、ということかと。
FHSで自分的に従来慣習と比較して見慣れないのは/srvだな。
どこのUNIXでの慣習だったんだろう?
0489login:Penguin
2008/01/20(日) 02:55:38ID:M1QHfiRt/usr/games/bin/fortune じゃなくて
/usr/games/fortune ってとこじゃなかったのかー
0490login:Penguin
2008/01/20(日) 04:01:16ID:FZKKsnApsed ':b;1~4,+2{N;s/\n/,/;bb}'
sedも心の片隅にでも置いておいてやってくだされ。
0491login:Penguin
2008/01/20(日) 04:20:45ID:IwRos1VB管理者のPATHからゲーム関係を除外するのが目的だろうから
/usr/games/binとサブディレクトリを掘る必要はないんじゃね。
0492login:Penguin
2008/01/21(月) 02:31:10ID:HJiECvMSそんな記法初めて見た…
どうなってんの???
0493login:Penguin
2008/01/21(月) 02:55:10ID:QTxOOwHl0494login:Penguin
2008/01/21(月) 11:41:48ID:JvqHER/Wpaste -d, - - - -
paste も心の片(ry
0495login:Penguin
2008/01/21(月) 14:42:32ID:svPtjQeo$ cat name.txt
name1
name2
name3
name4
name5
$ cat weight.txt
weight1
weight2
weight3
weight4
weight5
このとき、なんとかして
$ ???????????
name1 weight1
name2 weight2
name3 weight3
name4 weight4
name5 weight5
と表示したいのですができません。
最初は
$ cat name.txt weight.txt > data.txt
$ awk '{ if(NR<=5) a[NR]=$0; else b[NR-5]=$0} end{for(i=1;i<=100;i++) printf i,a[i],b[i];}' data.txt
としましたが、空白が表示されるだけでした。
0496login:Penguin
2008/01/21(月) 14:51:31ID:N+zVQlnlpaste
0497login:Penguin
2008/01/21(月) 14:53:35ID:svPtjQeoありがとうございました。
ぐぐるまでもヘルプ読むまでもなく、
適当にいじっただけでそうなりました。
0498login:Penguin
2008/01/22(火) 11:11:17ID:DOTIpHDEgawk 'FILENAME != old {i=0;old=FILENAME} {data[i++] = data[i]" "$0;} END{for(j=0; j<i; j++)print data[j]}' name.txt weight.txt height.txt
ファイル数に制限はない。あと出力される行数は、最後のファイルの行数によって決まってしまうがな。
0499login:Penguin
2008/01/25(金) 13:18:49ID:u9KTnE0i一応予想通りに動いてるようですが問題点や改善点があったら叩いてくだしあ
#!/bin/sh
EXT='.jpeg$|.jpg$|.png$'
LIST=`ls $1 | grep -Ei $EXT`
if [ "$LIST" = '' ] ; then\
echo "No files found in $1."
exit
fi
NUM=`echo $LIST | wc -w`
N=`expr $RANDOM % $NUM + 1`
TARGET=`echo $LIST | cut -d ' ' -f $N`
#echo "$1/$TARGET"
bsetbg $1/$TARGET
0500login:Penguin
2008/01/25(金) 15:41:59ID:5ugSsaO2そのままだと画像ファイル名やパスに空白があると動かないけど、いいのか?
0501login:Penguin
2008/01/25(金) 17:04:10ID:HizVC3Pfimport sys, os, random
def is_image(filename):
EXT = ('jpeg', 'jpg', 'png')
return any(filename.endswith(ext) for ext in EXT)
if sys.argv[1:]:
dir = sys.argv[1]
else:
dir = os.path.curdir
files = filter(is_image, os.listdir(dir))
if not files:
print "No images found in %s" % dir
sys.exit(1)
target = random.choice(files)
os.system("echo bsetbg '%s'" % os.path.join(dir, target))
# 高級言語って素晴らしいね
0502login:Penguin
2008/01/25(金) 17:51:17ID:u9KTnE0i修正してみました
#!/bin/sh
EXT='.jpeg$|.jpg$|.png$'
if [ "$1" = '' ] ; then\
DIR=`pwd`
else\
DIR="$1"
fi
LIST=`ls "$DIR" | grep -Ei "$EXT"`
if [ "$LIST" = '' ] ; then\
echo "No files found in $DIR."
exit
fi
NUM=`echo "$LIST" | wc -w`
N=`expr "$RANDOM % $NUM + 1"`
TARGET=`echo "$LIST" | cut -d ' ' -f "$N"`
#echo "$DIR/$TARGET"
bsetbg "$DIR/$TARGET"
■ このスレッドは過去ログ倉庫に格納されています