シェルスクリプト総合 その9
レス数が950を超えています。1000を超えると書き込みができなくなります。
0001名無しさん@お腹いっぱい。
2007/08/15(水) 07:25:02スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>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 でトレースしましょう。
前スレ
シェルスクリプト総合 その8
http://pc11.2ch.net/test/read.cgi/unix/1171517324/
0879名無しさん@お腹いっぱい。
2008/02/04(月) 23:26:500880名無しさん@お腹いっぱい。
2008/02/04(月) 23:44:18なぜsh互換ではNGでbash専用でないとダメなのか
その上司を問いつめて、結果をこのスレに書き込んでみ?
0881名無しさん@お腹いっぱい。
2008/02/05(火) 00:49:390882名無しさん@お腹いっぱい。
2008/02/05(火) 02:11:40まず
ttp://search.luky.org/linux-users.9/msg06102.html
とか嫁
0883名無しさん@お腹いっぱい。
2008/02/05(火) 02:30:35test とか [ を [[ 記法にでも変えたら?
0884名無しさん@お腹いっぱい。
2008/02/05(火) 03:10:05うっう〜
0885名無しさん@お腹いっぱい。
2008/02/05(火) 07:15:24testも[もないんだが、>>870 には。
0886名無しさん@お腹いっぱい。
2008/02/05(火) 09:47:50こんなの趣味でも書かないけどな。w
#!/bin/bash
while read line
do
grep "${line:0:3}" file2 &> /dev/null
if $[ $? == 0 ] ; then
echo "$key は file2にある"
else
echo "$key は file2にない"
fi
done <<< "$( < file1 )"
0887名無しさん@お腹いっぱい。
2008/02/05(火) 09:49:48けど、こんなの使わないからいいか。w
0888名無しさん@お腹いっぱい。
2008/02/05(火) 10:19:410889名無しさん@お腹いっぱい。
2008/02/05(火) 10:33:290890名無しさん@お腹いっぱい。
2008/02/05(火) 10:56:19他の環境どころか、明日はもう動かなくていいやつとか。
0891名無しさん@お腹いっぱい。
2008/02/05(火) 12:31:070892名無しさん@お腹いっぱい。
2008/02/06(水) 13:18:18のようなものの-not -regex ".*#.*" -not -name "*~" -not -name "*svn*"の部分だけを再利用したいんですが
ignore_backup="-not -regex \".*#.*\" -not -name \"*~\" -not -name \"*svn*\""
のようにして
$ find $FOO $ignore_backup -name "*.el"
としてもうまくフィルタリングしてくれないようです
何が良い方法はありませんか?
0893名無しさん@お腹いっぱい。
2008/02/06(水) 13:33:030894名無しさん@お腹いっぱい。
2008/02/06(水) 14:01:270895名無しさん@お腹いっぱい。
2008/02/06(水) 14:10:12evalすると言う手でなんとかしました
zsh,bashでしか確認してませんがとりあえずこんな感じでいけました
この方針なら内部で他の変数を参照する予定の無い文字列はsingle quoteにした方がよさそうですね
# dot files
ignore_bkup='-type f -not -regex ".*#.*" -not -name "*~"'
eval "$find $HOME -maxdepth 1 $ignore_bkup -regex '.*\/\..*'"
0896名無しさん@お腹いっぱい。
2008/02/06(水) 14:19:360897名無しさん@お腹いっぱい。
2008/02/06(水) 19:47:26引数にlistという文字列がある場合には、lsコマンドを実行する
これを実行するにはどういう構文をつくればいいのでしょうか?
0898名無しさん@お腹いっぱい。
2008/02/06(水) 20:05:04for arg in "$@"
do
case $arg in
list)
ls;;
esac
done
0899名無しさん@お腹いっぱい。
2008/02/06(水) 20:22:09ありがとうございます
0900名無しさん@お腹いっぱい。
2008/02/06(水) 23:46:40$args → "$args"
0901名無しさん@お腹いっぱい。
2008/02/06(水) 23:47:18お前馬鹿だろ
0902名無しさん@お腹いっぱい。
2008/02/07(木) 00:30:09> 何か最低限bashシェル専用の文法を使わなければ上司が納得してくれません。
お前に必要なのは不要な文法ではなくて新しい職。
0903名無しさん@お腹いっぱい。
2008/02/07(木) 04:59:080904名無しさん@お腹いっぱい。
2008/02/07(木) 09:35:36$ echo .string | sed -e s/^\\\\.//
.string
(2)
$ AAA=.string
$ BBB=
$ BBB=`echo "$AAA" | sed -e s/^\\\\.//`
$ echo $BBB
string
(1)(2)で結果が違ってくるのですがこれはなぜでしょうか。
0905名無しさん@お腹いっぱい。
2008/02/07(木) 09:48:23を使っているから。
0906名無しさん@お腹いっぱい。
2008/02/07(木) 09:49:180907名無しさん@お腹いっぱい。
2008/02/07(木) 09:55:550908名無しさん@お腹いっぱい。
2008/02/09(土) 01:16:110909名無しさん@お腹いっぱい。
2008/02/11(月) 14:50:12unixのwc -lコマンドと同等のものを
perlやawkの一行野郎にしたいのですがうまくいきません
perl -ne 'while (<>) { print cnt}' file1
お願いします
0910名無しさん@お腹いっぱい。
2008/02/11(月) 14:55:300911名無しさん@お腹いっぱい。
2008/02/11(月) 14:58:34awk使いたいだけなら、
cat file1 | cat -n | tail -1 | awk '{print $1}'
でいいじゃん。
0912名無しさん@お腹いっぱい。
2008/02/11(月) 15:00:280913名無しさん@お腹いっぱい。
2008/02/11(月) 15:03:27cat file | cat -n
ってところかい?
それは最初のcatは、catじゃなくても他の部分から取れるようにしてるのだが。
0914名無しさん@お腹いっぱい。
2008/02/11(月) 15:03:40awk 'END{print NR}' file
0915名無しさん@お腹いっぱい。
2008/02/11(月) 15:04:54無駄ってのは、>>914 でできるのにわざと冗長な方法を書いていること。
0916名無しさん@お腹いっぱい。
2008/02/11(月) 15:05:560917名無しさん@お腹いっぱい。
2008/02/11(月) 15:08:23要求をはっきりしたまえ。
もっとも、↓これなら完璧だが。
perl -e 'exec "wc", "-l", @ARGV'
0918名無しさん@お腹いっぱい。
2008/02/11(月) 15:09:44みんなで考察してみようぜ。
まず、どこから急にcntが出て来たのか。
0919名無しさん@お腹いっぱい。
2008/02/11(月) 15:11:25>>911でいいじゃないか。
思い付いたようにシンプルに済ませるのがShellScriptでしょ。
0920名無しさん@お腹いっぱい。
2008/02/11(月) 15:12:23サーバ環境のコードに合わない文字コードのファイルだと
wcコマンド使えないので他に代用したいというのが背景です。
目的はファイルの行数を単にカウントするだけです。
0921名無しさん@お腹いっぱい。
2008/02/11(月) 15:18:320922名無しさん@お腹いっぱい。
2008/02/11(月) 15:28:57みなさんありがとうございました
0923名無しさん@お腹いっぱい。
2008/02/11(月) 16:58:29awkなら、>>914 が解として最善だが、wcの文字コードの問題なら、
LANG=C LC_ALL=C wc -l
としても解決できるはず。
0924名無しさん@お腹いっぱい。
2008/02/11(月) 17:11:58それは>>914もそうだが。
0925名無しさん@お腹いっぱい。
2008/02/11(月) 17:23:15そんな必要ない。最初の質問情報だけで最適解を出すのが良い。
それで求めているものと違っているなら質問者が再度質問してくるだけだから。
それより問題なのは、最適解を知らないくせに質問者に追加情報だけ出せという奴。
(で、たいてい追加情報が出てきても最適解を答えられないw)
0926名無しさん@お腹いっぱい。
2008/02/11(月) 17:41:27もし複数のファイルを対象にしたいとか>>914の解とは違ってたら、情報を小出
しにするなとか言い出すんだろうなw
まぁ、そんなことより追加情報が出る度に解を出して良くってのはものすごい
効率が悪いな。 最初に情報を聞き出してから普通は何かを作るだろ。
仕様が不十分なままにコード書き始めて、途中で仕様がひっくり返ったら全部
作り直しだろ。
0927名無しさん@お腹いっぱい。
2008/02/11(月) 17:41:00そのとおりだ
0928名無しさん@お腹いっぱい。
2008/02/11(月) 17:45:280929名無しさん@お腹いっぱい。
2008/02/11(月) 17:48:56適してるならまだしも、最適って。
別に>>911でも解としては間違ってないわけで、
なんでそんなに自分の解に自信を持ってるのかと。
0930名無しさん@お腹いっぱい。
2008/02/11(月) 17:54:51awkを使うなら、cat -nだけでなくtail -1の機能もawk側でできるから、
わざわざ多段パイプにするのが無駄。
逆に、cat -n|tail -1にするなら、最後までawkを使わずに処理するべき。(cutとかで)
0931911
2008/02/11(月) 17:55:43perl -e 'while(<>){} print "$.\n"' file1
行数数えるだけならこうかな。
最適っていうなら、「Perlやawk」でって言ってるんだから、Perlでの最適な答えも出して上げれば良いのに。
もちろん、上の解が最適だとは思わないけどね。
他にもやり方は色々あるし、毎行処理してる時点で最適ではないし。
(awk {END}もそうだけど。)
0932911
2008/02/11(月) 17:56:59awkを使って。 って書いてあるから、awkを使っただけなんだけど…。
awkはあんまり使わんから、とりあえずできればって思っただけなんだけど。
まぁ、自分はそんなに自信があって言ったわけじゃないからねスマンね。
0933名無しさん@お腹いっぱい。
2008/02/11(月) 18:04:11>>914 最適な解を望む。 最適な解だぞ。
0934名無しさん@お腹いっぱい。
2008/02/11(月) 18:07:05だから、awkを使ってっていってるのに、
なんで awk側でできる cat -n や tail -1 相当の処理を
awk側でやらないのかってこと。
>>930 の最後の行で言ってる、「最後までawkを使わずに処理するべき」ってのは、
「cat -n | tail -1」を使う以上は、ってこと。
で、それだと「awkを使う」という質問に適合しないから、
>>911 は解にならないと言いたいわけ。
0935名無しさん@お腹いっぱい。
2008/02/11(月) 18:08:05かな。
0936名無しさん@お腹いっぱい。
2008/02/11(月) 18:09:37それだとお前の最適って言う言葉も最適ではないから解ではないな。
0937名無しさん@お腹いっぱい。
2008/02/11(月) 18:14:55で、>>920 で言ってるように、本当は wc -l を使いたかったけど、
それだと日本語環境で文字コードが解釈されてエラーになるのが問題なんだから、
>>923 が言うように、
LANG=C LC_ALL=C wc -l
が最適解だね。
0938名無しさん@お腹いっぱい。
2008/02/11(月) 18:18:5589232
real 0m0.359s
user 0m0.327s
sys 0m0.011s
tmp]$ time perl -e 'while(<>){} print "$.\n"' tmp
89232
real 0m0.273s
user 0m0.236s
sys 0m0.010s
tmp]$ time awk 'END{print NR}' tmp
89232
real 0m0.150s
user 0m0.126s
sys 0m0.009s
tmp]$ perlcc -B tmp.pl; time ./a.out tmp
89232
real 0m0.286s
user 0m0.263s
sys 0m0.000s
やっぱりawkが早いな。
0939名無しさん@お腹いっぱい。
2008/02/11(月) 18:19:55awk, Perlを使っての解がしりたかったみたいだから、wcは最適じゃないな。
0940938
2008/02/11(月) 18:20:420941名無しさん@お腹いっぱい。
2008/02/11(月) 18:30:05>>920 欲嫁。質問者はwc使いたかったけど使えなかったから仕方なくawkまたはperlで
ということだから、>>923 のwcが最適だね。
0942名無しさん@お腹いっぱい。
2008/02/11(月) 18:35:26勝手に想像するのは良くないよ。
>>924欲嫁
0943名無しさん@お腹いっぱい。
2008/02/11(月) 18:37:51> コントロールコードが入ってたりしてwcが使えないのが原因だったらどうするの?
そんなのありえるの? 具体的には?
0944名無しさん@お腹いっぱい。
2008/02/11(月) 18:38:27コントロールコードが入っていても LANG=C なら wcは無問題。
実際に試してから言おうね。
0945名無しさん@お腹いっぱい。
2008/02/11(月) 18:41:01全てのコントロールコードで試したの?
そのファイルをくれないかな。
0946名無しさん@お腹いっぱい。
2008/02/11(月) 18:44:45墓穴ほってるよww
そんなの、たとえば
dd if=/dev/random bs=1024k count=1 | LANG=C wc -l
で検証できる。ファイル用意する必要なし。
0947名無しさん@お腹いっぱい。
2008/02/11(月) 18:47:290948945
2008/02/11(月) 18:47:55君が、
> 実際に試してから言おうね。
って言ったんじゃないの?
randomで出したところで、全てのコントロールコードは試してないよね。
実際に試してないのに言っちゃったの?
0950名無しさん@お腹いっぱい。
2008/02/11(月) 18:51:270951名無しさん@お腹いっぱい。
2008/02/11(月) 18:52:24コントロールコードって、全部で32個(DELも入れると33個か?)だけって知ってる?
0952945
2008/02/11(月) 18:52:59tmp]$ cat tmp_r | LANG=C wc -l
0
tmp]$ cat tmp_r | perl -e 'while(<>){} print "$.\n"'
1
tmp]$ cat tmp_r | awk 'END{print NR}'
1
tmp]$ cat tmp_r | perl -lne 'END{print$.}'
1
ものすごい影響されてるが…。
0953名無しさん@お腹いっぱい。
2008/02/11(月) 18:53:370954名無しさん@お腹いっぱい。
2008/02/11(月) 18:55:43ワロタwwwwww
>>951は自分の発言すら試してなかったのか?w
それともたまたまうまくいっただけか
0955名無しさん@お腹いっぱい。
2008/02/11(月) 19:00:40/dev/randomじゃなくて /dev/urandomでやるべき。
/dev/randomを ddで吸い出すと、十分なエントロピーがなくて
ほとんどがゼロで埋まってるものと思われ。
それとは別に、wc -lでは、最後の改行がない行を数えないが、
awk 'END{print NR}'では数えるから、行数が1ずれる。
その点は、>>945 が最初指摘していたコントロールコードの問題とは違うので、
勘違いしないように。
0956名無しさん@お腹いっぱい。
2008/02/11(月) 19:04:10だいたい、1MBも乱数で取ったのに '\n' が1つしかない時点で
その実験自体がおかしいことに気づけww 乱数になってない。
0957名無しさん@お腹いっぱい。
2008/02/11(月) 19:06:040958名無しさん@お腹いっぱい。
2008/02/11(月) 19:06:49しかもファイルがおかしいにしても、今回はwcが扱えないことはわかったでしょ。
0959名無しさん@お腹いっぱい。
2008/02/11(月) 19:06:53ということなら、この場合やはり LANG=C wc -l の計数表示が正しいということになる。
awk 'END{print NR}' では、最後の不完全な行までカウントしてしまう。
そういう意味で、やはり LANG=C wc -l が最適ということになるな。
0960名無しさん@お腹いっぱい。
2008/02/11(月) 19:09:54$ echo -n a > file
$ LANG=C wc -l < file
0
$ awk 'END{print NR}' < file
1
ということだ。LANG=C wc -l の方が正しいな。
0961名無しさん@お腹いっぱい。
2008/02/11(月) 19:10:33最適とか言ってたのに残念。
0962名無しさん@お腹いっぱい。
2008/02/11(月) 19:12:19違うだろ
改行がある限り2行
0963名無しさん@お腹いっぱい。
2008/02/11(月) 19:13:10>>914 は wcを使わないという時点では最適だろ。
で、あとでwcを使わなかった理由が質問者から示されたから、
それならLANG=Cでということで、wcが最適になっただけのこと。
0964名無しさん@お腹いっぱい。
2008/02/11(月) 19:13:51wcのmanではああなっているから
0965名無しさん@お腹いっぱい。
2008/02/11(月) 19:14:30次々に新しい解を出すのが>>914の言う最適な解なんだから。
0966名無しさん@お腹いっぱい。
2008/02/11(月) 19:15:260967名無しさん@お腹いっぱい。
2008/02/11(月) 19:15:500968名無しさん@お腹いっぱい。
2008/02/11(月) 19:16:200969名無しさん@お腹いっぱい。
2008/02/11(月) 19:18:130970名無しさん@お腹いっぱい。
2008/02/11(月) 19:19:330971名無しさん@お腹いっぱい。
2008/02/11(月) 19:25:06http://pc11.2ch.net/test/read.cgi/unix/1202725267/
0972名無しさん@お腹いっぱい。
2008/02/11(月) 20:25:210973名無しさん@お腹いっぱい。
2008/02/11(月) 21:55:140974名無しさん@お腹いっぱい。
2008/02/11(月) 22:31:36シェルならシェルだけでやれ。
0975名無しさん@お腹いっぱい。
2008/02/11(月) 22:52:08↓
n=0; while read dummy; do ((n++)); done < file ; echo $n
0976名無しさん@お腹いっぱい。
2008/02/11(月) 23:06:41bash依存。失格。
0977名無しさん@お腹いっぱい。
2008/02/11(月) 23:33:04シェルだけということで、exprすら使わないようにしたよ
set --; while read dummy; do set "$@" a; done < file ; echo $#
0978名無しさん@お腹いっぱい。
2008/02/11(月) 23:46:18set -- はシェル実装依存。shift $# の方が確実だな。
レス数が950を超えています。1000を超えると書き込みができなくなります。