1 :
login:Penguin :
2007/07/10(火) 23:17:13 ID:qGthZdME
2 :
login:Penguin :2007/07/10(火) 23:18:45 ID:qGthZdME
3 :
login:Penguin :2007/07/10(火) 23:20:21 ID:qGthZdME
EUCで入力された文字列をShiftJISに置き換える方法ってありませんか?
5 :
login:Penguin :2007/07/14(土) 11:17:49 ID:29sQfd47
6 :
login:Penguin :2007/07/14(土) 22:31:28 ID:Lb+uQxni
シェルスクリプトの引数にワイルドカードを渡すと、 該当するファイルがファイルシステム上にある場合はそのファイルが変わりに 引数として渡されるみたいですが、ワイルドカード自体を取得したいのです。 何か方法はないでしょうか? ちなみにダブルクォーテーションをつければ展開されないのは知っていますが、面倒で。。 (例) $ test.sh *.txt $ echo $1 とするとカレントにあるXXX.txtを表示するのではなく 「*.txt」を表示したいのです。
>>6 呼ばれるスクリプトの側でなんとかしたいってことなら
無理だよ。
8 :
login:Penguin :2007/07/14(土) 23:13:50 ID:Lb+uQxni
>>7 そんな気はしていましたが、そうですか。。
残念です。
呼ぶシェル側でなんとかするなら $ set -o noglob $ test.sh *.txt とか。
10 :
login:Penguin :2007/07/15(日) 05:00:56 ID:OzInTFfn
>>6 test.sh '*.txt'
(シングルコーテーションならてんかいされないはず)
12 :
login:Penguin :2007/07/15(日) 12:37:56 ID:llPpP8sT
>>8 よく仕様がわからんが、スクリプトの多段階呼び出しで展開されたくないんだったら、
$ test.sh @.txt
みたいに、擬似ワイルドカード指定指定しておいて
使ううときに、
fs=`eco $1 | sed 's/@/*/'`
echo $fs
14 :
login:Penguin :2007/07/16(月) 12:28:16 ID:MK2VLXxK
すみませんちょっとヘルぽ /homeの中にある複数のファイル・ディレクトリーをrm -rf したいのですが /home/hogeとlost+found だけは消したくないので 何とかそれ以外を消す方法をご教示頂きたいのですが おしえてたもれ
>14 shell script関係ないが、lsでリストとって、リストから削除したくないファイル・ディレクトリを削除し、 その後 rm -rf `cat 〜` なんかするのが間違いなくて確実だとおもー。
>>14 bashだったら、GLOBIGNORE="hoge:lost+found" に賭けてみたまえ
/home/hogeとlost+foundに書き込み禁止属性をつけてから一気に rm -rf その後戻せばいいのでわ
awk の出力をコマンドとして実行したいでつ。 どうやればいいでつか?
awk ... | sh
>>5 遅くなりましたが、ありがとうございます。
試してみたいと思います。
あ、
>>15 もdクスです
その方法でやってみたいと思います
25 :
login:Penguin :2007/07/20(金) 01:54:45 ID:bZea7ZdA
スクリプトに実行時間制限を設けたいんですが、いい方法はないですか? 厳密さは求めていません。暴走防止程度です。 (因みにLinux初心者のプログラマです、あまり複雑な概念は未だ理解できていないと思います。 今は大体こんな感じでやろうとしています、 (sleep 10; kill $$)& 時間制限を設けたいコマンド これだと、時間内に終了しなかったとき、スクリプトのみ終了し、実際に終了させたいコマンドは生き残ります。 時間内に終了したときにkillさせないために最後に kill `jobs -p` すると「(sleep 10; kill $$)&」は終了しますが、sleepだけが残ります(自然消滅はする だからといって kill 0 とするとこのスクリプトの呼び出し元まで死んでしまいます。 プロセスを kill するときに、その子も殺せればいいんですが如何でしょうか。
>>25 ps --ppid とか pstree -p とかで
子の pid を調べれば
kill できると思う。
ulimit -tはだめ? CPU使った時間になっちゃうけど。
killのman見ればprocess groupを殺す方法書いてあるだろうに。
>>26 pstree -p からpidだけ取り出す方法が分かりません。
ps --ppid の再起で殺すようにしてみましたが思い通り動いてくれません。
間違えている可能性は大いにありますが。
>>27 CPU時間でも構いません。寧ろその方が良いかもしれません。
ありがとうございます。調べてみます。
>>28 でしょうね。
>>29 % pstree -p 親PID
親cmd(親PID)-+-子cmd(子PID)
と表示されるんだから、
% pstree -p 親PID | perl -nle '/親PID\)[^\(]+\((\d+)\)/ && print $1'
子PID
とならないかな?awkでもsplitを使えば同じようにできると思う。
そもそもperl使うならpstreeもkillも内部で呼び出せば済むけど。
それ以前にプロセスをアレコレする関数かmodがあるんだろうな...
31 :
login:Penguin :2007/08/04(土) 23:01:23 ID:prsNz29A
awkの区切り文字に'|'を指定するにはどうすればいいですか awk -F'|' ではパイプとみなされてしまいます
やってみた。 % echo 'a|b|c' | gawk -F'|' '{print $2}' b
非rootのアカウントからシェルを実行して 規定のHDDをマウントしたいと思っています。 問題は非rootなのでmountの実行権が無い点です。 sudo は設定方法がよく分からないので、 もちょっと簡単なやり方ないかと探しているのですが 何かよい方法ないもんでしょうか? スクリプトの中でrootでログインして、そのまま 実行してほしい。(passwd入力はOK) ちなみにSuSE 10.2を使ってます。
>>34 sudo の設定くらいわかれ。
そんなに難しくないよ。
sudo -u USER /dev/hd ... いかん、だるい。
>>34 /etc/fstabの規定のHDDのエントリ内に user というオプションを書いておけば、
そこは一般ユーザでもmount/unmountできるようになる。
もちろんこの場合、mountコマンド自体のxビットは、一般ユーザが実行できるように
設定する必要がある。
38 :
login:Penguin :2007/08/06(月) 22:17:00 ID:LTHEPNn8
テキストファイルが2つあると仮定して、(a.log、b.txt) a.logはソフトのログファイル。 b.txtはerror、badなどの複数行の文字列が入っています。 で、a.logに対して、b.txtの中を一行ずつgrepさせたいときはどうすればいいの? ↓のようにしたい。b.txtは50行程度の行数があるとする。 grep -i error a.log grep -i bad a.log grep -i ...... a.log などをしたい。
$ cat b.txt | while read keyword; do grep -i "$keyword" a.log; done bshしか知らね。
grep -f b.txt a.log
41 :
login:Penguin :2007/08/09(木) 03:57:05 ID:q+NJZ5PJ
スクリプトの中から、 スクリプト自身のパスを知るにはどうすればいいですか?
echo $0
うわ。あさたくの文章、久しぶりに見た。
こんなの作った。 #!/bin/sh for i in "$@" do a="$(echo $i | nkf -w)" mv $i $a done convmv は元の文字コードを指定しなきゃならないのが面倒なので。 良かったらどぞ。
47 :
46 :2007/08/10(金) 18:44:30 ID:hRezB52r
書き忘れたので一応。 ./myconvmv.sh * とかで使える。
48 :
38 :2007/08/11(土) 02:02:30 ID:h4twNLWe
・ファイルを指定フォルダ内へコピー ・同名ファイルが存在する場合は、 既に存在するファイル名を「ファイル名.1」へ変更し、 既にファイル名.1が存在しているのであれば、それをさらにファイル名.2へ変更し、、、(繰り返し) というコピーシェルスクリプトがほしいんですが、 簡単な記述方法などがあったらおながいします。
51 :
49 :2007/08/15(水) 18:30:05 ID:oxw3opBU
シェルスクリプト自体ほとんど作成経験がないので、 mv とかのオプションでそんな機能ないかな〜と 調べている程度の状態です。 -------------------------------------------------- ・同名ファイルが存在する場合は、 既に存在するファイル名を「ファイル名.1」へ変更し、 既にファイル名.1が存在しているのであれば、それをさらにファイル名.2へ変更し、、、(繰り返し) -------------------------------------------------- この部分を数行で教えていただけるとありがたいでつ。 ループ処理が必要になるのはなんとなく予想がつくのですが、、、
>>51 ファイルが何番まであるかを先にチェックして
番号大きい方から順に mv してくのが楽かな。
[ とか expr 使え。
番号をrotateすることに大した意味がないことに気付き、--backupオプションとかで安易に済ます。 そんな自堕落な道を私は選びました。
ディレクトリにあるすべての*.cファイルを 全部*.cppにするにはどういう風に書いたらよいのでしょうか? mv *.c *.cpp としてみましたがだめでした どなたかお知恵を...
rename コマンドで出来そうな気がする。
まあそうだけど。シェルスクリプトスレであることだし for f in *.c; do mv "$f" "${f}pp"; done
flashの動画をダウンロードできる シェルスクリプトある?
kurekure厨
>>58 普通にwgetでダウンロードすればいいだけでは?
youtubeから簡単に落としたいとかであればyoutube-dlとかが便利。
すごく基本的なことなんだろうけど、 いくつかのディレクトリの中にあるファイルのそれぞれの名前を変数に入れたいんだけど、 files=ls dir* | sort for i in files do done みたいなことは出来ませんか? 要するに標準出力する内容を変数に入れたいだけなんだけど。
>>62 理解できました。どうもありがとりんこです。
ファイル一覧だと長大になって溢れるので ls ... | sort | while read i; do echo $i; done とかも定番。
for i in dir* do done sortを挟むのは良くわからんが、単純にこんなんで済む話じゃね?
find DIR -exec (ここで好きなことやれ) \;
/home/200708/1200・・・1300・・・1400/と100刻み1800までディレクトリーがあるとして A.PDFとかファイルが格納されてて 0KB〜150MBなら 「ne-yo」 500〜600MBなら 「OK」 とfile.txtを出力したいのでつが・・・・・ if,thenの繰り返ししかないでしょうかね?
なんのバイト数? そのディレクトリ内ファイルの総和?
こんな感じ? $ du -s * | awk '{ print $2," ", ($1 > 10000 ? "ne-yo" : "OK") }' 条件文のところは自分で書き換えてくれ。
なるほどdu か。。。。と、>68とはちがう漏れ様が感心しますたーw
du 以外だと例えば何が?
すいません、初心者の質問です。 # time = 0.1000000000000000E-01 0 0.0000000000000000E+00 0.9108669739482692E-01 0.2058642824721793E-04 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 1 0.3175362884490020E+01 0.5150471547462544E+01 0.2241689225773500E-03 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 # time = 0.2000000000000000E-01 0 0.0000000000000000E+00 0.9108669739482692E-01 0.8246429583076927E-04 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 1 0.3176583636040012E+01 0.5152080697165893E+01 0.8959185481550624E-03 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 2 0.1132676183258557E+01 0.5482797684864557E+01 0.1300893227929982E-03 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 # time = 0.3000000000000000E-01 0 0.0000000000000000E+00 0.9108669739482692E-01 0.1858117181080544E-03 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 1 0.3178027531327324E+01 0.5153971284976635E+01 0.2013740280923297E-02 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 0.0000000000000000E+00 という形式で出力されるデータで、# time = 0.2000000000000000E-01からはじまって、# time = 0.3000000000000000E-01の手前までを切り出すスクリプトを教えてもらえないでしょうか。できればawk(perlかrubyでも構いません)で教えていただけるとありがたいです。
cat /tmp/test.txt | gawk '/^# time = 0\.3/{exit} /^# time = 0\.2/{flag=1} flag==1 { str = str$0"\n" } END{print str}' こんな漢字か。酔っているので合っているのかどうだか。 0.000000...の部分は付け足してクレイ
cat /tmp/test.txt | gawk '/^# time = 0\.20+E-01 *$/,/^ *$/ {print $0}' あと仕様の意味が、#time=...から始まる一ブロックだけ出す(空行が出たらオシマイ) という意味ならもっと単純になる
>>70 すげーまさにOK!ですた!
awk の ? と : の使い方に感動
>>71-72 ls -lh とかでやろうとしたのは漏れ様も同じww
79 :
login:Penguin :2007/08/29(水) 22:41:00 ID:4pERO676
再帰的に2つのディレクトリをdiffしたいのですが存在するかしないか と違うファイルだということだけわかればいいので わかりやすく比較する方法はありませんか? diffのマニュアルみてもそれらしいのはないようで
>>79 diff -rq dir1 dir2 ではだめなの?
む、-qで違いが分かるのか orz
デジャヴなんだが俺だけか?
84 :
login:Penguin :2007/08/30(木) 01:02:14 ID:F11xsKF5
パッケージようなのバージョンを比較する方法がわかりません。 イメージ的には、こんなことがしたいんです↓ ---------------------------------- hoge="1.3.37" foo="1.11.12" if [ "$hoge" -gt "$foo" ]; then echo "OK" else echo "NG" fi ---------------------------------- これだと、以下のようjにエラーになってしまいます。。。。 [: 1.3.37: bad number NG
hoge="1.3.37" foo="1.11.12" hoge=`echo $hoge | gawk -F. '{print (($1*100+$2)*100)+$3}'` foo=`echo $foo | gawk -F. '{print (($1*100+$2)*100)+$3}'` if [ "$hoge" -gt "$foo" ]; then echo "OK" else echo "NG" fi ピリオド区切りの数が固定(この場合は3) ピリオド内の桁数が固定(この場合は1-2桁) という条件付だけど。これらが不定なら、$1,$2,$3...を$iにして、 NFまでループさせればいいと思う
そのバージョン表記の書式にもよるけど、 oldv=1.11.12 newv=1.3.37 として if [ `echo $newv -gt $oldv | sed 's/\.//g'` ]; then echo OK; fi もしくは、 if [ `echo $newv.$oldv | tr . ' ' | xargs printf "%d%.3d%.3d -gt %d%.3d%.3d"` ]; then echo OK fi あたりでどうかな。
>>84 rpmver ってのがある。
$ rpmver -v 1.3.37 1.11.12
RPM version 1.3.37 is lesser than version 1.11.12.
Vine,VineSeed の RPMS.main SRPMS.main にある。
他のディストリは知らないけど
パッケージが用意されてるかもしれない。
$ which rpmver rpmver not found うえーん。。。
>>84 Linux板だからbashでもいいよね。
#!/bin/bash
v2n () {
local IFS=.
set $1
echo -n $(($1 * 1000000 + $2 * 1000 + $3))
}
hoge="1.3.37"
foo="1.11.12"
echo $(v2n $hoge) $(v2n $foo)
if [ $(v2n $hoge) -gt $(v2n $foo) ]; then
echo "OK"
else
echo "NG"
fi
添削してぇ
90 :
73ですが :2007/09/01(土) 15:15:18 ID:uwRTp3HZ
>>76 おくればせながらありがとうございました。
91 :
73ですが :2007/09/01(土) 22:39:45 ID:uwRTp3HZ
>>76 仕様はおっしゃるとおりです。
その際のスクリプトも教えてくだされば幸いです。
なお、他のスクリプトは現在のところ動作していません。わたしの知識不足なのだろうと思うのでもうすこし調べてみます。
#0は補ってはあるのですが...
ついでといってはなんですが、awkの本でおすすめの本などありましたら教えていただけませんか?
>>91 オライリーの sed & awk
てかawkの本なんて何冊もないって。
本命 足立さんの訳してる awk 本 大穴 awk 256 本
awk256倍はDOS時代からある骨董本で内容もふざけまくっているが、初心者が
「正規表現」「連想配列」という二つのキモを学習するにふさわしい内容。
読み終わったあとも、巻末の関数一覧がずっと使える。未だに刷を重ねてるけど
愛用者もおおいんじゃない?
大して御本家3人の書いたawk本は内容が高度な上に散発的で、調べたいことが
すぐに出てこなくて使いにくい
>>91 >>76 のがその仕様のスクリプトなんだけど。うまく動かないのは、スペースとかが
ちゃんとコピペされてないからなんじゃないの?
95 :
73ですが :2007/09/02(日) 21:37:03 ID:71yMDj2y
>>92-94 本の紹介ありがとうございました。
>>94 気づきませんでした。すいません。スペースの問題などを再確認してみます。
またなにかあったら伺うかもしれません。よろしくおねがいします。
DOS時代ってのはいつまでを言うんだ?
awk 256 本の話の文脈としては、MS-DOS上のawk実装の時代かな
>>97 そう。今の版じゃ改訂されてるのかもしれないが、俺の持ってるのだと
gawkをDOSに移植したjgawkとかいうのを下敷きにしていて、中には486を乗せたキューハチだと
スクリプトの速度が向上したとか、パイプの実行速度が遅いのはUNIXみたいな本物のパイプじゃないからとか、
そんな話題が満載
MS-DOS上のawk実装の時代ってのはいつを言うんだ?
100 :
>>84 :2007/09/04(火) 00:34:58 ID:3rxVdbk9
おくらばせながら、ありがとうございますm(_ _)m
指定されたディレクトリ以下にあるディレクトリ一覧を返してくれるコマンドはありませんか? /data/ をTOPディレクトリとしますと /data/hoge/ /data/piyo/ /data/moge/ 等が帰ってくるコマンドです。で、この際 /data/hoge/direc/ みたいに、TOPディレクトリの 孫ディレクトリ以下は返さないで欲しいんです。TOPディレクトリの子ディレクトリのみを 返して欲しいのです。そして for TARG in command; do 処理; done のように for文で1つ1つのディレクトリを処理したいのです。 それからもう1つ、指定されたディレクトリ以下の子ディレクトリの数を返すには ls -l /data/ | grep ^d | wc -l でいいのでしょうか?ディレクトリだと ls -l した時に必ず最初が dから始まるので これでディレクトリのみがマッチして、後はwcでその行数を数えればいいかと思っているのですが 今の所これでちゃんと動作していますが、不具合が発生するようなケースは想定されますか? ディレクトリの数も孫ディレクトリ以下は数えません(再帰処理しない)。 昨日 basename と言う便利なコマンドを知った程度のレベルの人間ですので awk や sed 等の難しいコマンドはなるべく使わずに実現したいのですが、出来ませんかねぇ? 宜しくお願い致します。
/data/.x/ とかも考慮したいなら find で。
>>102 あっちゃー・・・・そんな簡単なコマンドでこんな素晴らしい出力が得られるんですか!
LinuxのCUIって本当に高機能ですね・・・素晴らしいです。本当にありがとうございます。
ls -l /data/ | grep ^d | wc -l
ってやるより
ls -ld /data/*/ | grep ^d | wc -l
ってやる方が良いのでしょうか?どんなファイルやディレクトリがあっても確実に動作するような
書き方をしたいのですが・・・。
属性が見えて良ければ ls -d /data/*|grep "^d"
-l忘れてた
>>104 > ls -ld /data/*/ | grep ^d | wc -l
なんで grep するんだ?
ls -1d /data/*/ /data/.*/ /data/../ もヒットするのが難点だけどな。ってかあれだ。つ「man ls」
>>101 求めてることが出来たのであればどんなコマンドでもいいけど
find の使い方も知っておいたほうがいいと思う。
> 不具合が発生するようなケースは想定されますか?
> ディレクトリだと ls -l した時に必ず最初が dから始まる
ディレクトリへのシンボリックリンクがあった場合の扱いをどうするか。
さらに言えばリンクの対象がどこにあるか
ln -s /data/A /data/B と ln -s /tmp/C /data/B の違いとか。
ls -Ap /data | grep /$
でよかったか。
>>109 > find の使い方も知っておいたほうがいいと思う。
同意。
なのに誰もfindを使った答を書かないのはなんでだw 101への課題?
んじゃ、俺の回答に採点してくれ find /data -type d -maxdepth 1
114 :
109 :2007/09/07(金) 17:14:59 ID:NgwMB5/h
>>113 二ヶ所で減点。
1) find の出力に TOPディレクトリ(/data 自身)も含まれてる。
>>101 を読むとTOPディレクトリそのものは不要だと思う。
2) GNU find version 4.2.27 だと -maxdepth の位置で warning が出た。
find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.
>>114 なるほど。非常に参考になった。
模範解答を頼む。
find /data -mindepth 1 -maxdepth 1 -type d -exec ... shopt -s nullglob for i in /data/{,.{[!.],.?}}*/ do ... こんなんでいかが
cat hoge | awk に似ている。
>>116 OK。これでどうだ?
find /home/* -maxdepth 0 -type d
>>117 でもう答え出てるじゃん。
>>119 /home/.xxx/ とかが出ない。
* 使うなら find 使う意味ない。
>120 >* 使うなら find 使う意味ない。 上下別々の回答なんじゃないの?
bashrc の書き方もこのスレでいいですか?
#!/bin/sh -f ls *.dat > list.txt なぜか走らん。
>>123 子プロセスとして(?)起動するシェルに -f が渡らないんだと思う。
/bin/sh -f hoge.sh とか
あらかじめ /bin/sh -f で起動したシェルで
./hoge.sh みたいにすると
-f が有効になる。
>>124 エラーで *.dat: ファイルもディレクトリもありません とでる
ワイルドカードが原因かと思ったけど、hoge*でも同様のエラー
シェルにしたら走らず、コマンドラインで直接投げたら走る
なんでだろ
126 :
124 :2007/09/12(水) 17:27:12 ID:A49nKXNq
>>125 /bin/sh -f の -f がどんな意味かわかってる?
あと、シェルとシェルスクリプトはちゃんと区別したほうがいい。
!/bin/cshで走ったわ コンソールがcshだった
128 :
login:Penguin :2007/09/12(水) 20:01:20 ID:9HkBr7tD
複数のpasswdファイル(passwd_A、passwd_B)を結合して、同じユーザ名があった場合 passwd_Aのものだけを残すというようなことをしたいのですがどうすればよいでしょうか?
129 :
login:Penguin :2007/09/12(水) 20:12:55 ID:nfcPR4Gc
いったんファイルを結合する 一行ずつ上から順に読んでパスワードファイルに書き込む 書き込んだらそのユーザー名を別ファイルに書き出す その別ファイルにユーザー名がないことを確認してから パスワードファイルに書き込めばよい
while read t ;do if [ "`grep ^${t%%:*}: passwd_A`" ];then continue else echo $t >>passwd_A fi done <passwd_B
んだば awk で。 awk -F: '{ t[$1] = $0; } END { for (e in t) print t[e]; }' passwd_B passwd_A
awk -F: '!($1 in t){print;t[$1]=1;}' passwd_A passwd_B
133 :
login:Penguin :2007/09/13(木) 21:53:28 ID:8j1+julM
aaa.txtの中身 20070109,170000,170000,167000,170000,4 20070110,168000,168000,168000,168000,10 20070115,171000,171000,163000,169000,500 を 2007/01/09,170000,170000,167000,170000 2007/01/10,168000,168000,168000,168000 2007/01/15,171000,171000,163000,169000 のように YYYY/MM/DDと表示を変更する 最後の,からあとを削除してbbb.txtとして出力したいと思っています どのようにすればいいものでしょうか 4文字目と5文字目の間に/を挿入するということがsedでできなくて悩んでおります よろしくお願いいたします
cat /tmp/aaa.txt | gawk -F, '{printf("%04d/%02d/%02d,%s,%s,%s,%s\n", substr($0,1,4),substr($0,5,2),substr($0,7,2),$2,$3,$4,$5)}' > bbb.txt
\(\)でグルーピング、\{\}でマッチする回数の指定。 グルーピングしたパターンは後で\1,\2で参照出来る。 \を忘れるなよ。
あ、ごめん、>135はGNU sedの話
>>134 ありがとうございます
gwakというのも勉強してみようと思います
>>134 manを見てみたら いろんなところで使用できそうです
本当にありがとう
ある XXX っていう名前を含んだプロセスを全て殺したい時、 ps aux | grep XXX | grep -v grep | awk '{print $2}' | kill ではだめなのに ps aux | grep XXX | grep -v grep | awk '{print $2}' | xargs kill ではOKなのはなぜですか?
>>141 kill って標準入力を受け付けないんじゃない。
ところで pkill XXX じゃだめなの?
>>142 そうなのかなと思って
for p in $(ps aux | grep XXX | grep -v grep | awk '{print $2}'); do
kill "$p"
done
ってのもやってみたんですが、だめだったんですよ。
スクリプトでタイマー作れませんか? 一定間隔ごとに単純にコマンド出すだけじゃなくて 処理ごとに条件分岐してタイマーを止めたりコマンドが成功 するまで繰り返したりしたいのですが
>>144 sleep使って、て程度で良いなら作れるような気しかしないんだけど、具体的にどうしたいのか書いたのが良いと思うぞ。
>>143 だめってどうダメだったのかわからんと。
for p in $(ps aux | grep smbd | grep -v grep | awk '{print $2}'); do
"kill "$p"
done
これでやったらちゃんと動いたよ。スクリプトの問題じゃなくて
単に権限がなくてkillできなかっただけでは?
>>147 さっきやってみたら出来た。。。
間違って mplayer を40個くらい起動してしまって、そこでそのスクリプトを
叩いたつもりだったんだけど、焦ってなんか間違ってたのかもしれない。
とりあえず今度からは xargs のほうを使うようにするよ。
いやだからpkill使えって
command | command みたいな 例 cat hoge.txt | grep piyo 書き方があるじゃないですか? cat hoge.txt で出力される標準出力をパイプかませて その出力内容に対して grep piyo をかける と言うような。 これと xargs ってコマンドがあるじゃないですか?その違いがよく分からないのですが・・。 cat hoge.txt | xargs grep piyo みたいな?
「cat hoge.txt | xargs grep piyo」=「grep piyo `cat hoge.txt`」
>>151 ほぉほぉ・・・・
cat hoge.txt | xargs grep piyo が
grep piyo `cat hoge.txt`
と同じならば
cat hoge.txt | grep piyo
は
grep piyo hoge.txt
ん?なんか混乱してきた・・・イマイチはっきりと分からない・・・
argっていうぐらいだから引数に展開してくれるのだろ その場合hoge.txtの中身はファイル名でないとだめ
もう分かってるかもしれないけど、xargsは標準入力をコマンドライン引数に変換するだけ。 echo 'file1 file2 hoge' | xargs rm ↓ rm file1 file2 hoge
むぅ・・・ echo `file1 file2 hoge` | xargs rm が rm file1 file2 hoge となるならば echo `file1 file2 hoge` | rm は どう展開されるんですか? すみません、ほんと頭弱くて。
引数と標準入出力の区別がまだついてなくて、全部「入力」として ごちゃまぜの段階でしょ?まずそれを考えてみるんだ>155
>>154 の echo 'file1 file2 hoge' | xargs rm
>>155 の echo `file1 file2 hoge` | xargs rm
どこが違うか理解してからにしろ
こんな初歩の初歩みたいなことに、どうしてそんなに高飛車になれるんだ。
初歩の初歩は自力で身に付けてから来てくれよ。
タコタコ
convmv -r -f sjis -t utf-8 * --notest で、再帰的にカレントディレクトリ以下のファイル、ディレクトリ全てに対して sjisからutf-8に変換をかけるコマンドを打ったのですが、sjisとeuc-jpが混在していて convmvの仕様だと 1ファイルでも -f で指定した文字コード以外の文字コードのファイルが 存在した場合はそこで全ての変換処理が実行されなくなってしまいます。 違う文字コードの場合は除外して残りを全て処理してくれるオプションは無いかとman convmv を読んで見ましたが、無いようです。 仕方が無いので、これをシェルスクリプトで実現したいと思います。 実際にやりたいコマンドは convmv -r -f sjis -t utf-8 /data/* --notest で、これで変換できないファイルは convmv -r -f euc-jp -t utf-8 /data/* --notest で、全てのeuc-jpとsjisをutf-8にする事です。 for TARG in `find /data | nkf -w8` do convmv -f sjis -t utf-8 ${TARG} --notest convmv -f euc-jp -t utf-8 ${TARG} --notest done これで、sjisのファイルだろうがeuc-jpのファイルだろうが必ずutf-8になると思われますが いけると思いますか? | nkf -w8 をかませているのは、こうしないとターミナルで見た限りだと 文字化けしたファイル名でそのまま表示されるので、これだと多分ファイルにアクセスできないだろう との配慮から、ちゃんとしたファイル名で見えるようにしたつもりです。
>>162 http://hp.vector.co.jp/authors/VA000501/ これですよね?
しかしこれはconvmvとは全く別物のようです。
convmv => ファイル"名"の文字コードを変換する ←私はコレが必要
qkc => テキストファイルの"中身"の文字コードを変換する ←これは違う・・・
なので使えないみたいです。
ちなみに
>>161 で書いたスクリプトを実際に動かしてみた所、LinuxサーバのCPU使用率が
100%になって固まっちゃいました。無限ループをしているかファイル名取得に失敗しているか
よく分かりませんがダメでしたOTL
よくわからんのだが、nkf -gで文字コードの判別してやりゃ良いんじゃねぇの?
while ! convmv -f sjis -t utf-8 -r /data --notest ; do convmv -f euc-jp -t utf-8 -r /data --notest done なんか、どうよ? 文字コード判定がいまいちなのか誤認してくれたりするので --notest とって、ざっと眺めてからやる事を推奨。
--notest 外して試してみればーじゃん。
echo $RANDOM で結果に乱数を返したいんですけど、 0〜9までの一桁の結果のみ返したい場合の指定方法とかってありますか?
$RANDOM % 10
>>164 nkf はファイル"名"ではなくて、ファイルの"中身"についての文字コードを
調べるんですよね?テキストファイルに対して実行するとShift-JISと言う出力が得られ、
.exeファイル等に実行すると Binary と表示されました。
なので、これは全く別物です。
>>165 おお・・・
それはつまり
convmv -f sjis -t utf-8 -r /data --notest
で、元ファイルがsjisじゃなかったときは元ファイルがeuc-jpとして処理を繰り返すんですね。
しかしその場合、仮に1つでも元ファイルがsjisだった場合は?と言うか・・・
それ実行してみたのですが、無限ループに陥りました。何度も同じファイルを判定して
これsjisじゃないよ〜って帰ってきます。
よくよく考えると -r /data で既に再帰的に繰り返す処理なのに、それをさらにwhileでループさせて
いるんですよね。二重ループ状態ですか。
while ! convmv -f sjis -t utf-8 -r /data --notest ; do
これで、とりあえず convmv -f sjis -t utf-8 -r /data --notest が実行される
→実行された時に1つでも違うファイルが存在していてエラー
→convmv -f euc-jp -t utf-8 -r /data --notest が実行される
→実行された時に1つでも違うファイルが存在していてエラー
またconvmv -f sjis -t utf-8 -r /data --notest が、最初にエラーで止まったファイルも含んで
最初から実行される>当然また同じファイルでエラーを起こす>convmv -f euc-jp -t utf-8 -r /data --notest が
また実行されてまたこれも最初から処理してしまう>これを永遠に繰り返して無限ループに陥る。
ダメみたいですOTL
>>166 --notestはずして試してみてますが、エラーで弾かれます。
>>169 いや、ファイル名のコードをnkfで調べりゃいいじゃん、てことだったんだけど。
念のため。 for T in `ls ~` do C=`echo "$T" | nkf -g` echo $T,$C done ファイル名の文字コードを調べてると思うんだが。
>>170-171 違うと思うなぁ・・・。
>>171 のスクリプト実行してみたけど
これは ls ~ で表示されるファイル名リスト全体、、、そうだなぁ、、例えば
a.txt
b.mp3
c.tar
d.gz
e.tar.gz
とか日本語も含むファイル名全てが列挙されると思うけど、それらのファイル名リスト
全体を1つのテキストファイルとみなして、テキストファイルの中身(つまりファイル名が列挙されてる)
に対して文字コード変換をかけた結果を echo で出力しているんじゃないですか?
だからnkf は ファイル"名"の文字コードを調べるんじゃなくて、あくまでもテキストファイルの中身
の文字コードを調べるんだと思いますが。それこそqkcみたいな動作?
convmvは全くそれとは性格が異なる物だと思いますが、、非常にこの辺ややこしい・・・。
なんでこんなに全然わかってないのに自信満々なのだろうか
>>161 >>164 の意見を採用して書いてみた。
for を while に変えたのは俺の趣味。
find /data | while read TARG ; do
File=$( nkf -g <<< "$TARG" )
case "$File" in
Shift_JIS*) Code=sjis ;;
EUC-JP*) Code=euc-jp ;;
UTF-8*) continue ;;
esac
echo "$File: Convert to $Code" ## お好みで
convmv -f "$Code" -t utf-8 "$TARG" --notest
done
ファイル名程度の短い文字列だと nkf の文字コード判定の
精度はあまりよくないが、やらないよりはマシだろう。
文字コードが違うファイル名が混在しているディレクトリって。 どうしてそうなったかが気になる
ローカルで作ってSambaで作ってWebDAVあたりで作ってとやってしまうと 起きるな?>混在。 後はデータ中の文字列を元にファイルを作ったりすると、うっかり 混在状態になったり。
>>172 >>173 と同意なんだが、想像の斜め上な方向に理解してるのね。と理解。
なして
>>171 を実行してみた上で
>>172 になるのかわからん。。。
つまり、
>>172 としては、「a.txt あ.txt い.txt」の3つのファイルがあると、
a.txt, ASCII
あ.txt,UTF-8(とか)
い.txt,EUC-JP(とか)
てならず、
a.txt,BINARY
あ.txt,BINARY
い.txt,BINARY
となった、てこと?
>>174 半角カナ使ってなけりゃ、それなりの精度なんじゃねぇかと思うんだけど、どうだろ。
>半角カナ使ってなけりゃ、〜 ↑勘違い。すま。
>>173 すみませんOTL。
>>174 そのスクリプト動かしてみたのたですが、 echo ${File}を加えて確認した所
ほとんどのファイルが ASCII と出力されていて、少しだけ Shift-JISという出力が得られました。
って事は?Shift-JISとASCIIが混在しているという事でしょうか?
と言うかそもそもASCIIっていったいどういう・・?
euc-jp sjis utf-8 の3種類しか基本的には知らなくていいと思っていたのですが、4つ目の文字コード
も混在している(というよりeuc-jpのファイルは存在しなくてsjisとASCIIの2つが混在?)と言う事でしょうか。
と言うか convmv --list してみたら asciiってあるし・・・・。
>>176 そうそう、さらにFTPも混ざったりssh + rsyncとかでファイル持ってきたりすると
もう今ぐちゃぐちゃになってて、UTF-8に統一したいんですよ。。。
>>177 .txtの拡張子のファイルは BINARYはでません。
ん?って事は nkf -g ではファイル"名"の文字コードを判別しているって事ですか?
で、その出力がASCIIとShift-JIS、その他としてはBINARYの3種類の状態(だと思う)の場合は
convmv -f ascii -t utf-8
convmv -f sjis -t utf-8
でそれぞれ変換かければいいのかな・・・。なんか難しすぎて頭痛くなってきたOTL。
でもなんか全面的に私が間違っていた感じがするので、その点については皆様方には
大変ご迷惑をお掛けしておりまして申し訳ありません。
>>179 なんていうか、なぁ。
ASCIIってのは日本語使ってなけりゃASCIIだわな。ちと語弊あるけど。「a.txt」とか。
で、オレの
>>177 で示したのは、
>>174 をオレ解釈したところ、
「a.txt」と「(UTF-8な)あ.txt」と「(EUC-JPな)い.txt」が混在してると、いっしょくたになったのが
コード判別にかかって、結局コード判別できなくって「BINARY」って判別されるってことか? と。
オレの説明わかり難かったとは思うけどな。
でもってnkf -gだが、たんに「入力された」のの文字コード体系を調べるだけであって、それが
「ファイルの中身」なのか「ファイル名」なのかは、どっちを指定、てか、nkfに入力したか、て
違いだけ。わかる?
ついでに日本語のファイル名がShift-JISだけなら、SJIS→UTF8に変換指定するだけでokやな。
そんなわけで、まちっと勉強しれ。
>>179 ああ、そういや ASCII を忘れてた。w
解説は
>>180 を見てもらうとして、
それを踏まえて
>>174 を改良すると、こんな感じかな。
後は自分で調べてみな。
find /data | while read TARG ; do
File=$( nkf -g <<< "$TARG" )
case "$File" in
Shift_JIS*) Code='sjis' ;;
EUC-JP*) Code='euc-jp' ;;
ISO-2022-JP*) Code='iso-2022-jp' ;;
ASCII*|UTF-8*) echo "$TARG: $File"; continue ;;
*) echo "$TARG: $File: Not supported format."; continue ;;
esac
echo "$File: Convert from $Code to UTF-8." ## お好みで
convmv -f "$Code" -t utf-8 "$TARG" --notest
done
>>180 > 「a.txt」と「(UTF-8な)あ.txt」と「(EUC-JPな)い.txt」が混在してると
判定はファイルごとに行うからこれで「BINARY」にはならないはず。
「(UTF-8)あ(EUC-JP)い.txt」とか、複数の文字コードで構成された
ファイル名だと誤判定と言うか、期待通りにはならないと思う。
こういうのもきちんと判定したいのなら ack がお勧め。
こんなファイル名に出くわす事はまずないだろうけどな。w
>>180 なるほど、英数字だけの場合はASCIIなんですね・・。
では、 a.txt(ASCIIですよね) を convmv -f ascii -t utf-8 a.txt --notest
なんて有り得ないわけですよねぇ。
BINARYって判別されたのは 例えば vncviewer.exe とかのファイルです。バイナリファイルだし。。。
この結果を見て私は vncviewer.exe と言うファイル名自体は英数字のみなので ASCIIかと
思いますが、しかしvncviewer.exeのファイルの"中身"はBINARYなので、nkf ってのは
ファイルの中身を見てコードを判別して返してくれるんだなぁと思った次第です。
(nkf がファイル"名"を見て返してくれるのなら vncviewer.exeはBINARYではなくASCIIで
かえって来ないといけないからです。) でも nkf に対して何を入力するかによって
返してくるものは違うんですね。ファイル"名"をnkfに入力すればファイル"名"のコードが帰ってくるし
ファイルの内容を入力すればファイルの内容のコードが帰ってくると。
>>181 度々具体的なスクリプトを示して頂いて本当にありがとうございます。
しかしですね・・・よくエラーを見てみると no such file or directory が帰ってきてるんですよね・・・。
つまり find /data をした結果、文字化けしたファイル名が返ってくるわけじゃないですか。
その文字化けしたファイル名の場合、そのファイルにはアクセスする事が出来ないですよね。
文字化けしたファイルに唯一アクセスする手段があるとすれば、それは "*" を使う事ですよね。
だから for や while で1ファイルずつ処理するっていう最初のアイディア自体がそもそも不可能
だったと言う事に今更ながら気づきました。ほんと文字化け問題って大変ですね・・。
"*"を使うと言っても find /data/* だと結局1ファイルずつ文字化けしたものが帰ってくるので
ダメっぽいです。 convmv に 直接 * を渡す必要があるみたいで、そうすると混在している場合に
全く処理をしてくれなくて結局ダメと。。。参ったなぁ・・・OTL。
それと1つシェルスクリプトスレなのでお聞きしておきたいのですが
File=$( nkf -g <<< "$TARG" ) ←これなんですが、 <<< って何ですか?普通 < か << ですよね。
<<<は初めて
183 :
165 :2007/09/17(月) 22:30:38 ID:RA5G8Fdp
>>169 エラーの起こる直前までは変換してくれるのかと思ってた。
いらぬ時間をとらせてすまねぇ。
んで(w)、また懲りずに考えてみたんだが、nkf使うんだったら
find work/ -type f -exec sh -c 'FN="`dirname \"{}\"`"/"`basename \"{}\" | nkf -w`"; [ -f "$FN" ] || mv -v "`echo \"{}\"`" "$FN"' \;
とかいかが?
ディレクトリ含まれてないんだけど、含むと末端からやらないといけないからシェルスクリプトでやるのは面倒くさそうだなァ、と思って逃げたw
>>183 うぐぅ・・・・
そのfind 以下のスクリプト難しすぎて私には何をどうしているのかさっぱり分かりませんです。。
awkとか正規表現とかそこら辺全然知らないので、なんかそれっぽいコードに見えて読めないOTL。
ディレクトリを含まないって言うのも問題ですねぇ・・・。
例えばですが hoge.txt と piyo/ っていうディレクトリが存在していて、それぞれのファイル名
もしくはディレクトリ名の文字コードを知りたい場合はnkfではどのようにコマンド入力したらいいんですか?
ls -d piyo/ | nkf -g
nkf -g < hoge.txt
nkf -g | `ls -d piyo/`
nkf -g <<< hoge.txt
等など色々試してみましたが、文字コードが見えませんでした。
# convmv ももう少し気を利かせて --force オプションなんて作ってくれて処理できないファイルは
スキップして処理可能なファイルだけ全部処理するみたいな機能盛り込んでくれてれば助かったんだけどなぁ・・・。
無理してシェルで書くより perl かなんかで書いちゃった方が早い気がする。
186 :
login:Penguin :2007/09/17(月) 23:26:23 ID:hplwR1nR
すいません、いろいろやってみたけど出来ないので教えてください。 aaaa,bbbb,cccc,"hoge,hoge",ddd,eee,ffff みたいなCSVが有ります。 ※カンマがある列は必ず「""」で括られています。 # cut -d, -f 4 とかでカンマが含まれる行を出力しようとすると 結果に「"hoge」とのみ出力されてしまいます。 本当は「"hoge,hoge"」が出力されてほしいのです。 「"hoge,hoge"」の出力結果を得るためにはどの様にすれば良いですか? 自分的には、 sedコマンドでいったんワークファイルwor.csvなどに「"hoge\,hoge"」と エスケープシーケンスを追加してからcutコマンドを実行すればうまく行くような気がしているのですが、 sedをどのように記述して良いのかすら解りません(泣) どなたか教えてください。。。。
実は混在なんかしてない、ていうことはないのんか? もしくはかなり偏っている。 なら、ある程度手作業でその他一括、のが楽かも知れん。
結局カンマ関係なしに""で括られたのが欲しいんじゃねぇのか?
186です。
>>187 1000行近くのCSVファイルで確実に混在しています。
例えば、↓↓↓みたいな行です。
(「US」の後ろにカンマがありますよね?)
75,0,,,-,,-,"LOG3\.0.*123456 .....5.*\(US, 21\): NOTICE:.*",,,,,,,AAAA,BBB,"TEST",WARN,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,,,,1,,,,,,,,,,,,,,,,,,,75
この行から特定の列だけ抜き出し&抜き出しした列を引数にコマンドを実行しています。
>>188 そんなことないです。
実際には初期値の列も多いので。
>>182 read に -r オプションつけたらどう?
旧) find /data | while read TARG ; do
新) find /data | while read -r TARG ; do
^^^
> File=$( nkf -g <<< "$TARG" ) ←これなんですが
man bash のヒア・ストリングス (Here Strings) の項を参照。
>>189 う〜ん、難しいね。
クォートされたエントリが一行に一つだけなら
↓で取り出すことはできるけど。
sed '/"/ s/.*\(".*"\).*/\1/'
俺なら一度 csv を Excel に放り込んでから
特定の列を抜き出すかな。w
sed -n 's/\(\("[^"]*"\)\|\([^,]*\)\)\(,\|$\)/\n\1\n/4;s/[^\n]*\n//;P' sedでやってみた。
186です。 ありがとうございます。 191,192を実行してみたんですけど、正しく表示されませんでした(泣)
>>186 センス悪いけどこんなのでよければ
#!/usr/bin/gawk -f
BEGIN{n=ARGV[1];ARGV[1]=""}
function parse(s,c,f,i,j,k){
while(1){c=substr(s,i,1);if(c=="")return;else if(c=="\"")f=(f>0)?0:1
else if(c==","&&f==0){array[k++]=substr(s,j,i-j);j=i+1}i++;}}
{parse($0);print array[n]}
195 :
192 :2007/09/18(火) 18:40:20 ID:AGCqK3mV
/^o^\懽懽懽懽懽懽懽 自分の環境では、186と189は上手くいってるぽいんだが。 例えば、189は192の4の所を8にすれば "LOG3\.0.*123456 .....5.*\(US, 21\): NOTICE:.*" って出るし、15にすれば AAAA と、出る。 sedのバージョンと実データがどんなのか知りたい所。
>>195 スマソが懽の隣の文字のフォントが無いのだが
E3
5E
って表示になってる
半角カナで書いたら化けた模様w
bashでスクリプトと組んでいる途中でつまづいてしまいました ~/tmp/ 以下にあるファイルすべてに対してファイル変換したいのです(例 aaaaa ⇒ aaaaa.txt) ~/tmp/aaaaa ~/tmp/bbbbb : ~/tmp/nnnnn ============= cd ~/tmp/ ls_result1=`ls` for list1 in $ls_result1 do #便宜上 (変換コマンド) (変換前) (変換後) とします (変換コマンド) ~/tmp/$(list1) ~/tmp/tmp/$(list1).txt ←listの使い方が間違っているのだと思います done ============= list1 not found というエラーがたくさん出てきてしまい困っております。 ~/tmp/ 以下にあるファイル名をそのまま使いたいので、どなたかご教授ください。
>>198 ×(変換コマンド) ~/tmp/$(list1) ~/tmp/tmp/$(list1).txt
○(変換コマンド) ~/tmp/${list1} ~/tmp/tmp/${list1}.txt
200 :
198 :2007/09/18(火) 22:15:47 ID:En+WDn3C
>>199 できました♪ ありがとうございました m(_ _)m
201 :
login:Penguin :2007/09/19(水) 06:55:54 ID:OLZv4Z+v
sed で/、\を多用できるようになりますたww \tとか技も覚えますたww みなさんdd!
202 :
198 :2007/09/19(水) 12:51:22 ID:OlaeIc6l
~/tmp/ 以下にある txtファイル だけファイルの中で置換したいのですが、 またつまづいてしまいました # その前の処理で year month day hour という変数が与えられています txtファイルの1行目 2007090100AB ⇒ year month day hour AB(変数の間のスペースなし、ABは固定文字列) txtファイルの2行目 2007/09/01 ⇒ year/month/day そこで以下のように作ったのですが、~/tmp/ に bakファイルが作られておらず、 echo $ls_result を見ると /home/myname/tmp/*.txt となっていました 想定では *.txt だったのですが・・・ ================= ls_result=`ls ~/tmp/*.txt` for list in $ls_result do cp -p $list ${list}.bak sed -e '1 s/2007090100AB/${year}${month}${day}${hour}AB/' ${list}.bak sed -e '2 s/2007\/09\/01/${year}\/${month}\/${day}/' ${list}.bak mv &{list}.bak $list #rm -f ${list}.bak ================= どなたか教えてください。よろしくお願いします。
これではまともに動いてもbakファイルはないだろ
>>202 これだと置換後のファイルを.bakに作って、そのあと出来た.bakをオリジナルに
重ね書き(しかもムーヴ)してるように見えるけど。
.bakとオリジナルの2個とも残したいなら、mvじゃなくてcpだろうね。
それ以前に、こういう処理だと普通は.bakに変換前のオリジナルを残すと思うが。
最初にオリジナルを.bakにcpしてあるんだから、.bakは触らずに、元のファイルに
sedかけて、最後のmvは不要では
205 :
198 :2007/09/19(水) 20:34:50 ID:OlaeIc6l
>>203-204 コメントありがとうございます
いただいたアドバイスどおり、bakにはさわらずにオリジナルでsedかけてみました
ところが、シェルを動かした後のファイルを見ると動かす前とまったく同じ状態でした。
タイムスタンプも動かす前と同じでした。
sedの使い方が間違っているのでしょうか。今一度教えてください。
=================
ls_result=`ls ~/tmp/*.txt`
for list in $ls_result
do
cp -p $list ${list}.bak
sed -e '1 s/2007090100AB/${year}${month}${day}${hour}AB/' ${list}
sed -e '2 s/2007\/09\/01/${year}\/${month}\/${day}/' ${list}
#rm -f ${list}.bak
=================
>205 sedは-iオプションを指定しないと結果を標準出力に書き出すだけだよ。
sed -i.bak -s \ -e "1s/2007090100AB/${year}${month}${day}${hour}AB/" \ -e "2s,2007/09/01,${year}/${month}/${day}," \ ~/tmp/*.txt で、よくね?
208 :
198 :2007/09/19(水) 21:44:56 ID:OlaeIc6l
>>203-204 ,206-207
207さんのとおりにしたら、想定どおりに動きました!
みなさんありがとうございました。m(_ _)m
ずっと調べてたらこんな時間に…
今からごはん作ります (^o^)/
209 :
login:Penguin :2007/09/21(金) 15:18:02 ID:5N/Tidqv
ディレクトリーA(ファイルが入ってます)を 10/1〜10/31の日付名でコピーしたいのですが なんかいい方法無いでしょうか? Zshだと cp -R A 10[1-31]なんてできるのでしょうか?
>>209 for i in {01..31}; do cp -pR A A10$i; done
zsh と bash で挙動違うな。
>>209 < - > のことなら、ちょっと用途が違うよ。
こんなんやってみ。
% touch B2
% ls B{1..3}
% ls B<1-3>
>>210 ハヤッ! ありがとうございます!
ディレクトリーAにhoge01〜100ってファイルを作ったときは
Zshでさらさら〜って逝けたのですが
現在bash環境なのでそれなりに書かないといかんなと思いつつ
3行になってしまう、漏れの脳みそでした il||li○| ̄|_
1行でやりたかったww さすがです
>>210 様 1行でばっちりコピーできますた
>>211 すみません −じゃなくて..でした
なかなか参考になるスッドレですね
正規表現もきっちり覚えないといけませんねorz
for d in {01..31} ; do printf "%02d " $d; done
215 :
73ですが :2007/09/22(土) 22:02:55 ID:TBL9KN2J
>>94 おくればせながらスクリプトが動くようになりました。
御指摘のとおりスペースの数などがあっていませんでした。
ありがとうございました。
時間の逆算っていい技ないですか? やぱ現在時刻から60進法で計算したほうが早い? 現在時刻 21:24 残り時間 36分で22時 って感じ で、やてみたい
date --date xxmin とかできるのですね!!
しらなんだポカーン
>>217 ありがdクス
echo $((59 -` date '+%M' | awk '{print $1}'` )) $((59 -` date '+%S' | awk '{print $1}'` )) これでもでけた!
220 :
login:Penguin :2007/09/27(木) 18:47:27 ID:Qh1DP+hx
date,sleep, atは使い込めばラーメンタイマーも・・・・・・・いやなんでもない
221 :
login:Penguin :2007/10/02(火) 23:24:08 ID:57QYWA2W
ほしゅ
モデムをオンフックにするのに 今のところcuを使って対話的にATH0を 送っているのですが、これを シェルスクリプト内で実行して 自動化する方法はありますか?
対話的といえば expect ぐらいしか思いつかないな
224 :
222 :2007/10/10(水) 19:31:25 ID:TchaYqjx
>>223 manを眺めましたが奥が深そうですね。じっくりと勉強してみます。
ありがとうございました。
モデムで思い出したが、ミャンマーで対外ネット回線が一時遮断されたって 報じてたじゃん。 こんなときにもなんとかなるよう在外公館にアナログモデムを常備してたりは しないだろうか。
227 :
222 :2007/10/11(木) 06:32:06 ID:o32fDZEh
>>225 これまでCCT-98IIIのマクロで自動巡回してたんですが
Linuxにしたら使えなくなるそうなので・・・・。
って、いやそうじゃなくて、vgettyで留守電のテストを
やってたら回線をつかんだまま切れないことがあって
それを切断させたいわけです。
>>226 自分はいざというときのためにジャストシステム製の
音響カプラ持ってます。(処分してないだけかも)
kermitをperlで操作するnifty4uというパッケージが、前世紀にあった。 NIFTY フォーラム自動巡回スクリプトなので、CCT-98な人には改造が容易かも。 ダイアルアップpppスクリプトを書けば済むんじゃないかと思うけど、やったことないから分かりません。。。
229 :
login:Penguin :2007/10/11(木) 13:36:28 ID:wykYuUw8
#!/bin/bash cd /home/hogehoge というシェルスクリプトを作成し、実行してみても、移動でき ません。 ディレクトリを移動するにはどのようなスクリプトを書けばい いでしょうか?
>>229 シェルスクリプトとバッチファイルは違う。
シェルスクリプトはシェル内で動作する子プロセスだ。
>>229 >>230 一部訂正。
s/シェルスクリプトは/単純に実行したシェルスクリプトは/
解決方法は "source" 。
232 :
229 :2007/10/11(木) 14:10:15 ID:wykYuUw8
>>232 shell.sh がシェルスクリプトのファイル名だとして
chmod a+x shell.sh で実行権限与えて
shell.shがあるディレクトリで
./shell.sh
したら移動するよ。
234 :
229 :2007/10/12(金) 09:38:40 ID:EbLcx1Gh
>>231 sourceやってみたら無事cd出来ました。
>>233 やってみたけど、上手くいきませんでした。
お二方ともありがとうございました。
シェルプロンプトにコマンド名を叩き込んで実行すると、 子シェル(sh,cshなど)が新たに作られて、その子シェルがスクリプトを実行する。 で、スクリプトが終わるとその子シェルもろとも消えて親シェルに戻ってくる。 だから、シェルスクリプト内でcdしたり、環境変数をセットしても、その影響は 子シェルの中にとどまって、スクリプト終了と共に消えてなくなる。 cshのsourceやshの.(ドット)は、子シェルを作らないで自分の中でスクリプトを実行する。 だからcdやsetenv、exportの結果が、起動した親シェルに反映される
. の他に alias とか関数使う手もあるよ。
237 :
233 :2007/10/12(金) 17:40:09 ID:sUVuIX9s
>>234 ごめん!間違った。
./shell.sh じゃなくて
. ./shell.sh でした。
. を打って1個スペース空けて シェルスクリプトファイル指定。
Yeah!めっちゃホリデイ
特定のURLを一定時間に読み込むシェルスクリプトをつくりたいのです。
今のところwgetを使ってwget
http://hogehoge をクーロンで動かす予定ですが
もっとスマートなやりかたはありますか?
>>241 じゃあ1分に1回よりも高頻度(30秒に1回とか、15秒に1回とか) やりたい場合はどうすれば?
アタックしたいのか?
>>243 アタックしたいわけじゃないですよ。
ただcronって最高でも1分に1回しか実行できないはずなので、それよりももっと短い間隔で
処理をさせたい場合とかどうするのかなぁとふと疑問に思ったもので。
>>244 なるほど・・。 しかし wget
http://... ; のところで1分ぐらい処理に時間がかかった場合
その後の sleep 30 ; がきて、そしてまた wget
http://... がくるから、タイミングと言うか場合によっては
30分に1回キッチリ実行されるとは限りませんね。31分かかって、その後実行されて
今度は29分後に実行されるみたいなズレ方はしますよね。
>>245 バックグラウンドで実行するとか。
つーか、何分もかかる処理を30秒ごとに実行していいのか?
cronはプロセスが無限増殖するのを抑えるために、同時実行数に制限があるので注意 Solarisだと、確か同時実行数が100個を超えるとそれ以降は時刻が来ても起動しなくなる LinuxだとOOMキラーが動いて刈り取られるかもしれん cronの起動間隔 ≒ プロセスの実行時間 となるような長めのプロセス、特に通信関係とかで長めのタイムアウトが発生しそうな プロセスをcronに仕込むときは、注意したほうがいい
248 :
229 :2007/10/16(火) 13:58:23 ID:EtpWijek
環境が手元にないもので、遅レスになってしまいすみません。
>>235 なるほどです。ありがとうございました。
>>236 ありがとう。aliasでも出来そうでした。
>>237 .の後に続けて入力したところ、うまくcdできました。
>>238 素人なのでよく分かりませんが、実行ファイルを実行するときに付けるんでは?
それでは、みなさんありがとうございました。
>>248 . shell.sh
でもいっしょだよ。
やってみ。
./ を つけるのは カレントディレクトリのファイルを指定する為。 つけないと 環境変数 $PATH の中から該当する物が無いかを探してなかったら エラー返すので。 カレントディレクトリのファイルを指定する時にいちいち ./ をつけるのが面倒だからって $PATH に ./ も含めてしまうとセキュリティホールになるので やらないでね。
シェルスクリプトで端末の現在の行数を得るにはどうしたらいいですか
stty -a とかかな。
>>253 情報ありがとうございます。
行数を表示するだけでなくて、
シェルスクリプトの中で行数を変数に格納して、
なんらかの処理を行いたいと思っているのですが
何かうまい方法はありますでしょうか
>>254 ROWS=`stty -a | tr ";" "\n" | grep rows | sed "s/.*rows //"`
$LINES じゃだめなの?
シェルスクリプトの中で$LINESがとれるとでも?
ROWS=`tput lines` COLS=`tput cols`
eval `resize` echo $LINES $COLUMNS
>>260 resize は X がインストールされていない環境では使えない。
xterm の付属物なので。
262 :
login:Penguin :2007/10/23(火) 17:14:39 ID:OMh5qn/O
ちょっと相談に乗ってください。 日付.pc名.サイト名_access_log ex) 20071023.pc-local01.hoge_access_log 20071023.pc-local02.hoge_access_log 20071023.pc-local01.hagehoge_access_log 20071023.pc-local02.testhoge_access_log と言うログファイルをサイト名別のフォルダに移動した後 1つのログファイルにマージさせるスクリプトを書きたいのですが。 とりあえず、スクリプト書いてみたのですが正直何がなんだか 分かりません。アドバイスを下さい。 #!/bin/sh timestamp=`date +%Y%m%d` log=`find /home/hoge/log -name $timestamp.*` list=`echo "$log" | sed -e 's/_access_log//g' | cut -c57-` スクリプトでは、今日のタイムスタンプを取ってlogファイルを検索し その結果のサイト名以降の”_access_log”を消して、サイト名より前 も入らないので、表示させないようにする。これから、サイト別にフォルダを 作ってそこに移動させるのですが、mkdir "$list"では上手く行きません。 何かいいアドバイスを教えてください。よろしく御願いします。
>>262 シェルスクリプト以前の話だな。
まずは最終的に何をやりたいのかをはっきりしろ。
>>262 $log にたくさんファイル名が入ってるのに
echo $log をいじろうとするのがよくわからんな。
>>264 まずは日本語の勉強からだな。
>>263 サイト名だけの文字を取りたかったので、cut -c57- としました。
>>264 申し訳御座いません。
ログファイル名からサイト名だけを文字を取り出して、取り出した文字
(サイト名)のフォルダを作って、作ったフォルダにそれぞれログを
振り分けてログファイルをマージさせたいです。
これで、少しは伝わりますでしょうか?
>>265 $logの結果からサイト名の文字だけ取りたかったので、echo $logを
いじっています。
>>266 プログラミングの論理部分を勉強したほうがいい。
「やりたいこと」と「実際のスクリプト」の間には
「ロジックを組み上げる」作業が必要になるが、
君はこの部分について全く理解できていないようだ。
まずは
「findで検索したファイルの一覧はどういう形で変数logに入っているのか」
「その変数logに対して繰り返し処理を行なうにはどうしたらよいか」
を調べてくるべし。
そもそも find でうまくいかんな。
>>262 find . -type f -printf %f\\n|awk -F. '{gsub(/_access_log/,"",$3);print $2 "." $3}'|uniq >hostlist
for i in $(cat hostlist);do mkdir $i;done
あとawkで同じように
cp 20071023.pc-local02.testhoge_access_log pc-local02.testhoge
のようなlist作って実行
>>267 アドバイスありがとうございます。
正直、インフラ担当なのでプログラムさっぱりです(;´Д`)
とりあえず、ググって調べてみます。
>>268 もう少し調べてから、スクリプト書き直します。
ありがとうございました。
>>269 ありがとうございます。
参考にさせて頂きます。とりあえず、スクリプト周りを調べて
書いてみます。
#!/bin/sh cd /home/hoge/log for i in `date +%Y%m%d`.*; do dir=`echo $i | cut -f2 -d.` [ -d $dir ] || mkdir $dir mv $i $dir done ファイル数が多過ぎるとかヘンなファイル名とかは知らね。
IPアドレスを16進に変換したいです。 どうやりますか?
echo '192.168.0.1' | gawk -F. '{printf("%02x%02x%02x%02x\n", $1, $2, $3, $4)}'
275 :
login:Penguin :2007/10/27(土) 13:26:52 ID:QMQXG4ov
>>274 俺のIPサンプルに使うなよ。晒されたら攻撃の的になるだろうが(´・ω・`)
>>275 ネットに繋がらないと思ったらお前のせいかー!
早く俺のIP返してくれよ(´・ω・`)
278 :
login:Penguin :2007/10/27(土) 15:34:59 ID:XQQiaIjq
>>275 そうか、そんなにお望みなら今から的にしてやるよwww
タシロ砲とブラスターとあと手持ちの攻撃ツールの標的IPを全部セットして攻撃開s
俺のIPは127.0.0.1だから攻撃するなよ
ひどいネタスレと化してるなココwwwwww
俺のIPは172.31.0.1だぞ。
もういいよ。
283 :
login:Penguin :2007/10/29(月) 11:01:37 ID:F/RFN0ba
俺のIPは203.・・・・ いややめとく
じゃあオレも1個 オレのIPは 169.254.88.24だぞ。
あ、思い出した。 255.255.255.255 -> 0xffffffff のように、IPv6表記を16進表記に変換する手続きを考えてくだちい。 f000::1 -> 0xf0000000_00000000_00000000_00000001 ("_"は不要) ff::169.254.88.24 -> 0x00ff0000_00000000_00000000_a9fe5818
完全に他人まかせだなぁ。 > ruby -rsocket -e 'p Socket.gethostbyname("ff::169.254.88.24")[3].unpack("C16").map{|c|format "%x",c}.join' "00ff00000000000000000000a9fe5818"
あー、目鱗。 gethostbyname()等を使えばいいのか。
あるコマンド(hoge)の結果が・・・ (カラム位置) [col1 col2 col3 col4] (コマンド出力) 0001 0002 * 0004 である場合にこの結果をset `hoge`で受けた場合、位置変数 $3に「*」が入ってくるようにbashのスクリプトを作成したい のですが現状ではどうやってもカレントディレクトリ配下の ファイル一覧が入ってきてしまいます。 何か良い手がありましたら教えて下さい。
"`hoge`"
>>289 オイオイ!w
マジレスすると
$ set -o noglob
じゃないの
>>300 zenity を使うとシェルスクリプトで手軽な GUI が作れるぞ
文章全体から見てポジティブな物言いだと思うが...
zenity の使用例: jpg と mp3 をあわせて avi を出力するスクリプト 音声ファイルをビデオホスティングサイトに投稿時に使用 ==================================== #!/bin/sh # mp3jpg2avi.sh JPG_FILE=`zenity --title="JPG ファイルを選択してください" --file-selection` MP3_FILE=`zenity --title="MP3 ファイルを選択してください" --file-selection` zenity --title="質問" --question --text "変換開始しますか?" if [ $? = 0 ]; then ffmpeg -shortest \ -loop_input -f image2 -i $JPG_FILE \ -i $MP3_FILE \ -sameq output.avi fi ====================================
>>292 Linuxから入った人だけど、Gnomeなんてマルチウインドウ端末エミュレータ支援ソフト西か見えません
マルチウインドウ端末エミュレータ支援ソフト西やら マルチウインドウ端末エミュレータ支援ソフト力石やら マルチウインドウ端末エミュレータ支援ソフトホセ=メンドーサやら知らん。
そういやこの間表参道歩いていたら、 胸にでっかく 「マンモス西」 と書かれたTシャツを着たガイジンが 前からいきなり歩いてきてビビった。 東京は怖い街だよ。
恥を忍んで質問なのですが /home/me/ 以下にjpgファイルが数千有ります 中身はこんな感じなのですが 1082053423922.jpg 1082053508305.jpg 1082053537535.jpg 1082053614971.jpg 1082053699948.jpg 1082053732609.jpg 1082053763346.jpg 1082391828601.jpg 1082392563669.jpg 1083091232922.jpg この数千の*.jpgのファイルをディレクトリから読み込んで以下タグの中にディレクトリから読み インクリメンタルに全ての画像ファイルがリンク代入された状態で出力したいと思っています <div id="myGallery"> <div class="imageElement"> <h3>Item 1 Title</h3> <p>Item 1 Description</p> <a href="mypage1.html" title="open image" class="open"></a> <img src="images/foo/a.jpg" class="full" /> <img src="images/foo/a-thum.jpg" class="thumbnail" /> </div> ディレクトリから読み込んだfileの名前a.jpgににファイルの中が無くなるまで 置換したいという意味なのですが.. どうか、助言願えないでしょうかm(__ __)m
まずは「この数千の……」以降の文章を推敲して他人に理解できるよう 書き換える。
こういうことか? for f in `ls -1 /home/me` ; do echo '<img src="images/foo/'$f'" class="full" />'; done for f in `ls -1 /home/me | gawk '{gsub("\\\.", "-thum.");print}'` ; do echo '<img src="images/foo/'$f'" class="full" />'; done
306 :
302 :2007/11/13(火) 14:02:39 ID:tnRwnYpT
>>303 深夜に回転数が落ちていまして申し訳ないですm(_ _)m
>>304 それも考えたのですが、出来ればこちらの方が良いなと思いまして..
>>305 バッチリ書き出せました、もの凄い感謝なのですが
thumとthum無しのイメージが交互に書き出すことが出来ると思います
教えていただいた物を各ディレクトリに置き換えたものが以下の物なのですが
for f in `ls -1 /www/web_dir/photo_album/images/foo/`; do echo '<img src="images/foo/'$f'" class="full" />'; done
for f in `ls -1 /www/web_dir/photo_album/images/foo/ | gawk '{gsub("\\\.", "-thum.");print}'` ; do echo '<img src="images/foo/'$f'" class="full" />'; done
1行目と2行目を並べて出力できるように努力したのですが...
gawkの部分で引っかかってしまいます、というか1行目しかループしてくれません(T.T)
補足いただければと思うのですが、よろしくお願いします マジ感謝感激です
shell sciptとawkの本もamazonしようと思っています
307 :
302 :2007/11/13(火) 14:19:58 ID:tnRwnYpT
もうちょっとで出来そう...
308 :
302 :2007/11/13(火) 15:05:30 ID:tnRwnYpT
出来ました ありがとうございましたm(__ __)m
最終的にどうやりましたか? 報告して下さい。
310 :
302 :2007/11/13(火) 15:32:02 ID:tnRwnYpT
ディレクトリを作りthumnail入れてこれで出力できました for f in `ls -1 /www/web_dir/photo_album/images/foo/`; do echo '<div id="myGallery">'; echo '<div class="imageElement">' echo '<h3>Item 1 Title</h3>' echo '<p>Item 1 Description</p>' echo '<img src="images/foo/'$f'" class="full" />'; echo '<img src="images/foo-thum/'$f'" class="full" />'; echo'</div>'; echo ' '; done
ちなみにサムネールは thumnail じゃなくて thumbnail ね。
312 :
302 :2007/11/13(火) 16:02:23 ID:tnRwnYpT
はい、ありがとうございました^^
>>306 ls -1 /www/web_dir/photo_album/images/foo/ | gawk '{gsub("\\\.", "-thum.");print}'
ここだけ実行するとどうなるの?
ls -d /a/b/c/d/*/ のようにコマンドを打ち込むと /a/b/c/d/hoge1 /a/b/c/d/hoge2 /a/b/c/d/hoge3 のように出力が帰ってきますよね。この中から hoge1, hoge2, hoge3 の部分のみ、つまり ディレクトリ階層の一番深い部分のディレクトリ名 のみを得る為にはどうすれば良いのでしょうか?シェルスクリプト内で必要なのですが 分かりません。教えてください。 自分で調べた限りだと basename とか dirname がそれに近そうだったのですが、 ちょっと違うようです。他には見つけることが出来ませんでした。
>>314 > のように出力が帰ってきますよね。
いいえ。
>>315 /a/b/c/d/hoge1
/a/b/c/d/hoge2
/a/b/c/d/hoge3
じゃなくて
/a/b/c/d/hoge1/
/a/b/c/d/hoge2/
/a/b/c/d/hoge3/
の間違いでした。 このリストから hoge1, hoge2, hoge3を抜き出したい。
hoge1/ の最後の "/" も切り落としてしまいたいのですが、どうすれば良いでしょうか?
>>316 sed なり awk なりで切り出せると思うけど、
最初から
find /a/b/c/d -mindepth 1 -maxdepth 1 -type d -printf "%f\n"
とかじゃだめなん?
>>316 for i in ls -d /a/b/c/d/*/; do basename $i; done
>>318 for i in `ls -d /a/b/c/d/*/`; do basename $i; done
と言いたいんだろうが、
for i in /a/b/c/d/*/; do basename $i; done
でいいな。
空白とか入ってなければ。
>>317 レスありがとうございました。
しかしfindコマンドに詳しくない為自分ではよく分かりません。それ・・・。
>>318 レスありがとうございました。
こちらの方法はまさに私が求めていた方法です。非常に分かりやすくて助かります。
本当にありがとうございます。
321 :
320 :2007/11/16(金) 21:33:37 ID:q8UeZNS0
解決したと思ったのですが、 ROOT=/a # ←ココは何でもいい、とにかくディレクトリ cd ${ROOT} for DIR in `ls -d ./*/` do for TARG in `basename ${DIR}` do echo ${DIR} echo "${TARG}" done done といった感じにしてみたのですが、 Venus7.0 Personal Edition といったディレクトリが Venus7.0 と Personal と Edition の3つに分割されてしまい、そのディレクトリに対して 処理したいのに3つの存在しないディレクトリに対して処理しようとする為、 no such file or directory エラーが次々と帰ってきました。 どうも ディレクトリ名に半角スペースが入っているのがダメなようです。解決策はありませんか? ちなみに全角スペースの場合は1つのディレクトリとして正常に動作しています。 for DIR in `ls -d ./*/` ←この部分で分断されてしまっていると思いますが for DIR in `ls -d ./"*/"` などと" " で囲んで見ましたが */ なんてディレクトリは見つからない と怒られました。 ' ' で囲んでも同じ結果です。どうしたら半角スペースをセパレータとして 認識するのを防げますか?
なんでそんなディレクトリがあるのか を考えたほうが根本的な解決になりそう
わざわざ_使ってる人の意味を考えよう
>>321 は''の囲み方が間違ってるだけだが
_があるのが普通って考えたほうが手間なくていい
windowsがらみならwindowsでやったほうがいい
325 :
320 :2007/11/16(金) 23:35:30 ID:q8UeZNS0
>>322 ま、まぁ色々事情がありまして。あるんですよ。。。
>>323 >>319 の事かと思ってレスを投稿する前に確認したのですが、
for DIR in ./*/
do
for TARG in `basename "${DIR}"`
do
echo ${DIR}
echo ${TARG}
done
done
で確認したところ 変数DIRには正しく取れました。 しかし
`basename "${DIR}"` としているにも関わらず
元ディレクトリ名 AVG Anti-Virus Free Edition 7.3
実行結果
AVG
Anti-Virus
Free
Edition
7.3
とこのように分断されてしまいます。 " " で囲っているにも関わらず、です。
何がいけないのでしょうか?
#!/bin/sh LIST="\"space aaa\" \"bbb\" \"space ccc\" \"ddd\""; echo $LIST; # "space aaa" "bbb" "space ccc" "ddd" func(){ echo "arg= $#"; #6 echo "$1"; # space echo "$2"; # aaa echo "$3"; # bbb echo "$4"; # space echo "$5"; # ccc echo "$6"; # ddd } func $LIST; 上のようなスクリプトで func には、"space aaa" みたいにスペースの入った引数を渡したいんですが、 なにか方法はないでしょうか? この場合funcにわたす引数を4つにしたいんです。 展開されて、引数が6つになってる。。。素人ですません。
>>325 for TARG in `basename "${DIR}"` ->
for TARG in AVG Anti-Virus Free Edition 7.3
>>328 これだけで良かったんですね。
3時間くらい悩んでたよ。d
つeval
331 :
320 :2007/11/17(土) 10:54:12 ID:oelt9+66
>>327 レスありがとうございます。
そうなんですよ、そんな風に展開されてしまうんですよ。
${DIR} だけを出力しても
./AVG Anti-Virus Free Edition 7.3
となるのに
"${DIR}" とダブルクォートで囲っても
./AVG Anti-Virus Free Edition 7.3
と全く同じ出力になってしまう。つまりダブルクォートが利いてない・・。
だからそれをどうすれば1つの文字列として扱えるのですか?空白を区切りとしないようにする為には・・・。
>331 basename の結果が正しいんだからダブルクォートは効いてるだろ? その後、`` で置き換えた時には既に "${DIR}" とは無関係の文字列なんだから 直書きされてるのと同様に空白で分割されてるだけ。 あえて書くなら for DIR in ./*/ do BASE=`basename "${DIR}"` for TARG in "${BASE}" do echo ${DIR} echo ${TARG} done done っていうか、なんで 2 段で for を回す必要があるのか。
>>331 バッククォート内はコマンドの出力に置き換えされるんだから、その出力を
クォートすればいい。
for TARG in "`basename "${DIR}"`"
っていうか、なんで 2 段で…
334 :
320 :2007/11/17(土) 22:43:03 ID:oelt9+66
>>332-333 な、なるほど・・・・
お二人の解説文を10回ほど読み直しながらじっくり考えてみた所、ようやく理解できました。
特に "`basename "${DIR}"`" はややこしくて 最初は何をかいているのだろうかと思いましたが
`basename "{DIR}"` の出力結果そのものを " " で囲っているわけですね。なるほどなるほど。
う〜ん、これは思いつかない・・・。発想力ですか・・・。
で、2段でfor回していますが、確かに冷静に考えると2段で回す必要はありませんね・・・。
むしろ2段で回す処理にしている事で複雑化してしまった感があります。
1段forでいけそうです。
>326です。
拡張が必要になり、問題が増えました。
#!/bin/sh
echo $LIST; # "aaa aaa" "bbb" "ccc ccc ccc" "ddd"
func(){
〜処理〜
}
func "eee eee" "fff fff" "$LIST" "ggg ggg";
以下のようにfuncにスペースを含んだ形で
${LIST}とその他の値を同列に引数として渡したいのです。
↓funcに渡したい引数
"eee eee" "fff fff" "aaa aaa" "bbb" "ccc ccc ccc" "ddd" "ggg ggg"
>>328 >>330 にあったように eval func で展開すると
LIST以外の引数がスペースで展開されてしまいます。
LIST以外の引数を "eee\ eee" とか"\"eee eee\""とする手で回避も可能ですが、
修正箇所が増えるので、極力この形は取りたくありません。
なにか方法はありませんか?
Σ^)/アホーアホー☆ミ-
uniqはsortしておかないとだめですが、 sortしなくても2回目意向の重複を削除するコマンド内ですか?
some | command | perl -ne 'print unless $seen{$_}++'
>>335 func をスペースを分割しないで処理するようにして、
func に渡す前に "$LIST" だけ分割しちゃえば良いんじゃないの?
>>338 おおおお、できました。ありがとうございました。
grep -A1 "Nov 20" | grep -o "<.*@.*>"
>>339 それが出来れば良いんですが、
できないのです。方法ありますか?
func内で echo $3; した場合。
func "eee eee" "fff fff" "$LIST" "ggg ggg";
echo $3 → "aaa aaa" "bbb" "ccc ccc ccc" "ddd"
当然のように、LIST全体が一つの引数に、、、
以下のようにクォートをなくすと
func "eee eee" "fff fff" $LIST "ggg ggg";
echo $3 → "aaa
LIST内のスペースで、分解されてしまいます。
$3 に "aaa aaa" を渡したいのに、、、
無理にシェルで書くより perl かなんか使った方がいいんじゃね。 適材適所。
eval set $LIST func "eee eee" "fff fff" "$@" "ggg ggg"
>>345 これだ!
こんなトリッキーな手法もあるんですね。
奥が深い。ありがとうございました。
348 :
login:Penguin :2007/11/28(水) 16:44:21 ID:lxwXbk7L
特定のディレクトリ以下にあるディレクトリ名を検索し そのディレクトリの中にファイルがあった場合のみ変数にディレクトリ名を追加する。 という処理をしたいと考えています。 LIST=`find 特定のディレクトリ -maxdepth 1 -mindepth 1 -type d` 上記のコマンドでディレクトリ一覧は取得できたのですが 取得したディレクトリ一覧の中にファイルがあるかどうかの条件設定方法がわかりません ご教授ください
>>348 GNU の find なら ! -empty で。
350 :
348 :2007/11/28(水) 17:14:26 ID:lxwXbk7L
>>349 レスありがとうございます。
LIST=`find 特定のディレクトリ -maxdepth 1 -mindepth 1 -type d ! -empty`
上記のコマンドで無事に条件を満たすことが出来ました。
感謝です><
1 A 1 B 1 C 2 P 2 Q 3 X 3 Y 3 Z ... のような入力を 1 A B C 2 P Q 3 X Y Z ... のように整形する簡単な方法はありますか?
awk '{h[$1] = h[$1] " " $2} END { for (key in h) print key h[key] }' < input | sort
inputをリダイレクトしているのがイヤ。
awkはファイル名を引数に取れるんだな。 パイプでしか使った記憶がなく、素で知らなかった。
むしろパイプでしか使えないコマンドの名前を パッと挙げろという方がむつかしいだろ
オプションの引数という形もない、というものはだいぶ少ないね
とっさに出てきたのは tr
MS-DOS 標準添付の SORT (.EXE か .COM か自身がない)
MS-DOS 標準添付の MORE
361 :
login:Penguin :2007/12/03(月) 14:25:58 ID:pB5IpK3Q
363 :
login:Penguin :2007/12/03(月) 15:02:26 ID:pB5IpK3Q
>>362 ありがとうございます
できました。
最初に言ってたのとちょっと違うのですが、ようは、すべてログに保存して
なおかつERRORの文字が入ってる行だけを画面に出力したかったので
2>&1 | tee file.log | grep ERROR
でやりたいことができました。
いろいろ勉強になりました。サンクス。
>>364 面白そうだけど、記事の中に具体的な画像が欲しいね・・・・
>>366 画像が表示されないのは、送ってくるContent-Typeがおかしいのか。
なんでapplication/octet-streamやねん。
368 :
login:Penguin :2007/12/04(火) 22:59:48 ID:Bpu7L1AF
ややスレ違いだが、くだ質よりこっちかなと シェルスクリプトの本を買う際に、Linuxユーザーでbashメインで使ってるなら 主旨がbash向けのものを買うべきですか? それともB shell全般向けやsh向けでbashは補完程度の本でも質の高いものを買うべきでしょうか 両シェルの間にそれほど機能、性格の差はなさそうだし
bashismって言葉があるくらいで、ついついbashの機能を使ってしまうことは多い。 素のBourne Shellの機能がどこまでなのか書いてある本がいいと思う。
>>369 サンクス
sh向けでも最近の多くの書籍はbashもカバーしているようですので、その辺りを探してみます
>>371 その本と、「UNIXシェルスクリプトコマンドブック 山下 哲典」を最後に候補にしてましたが、後者を買いました。
sh、bash共用でサンプルが多いので。
373 :
login:Penguin :2007/12/06(木) 18:06:51 ID:ltYfbiEn
いつも複合条件式でまるんですけど #!/bin/bash WAITSEC="" if [ -z "$WAITSEC" -o $WAITSEC -lt 60 ]; then WAITSEC=10 fi を実行すると ./hoge.sh: line 3: [: too many arguments というエラーになります。-oとか-aで記述するifは今まで何回かやったのに 一度もできた記憶が無い!!。結局ifを分けたりして対処してきた負け人生です。 いったい何が悪いというのでしょうか?? 教えていただけますか?
確かにbashだとなるねぇ。zshだとならんから気づかなかったw #!/bin/bash WAITSEC=$1 if [ -z "$WAITSEC" ] || [ $WAITSEC -lt 60 ]; then WAITSEC=10 fi echo $WAITSEC とりあえずこれで。
と、思ったら出来たw if [ -z "$WAITSEC" -o \( $WAITSEC -lt 60 \) ]; then こういうことだな。 優先順位がおかしいんだ。
>>373 -z "$WAITSEC" の成否にかかわらず $WAITSEC -lt 60が実行されちゃってるから問題なんじゃないか?
おそらく -z "$WAITSEC"のときは 後ろの条件は 「-lt 60」になるだろうから、
>>374 のようにするか${WAITSEC:-0}とかやったらいいんじゃね?
>WAITSEC="" なので、 >if [ -z "$WAITSEC" -o $WAITSEC -lt 60 ]; then は if [ -z "" -o -lt 60 ]; then と解釈されてエラー。 zsh は sh と違って $WAITSEC は "$WAITSEC" と同じ意味なのでエラーにならない。 "$WAITSEC" -lt 60 と書き換えた場合は、 >-z "$WAITSEC" の成否にかかわらず $WAITSEC -lt 60が実行されちゃってるから問題なんじゃないか? この理由で正しい。
シェルスクリプトにコメントを書くには # comment っていう感じに # を行頭につけてコメントにしますが、自作のシェルスクリプト等に 日本語でコメントを埋め込むのは良くない事なのでしょうか? 英語でコメントを埋め込むべきなのでしょうか? 理由>環境によっては文字化けするかもしれないから その場合、英語では上手くコメントがかけないのですが、、、皆さんはこの辺どうしていますか?
>>378 英語では上手くコメントがかけない、って、自分が書いた自分用のスクリプトだったら、
べつに、自分にさえ分かればいいんじゃないの?極端な話、ローマ字で書いた日本語でもいいんじゃないかと。
Shift_JISで書いて2バイト目に ¥ が含まれるとコメントが継続しちまうかな、 と思ったんだが、そうでもないみたいだな。
>>379 いやー、他の人にもスクリプトの内容が分かるようにコメント書かないといけない場合はどうすれば?
今はローマ字で書いたりしていますが、さすがに見にくいというか・・・ かといって英語では上手くかけないし・・
C言語やJava等では // 日本語コメント が使えるし
MS-DOSの.batファイルでも
REM 日本語コメント
が使える、Windows Script Hosting(WSH)であっても
'日本語コメント
が使えて、大抵のスクリプト言語は日本語のコメントが使えるのになぜにLinuxのシェルスクリプト
だけこんな事で悩まないといけないんだろうと・・・。
まぁOSが違うから文字コード周りのトラブルなんだろうけど・・。
使えるか使えないかっていうなら使えるだろ。 確実に自分しか使わないならShift_JISのようなbrain damagedな文字コードじゃなきゃ 別に何でもいいんじゃない。 しかし使ってよいか使わざるべきかというと、一般にスクリプトって どのロケールで実行されるかわからないよとかの問題が出てくる。 あなたが出した例ではCやJavaのソースファイルはコンパイルするときの 環境が限定できれば問題ないし、DOSのバッチファイルも日本語DOSしか 考えていない。
>Shift_JISで書いて2バイト目に ▼ が含まれるとコメントが継続しちまうかな、 sjis だろうが何だろうがコメントの継続なんてありません。 >しかし使ってよいか使わざるべきかというと、一般にスクリプトって >どのロケールで実行されるかわからないよとかの問題が出てくる。 コメントにロケールなんて関係ありません。
英語くらい書けよ。
っつか、どういう環境(=人間環境)だか知らないけど、 そんな雰囲気だと、頑張って英語でコメントを書いても、 肝心の「他の人」が、それを理解出来ない、 ということが容易に想像出来てしまうわけで、 だったらローマ字でいいじゃん、と思う。
>>383 コメントってのは実行されるときはロケール関係ないけど
元々読むものだから、ロケールばらばらと読みにくくて困るよね
って意味だよ。たぶんね。
#!/bin/bash for i in *.txt で、'*.txt' で展開されるリストの長さに制限はある? ls: argument list too long になる長さでも処理できるようだが、他に何か別の制限はある?
388 :
login:Penguin :2007/12/20(木) 18:50:14 ID:Qtkk7tpx
sedについての質問です aaa bbb ccc という出力を、sedコマンドで一行にしたいのです。 aaa bbb ccc このように。 どうしたらよいですか。 逆の、sed -e 's/\ /\n/g' はできるのですが。
awkなら $ (出力するコマンド) | awk '{printf("%s ", $0)}' でできるんだけどなぁ
$ cat input aaa bbb ccc $ sed -n 'H;${g;s/¥n/ /g;s/^ //p;}' input なんか無様だ。きっともっとスマートに出来るに違いない。
もし各行が空白文字を含まないなら、 echo `cat 元テキスト` > 新テキスト でいいな。
>>388 sed ':loop; N; s/\n/\ /g ;$!b loop' hoge
sedにこだわらなければ tr -s '\n' ' ' < input とか
目的によっては、 $ fmt input fmtってUNIX標準?
>>389-393 こんなにレスが来るとは。
皆さんありがとうございます。
すべて試してすべてで出来ました。
echoとtrはなるほどという感じです。
他は知りませんでした。レベル1アップですね。
>>394 更新遅れた。
できました。オプションすらいらないとは。
awkで awk '{print $2,$3}' とすると2,3番目が表示されますが 二番目以降全て表示するにはどうすればいいのでしょうか?
awk 'gsub($1,"")'
$1に特殊文字が入れられると思わぬ結果になりそうな気がする。
awk '{for (i=2;i<=NF;i++){printf($i" ")}}'
フィールド区切が複数のスペースやタブコードでも、1個のスペースに置換されてしまう気がする。
>>397 の「全て」がそこまで求めているかは分からないが。
>>401 awk -Fなにか '{for (i=2;i<NF;i++){printf("%s%s", $i, FS)};print $NF}'
403 :
397 :2008/01/07(月) 02:29:17 ID:SZZlXYY6
ありがとうございます。
最初
>>387 さんと同じことを思ったのですが他に
オプションか何かで用意されていると思ってました。
402さんのを使わせていただきます
404 :
397 :2008/01/07(月) 02:29:58 ID:SZZlXYY6
s/387/398
>>402 これだと複数の空白が一つになって表示される
awk '{gsub($1, "");print substr($0,2)}'
hint: aho,choaho,kusoaho,doaho ∴ awk '{print substr($0,length($1)+2)}'
個人的には
>>398 をアレンジして、
gawk 'gsub(/^[[:blank:]]*[^[:blank:]]+/,"")'
かな。
なんだ
>>398 で既出だったのね。見落としスマソ。
[file1] bar=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 みたいなのはでっち上げたんだけど、正直汚い。
回答じゃなくてすまんのだが、最後にあるワンライナーだと、 2ファイル通して1回しか現れなかったものを表示するから、 「file1にはないがfile2にある」ものだけでなく 「file2にはないがfile1にある」も出てこないか?
負けず劣らずかっこ悪いシロモノ for 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
grep -v -i "`cut -d= -f1 file1`" file2 重複は無考慮
>>411 あ、すみません。バグです。が、元の仕様が厳しすぎで、
どちらかにしかないエントリを出す
でも大丈夫でした。
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 処理して出力って
簡単そうで微妙に面倒です。
>>413 おおー。grepのexprに改行入れるとそんな動作になるとは!
エレガントです。勉強になりました mOm
416 :
login:Penguin :2008/01/08(火) 18:35:59 ID:0P1F18Bp
1行で2つのコマンドを実行するときに 2つ目に実行したコマンドに、1つ目に実行したコマンドの引数を そのまま渡したい場合の記述方法がわからず、困っています。 $ vi hogehoge; echo ?? *??が不明箇所* 上記の例の場合は2つ目に実行しているecho文の出力結果でhogehogeを表示させたいのですが。。 対処方法はないでしょうか? よろしくお願いいたします。
>>416 i="hogehoge"; vi $i; echo $i
じゃだめなん?
418 :
416 :2008/01/08(火) 19:34:39 ID:0P1F18Bp
>>417 ありがとうございます。
その方法があったことに気づきませんでした。
おかげで解決しました、感謝です><
vi hogehoge; echo !$
>>419 それタイプしたタイミングではまだ!$は前行のコマンドの。
引数が一つだけなら vi hogehoge; echo $_ でもいけるな。
422 :
login:Penguin :2008/01/10(木) 13:02:51 ID:9dVYtTPe
cshからJavaを呼び出すシェルを作成しています。 その呼び出したJava内部で例外が発生した場合、 以降のシェルの処理を続行させたくありません。 どの様にすればよいのですか? Javaのcatch節でSystem.exit(1);とかで処理を終了させて、 cshでそれを検知する方法があるのかなぁ? と漠然には思うのですが・・・
Javaのポリシーは知らないが、エラーメッセージと終了コードは二者択一せにゃならんものではない気がする。
425 :
login:Penguin :2008/01/11(金) 14:14:06 ID:mrGJLB/g
>>423 、424
ありがとうございます。
シェルスクリプト自体、経験が浅い上に今回の要望がcshというのが
決まっているもので・・・
困っています。。。
2chでの質問自体も初めてなもので・・・
準正常として扱うような例外は全てJava側で処理をしてプログラムは
正常終了として扱っています。
処理続行不可能と判断した、ランタイム系やIO例外などが発生した場合は
後続のシェルを流したくない。
という状況です。
if $JAVA_CMD
then
続き
else
exit 1
fi
以下処理続く
・・・
ってな感じにしたのですが、どうも上手くJavaでexitした値が取れないです。
文法が間違っているのですかね?
もう少し調査してみますが、上記の書き方で間違いがあればご指摘頂きたいです。
後は教えていただいた、テンポラリファイルでの判断も考えてみます。
findコマンドの結果をツリービュー(treeコマンドの結果的なツリー表示)で出すコマンドまたは方法ってありますか?
>>425 cshなら
$JAVA_CMD
if ($? != 0) then
echo "failed"
exit $?
endif
echo "OK"
でどう?
428 :
login:Penguin :2008/01/11(金) 16:55:30 ID:mrGJLB/g
>>427 ありがとうございます。
教えていただいた方法で、想定通りの動作になりました。
>>426 普通にtreeコマンド使うんじゃだめなん??
findで絞った結果を出したいのかなぁ。
grep -f find結果 tree結果 とか。 # 本気にしないように。
基本的にはtree | grep なんちゃら でいいんじゃね?
画像の特定の領域だけを一括でぼかしたいのですが いい方法はありませんか?
つ netpbm
つimagemagick
メールアドレスの@以降の最後の国を表すCountry Codeの部分だけを抜き出すには どのような正規表現を使えば良いでしょうか? @hotmail.co.jp の.jp の部分を見る感じです。 .jp以外は無視する、という感じです。これで日本のメールしか相手にしない事になりますよね。
spam避け? 日本からも.comや.netや.orgや.infoや.bizや.acや.tvや.toや(以下略)の アドレスでメールが送られることはあるぞ。
$.jp ↑これでいいんでしょうか?正規表現全く知らない状態でネットでちょっと検索してみたのですが・・・
あっちゃー、そうなんですか・・・ 海外のメールを相手にしない方法って無いんですかね・・・ 英語でViagraとかうるさいんですよ。
/[あ-ん]/? ひらがながないメールは無視してもよかろう。
ヘッダの Content-Type を見て弾くとかどうよ? ^Content-Type: .*iso-2022-jp
最近はutf-8なのも多いよ。
utf-8 は違法で、危険運転致死罪が適用になるんじゃ?
テキストファイルを、最後の3行を除いて出力したいのですが 何か良い書き方はないでしょうか。 sed '$d' xxxx | sed '$d' | sed '$d' と書くくらいしか思い付かなくて。
>>444 head -n -3 foobar.txt
awk '{a[NR]=$0}END{for(j=1;j<=NR-3;j++) print a[j]}' a.txt
>>445 head のオプションは見落としてました…ありがとうございます
448 :
login:Penguin :2008/01/16(水) 21:56:01 ID:KAlEWwYc
ランダムな数字が欲しいとき,どうするのが簡単? 1. $$ 2. $RANDOM 3. /dev/urandom 4. 時計 あたりを思いついたんだけど
ワシは、ランダムな数字の用途により生成手段を変えてるような気がする。
1. 偏りそう 2. bash依存 3.4. 面倒 という問題点があるから,誰かいい方法教えてくれないか?
>449 たしかに用途によって求められる強さが違う気がする. とりあえずこうしとけ的な汎用的な方法はないんかな. いちばん手軽な方法が知りたい
>>448 $$はスクリプト内で複数個必要だと使えない罠
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 %
jotはたぶんBSD系限定だよな。 jot -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' ' とかで削るか。
>452,453 なるほど.date +%Nはいい感じ. jot便利そうだよ,jot.犬にもこんなの欲しいな. ありがとう
od -t u1 /dev/urandom | awk '{print $2;exit}'
r=`fortune | md5sum - | sed 's/^¥(........¥).*/¥1/'` r=`printf %d 0x$r` ごめんなさいごめんなさい。
普通に perl -e 'print int(rand(1000))' じゃダメなの?(perl5前提だけど)
>457 これだけのためにperlやawkを出してきたくないという貧乏心があってwww
時は金なり、というじゃない
つーか、乱数ってこれだけのため、っていうほど簡単なものじゃないと思う。 そういうものが必要な処理はシェルじゃなく、ちゃんとそれなりの言語でプログラムしたほうがいいかも。
確かに簡単な乱数ならともかく、ちゃんとした乱数が欲しい処理は言語引っ張り出したほうが良いかもね
% 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.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% (゚д゚)
% od -t u1 /dev/urandom \ | 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は、ばらつきはともかく遅いな...
遅いのは date +%N じゃなくて while のループだと思うよ。
>>450 > 2. bash依存
ksh88由来らしい
tp://www.cs.princeton.edu/~jlk/kornshell/doc/man88.html
ksh互換を期待できるなら使ってもいいんじゃね
/usr/games/random -e 100; echo $? は?
>>466 /usr/gamesってそれ何年前のWSのディレクトリ構成だよ...
findの検索結果でディレクトリの場合は最後に「/」をつけさせたいのですが、いい方法はあるでしょうか?
find . -exec ls -Fd {} \;
>>468 find (検索ディレクトリ) -type d -printf "%p/\n" -or -print
>>467 最新のLinuxの(いやほんと。これだけは伝統的理由で残ってるのかな)
>471 鳥は?
>>472 Debian (sid)。まあ bsdgames とかまんまレガシーなパッケージだけだけどね。
Debian etch にも/usr/games はあるな。 中みたらbannerとfortuneが入ってた。
シェルスクリプトの本で実用例の多い本ってありませんか?
476 :
login:Penguin :2008/01/19(土) 17:07:33 ID:NuJUp+KH
Fedora4を使っています /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行にする考え方でいい方法を教えていただけないでしょうか よろしくお願いいたします
cat /tmp/test.txt | awk 'NR%4{printf("%s,",$0)} !(NR%4) {print $0} ' 余りが出たら最後カンマ付きで出力されちゃうけど
478 :
login:Penguin :2008/01/19(土) 18:55:41 ID:NuJUp+KH
>>477 完璧な物ありがとうございます
今迄sedばかり使っていたのですがawkすごいですね
awkの勉強させていただきます
>>477 あらupしようとしたら同じだったわ。
awk '{printf"%s%s",$0,(NR%4?",":"\n")}' < start.txt
>>479 ありがとうございました
とても参考になります
vi start.txt q94J↓q10000@9 :%s/ /,/g :w end.txt
>>482 なんでだろうね?
FHS誤解してたかと読み直したらそんなことないし。理由がわからん。
ごめん上は嘘。Debian Policy には As 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作っていいと 書いてあった。
FHSとかグローバリゼーションとか国際化とか そういうのが全て悪の元凶。
FHSは/usr/localと/etcを綺麗にしてくれる。 それだけでも推進されてしかるべき。
/usr/gamesはオプションなのに、/usr/local/gamesは必須扱いなところを見れば分かるとおり ディトリビュータはゲームなんか提供すんな、ということなのだよ。 つまりゲームを提供しているDebianは人々を堕落させる悪のディストリビュータなのだ!
>>487 なにその陰謀史観(w
単に /usr/ 直下はディストリの管轄だし自分で決めろ、
一方で /usr/local/* は空フォルダ切っておく以上は認められないから
代わりとして、せめて誘導できるように切っておけ、ということかと。
FHSで自分的に従来慣習と比較して見慣れないのは/srvだな。
どこのUNIXでの慣習だったんだろう?
つっこみどころは /usr/games/bin/fortune じゃなくて /usr/games/fortune ってとこじゃなかったのかー
>>476 sed ':b;1~4,+2{N;s/\n/,/;bb}'
sedも心の片隅にでも置いておいてやってくだされ。
>>489 管理者のPATHからゲーム関係を除外するのが目的だろうから
/usr/games/binとサブディレクトリを掘る必要はないんじゃね。
>>490 そんな記法初めて見た…
どうなってんの???
アドレス指定がGNU拡張?
>>476 paste -d, - - - -
paste も心の片(ry
次のようなファイルがあるとします。 $ 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 としましたが、空白が表示されるだけでした。
>>496 ありがとうございました。
ぐぐるまでもヘルプ読むまでもなく、
適当にいじっただけでそうなりました。
gawk '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 gawk '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 ファイル数に制限はない。あと出力される行数は、最後のファイルの行数によって決まってしまうがな。
ランダムに壁紙を表示するスクリプト作ってみました 一応予想通りに動いてるようですが問題点や改善点があったら叩いてくだしあ #!/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
>>499 そのままだと画像ファイル名やパスに空白があると動かないけど、いいのか?
#!/usr/bin/python import 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)) # 高級言語って素晴らしいね
>501 ちょwwスレタイwww 修正してみました #!/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"
>502 事故レス expr はクオートしちゃまずかった
個人的には NUM= 以降を配列でやらせることが多いので、わりと bash を使う。 #!/bin/bash DIR=$1 IFS=' ' TARGET=(`find "${DIR:=.}" -maxdepth 1 \( -name '*.[Jj][Pp][Ee][Gg]' -o -name '*.[Jj][Pp][Gg]' -o -name '*.[Pp][Nn][Gg]' \)`) if [ ${#TARGET[@]} -eq 0 ]; then echo "No files found in ${DIR:=.}" exit -1 fi #echo ${TARGET[`expr ${RANDOM} % ${#TARGET[@]}`]} bsetbg ${TARGET[`expr ${RANDOM} % ${#TARGET[@]}`]} とか。
>>504 おまいさんの find には -iname は無いのか?
あと、bash なら自前で算術計算できるよ
bsetbg "${TARGET[RANDOM % ${#TARGET[@]}]}"
>おまいさんの find には -iname は無いのか? あ、これは知らんかった。有り難う。 >あと、bash なら自前で算術計算できるよ こちらは知っていたけど、元ネタに合わせんと。
#!/bin/sh filesize=('du -h ~/file.tmp') $loglen > ~/filesize.txt という感じでfile.tmpのファイルサイズを出力したいのですが 出力結果に不要な部分があります。 欲しい部分だけ切り取るには、どうすればいいでしょうか? よろしくお願いします。 100k /home/user/file.tmp ~~~~~ ~~~~~~~~~~~~~~~~~~~~ ↑ ↑ 欲しい 要らない部分
#!/bin/sh filesize=('du -h ~/file.tmp') $filesize > ~/filesize.txt 間違えてしまいました。こんな感じです。 grepで抽出するオプションの書き方も思い付かず スクリプトで処理するには・・・?と、行き詰まってます。
>>509 ヒントありがとうございます。
使い方を調べてみます。
>>509 もう少しヒントをください。
cat と coreutils のどちらかを使うや
cat か coreutilsのどちらかを使うかや
レスの意図を示していただけるとありがたいです。
シェルスクリプト歴数時間で理解が及ばなく申し訳ないです。
>511 ちょっとでもぐぐってみたのかと. あと猫じゃなくて切るほうな.
>>512 調べてみたのですが、広範囲になってきて混乱してきました。
今のところ
cat -Tというオプションと、rtというコマンドを発見して
コンソール上で
du -h /home/user/file.tmp|cat -T|tr "^I/home/user/file.tmp" " "
とすると、ファイル数だけ表示されるようになったので
うまい方法でもないような気もしつつに
#!/bin/sh
filesize=('du -h /home/user/file.tmp|cat -T|tr "^I/home/user/file.tmp" " "')
$filesize > ~/filesize.txt
としてみたのですが
$./filesize.sh
↓うまく実行できずに困っています。
du: invalid option -- T
du: invalid option -- |
du: invalid option -- t
du: invalid option -- r
詳しくは `du --help' を実行して下さい.
>513 catじゃなくてcut.たぶんこれ一発でやりたいことはできると思うから調べてみな.
>>512 ,514
ありがとうございます。
素で間違えていました。
調べてみます。
stat -c %s ではだめなのか
コンソールで
$ du -h /home/user/file.tmp|cat -T|cut -d ^ -f 1
としたらうまくファイルサイズだけ切り出せたので
#!/bin/sh
filesize=('du -h /home/user/file.tmp|cat -T|cut -d ^ -f 1')
$filesize > ~/filesize.txt
と、してみたのですが
なにか基本的な構文がおかしいのでしょうか?
バックスラッシュやシングル、ダブルクォーテーションを試してみましたが回避できません。
↓
du: invalid option -- T
du: invalid option -- |
du: invalid option -- u
du: invalid option -- t
du: invalid option -- d
du: invalid option -- f
詳しくは `du --help' を実行して下さい.
>>516 ヒントありがとうございます。
調べてみます。
>>517 これでいいだろ。
du -h /home/user/file.tmp | awk '{print $1}' > ~/filesize.txt
>>518 調べたらawkは強力で、いろいろ使えそうです。
出力も当初の予定通りで完璧でした。
ありがとうございます。
結果を変数に代入出来なくなりましたが、構文を参考に
>>517 を直したら同様の出力結果で動きました。
#!/bin/sh
du -h /home/user/file.tmp | cat -T | cut -d ^ -f 1 > ~/filesize.txt
>>516 >>518 さんを参考に手を入れたらキロバイト表示もできました。
ありがとうございます。
ただ、数字の後ろに「k」を入れる方法が判りませんでしたが。
#!/bin/sh
stat -c %s /home/user/file.tmp | awk '{printf "%s" ,$1/1024}' > ~/filesize.txt
>>519 stat -c %s /home/user/file.tmp | awk '{printf "%sk" ,$1}' > ~/filesize.txt
columnコマンドがない環境でインデント合わせをしたいのですが、 何か良い方法はあるでしょうか?
lsコマンドで、ファイルのatimeやctimeを取得する方法はあるでしょうか。 HP環境なので、Linuxのstatコマンドがなくて途方にくれています。
ファイルから目的の行を削除して上書きしたいとき, sed -e 2d file >tempfile mv tempfile file のようにすればできるんですが,テンポラリファイルを使わない方法はありますか?
リダイレクトとサブシェルを駆使してうまいことinplace editをやる技が あったはずなんだがどうやってぐぐればいいかわからん。
つ named pipe
こんな感じのやつか? $ echo hoge > hoge $ (rm hoge; (echo fuga; cat) > hoge) < hoge 要はサブシェルに開かせておけば中で上書きしても内容は デスクリプタから参照できるからそれでin-place処理できるって奴だな。 上は手抜きだけど、どっかのFAQにデスクリプタ付け替えまくりの例題が 載ってたのだけ覚えてる。csh-whynot文書あたりかも?
おおう、そんなかんじだったかも。thx
すいません ちょっと今シェルの作り方で困っているのですが やりたいことは 一つのフォルダに入っているファイルを、ファイル名によって3つのフォルダに振り分けたいのです。 その際に、どのファイルをどのフォルダに移動するのかはシェルの中に記述するのではなく、 ファイル名の一覧が書いてあるtxtファイルを一行ずつ読んで振り分けたいのです。 ですが、作り方が今いちわかりません。 例えばA,B,Cと分かれていたら 1、Aのフォルダに振り分けるファイル名が書かれたtxtファイルを読む 2、同じファイル名がヒットしたらAに送る 3、次にBのフォルダに振り分けるファイル名が書かれたtxtファイルを読む 4、同じファイル名がヒットしたらBに送る ファイル名が書かれたtxtファイルはA用B用C用の3種類用意します。 どうやって作ればいいのでしょうか?
シェルの作り方なんぞ知るかい。
宿題は自分でやれ。
>531 testコマンドでググレカス ファイルの読み込み方すらわかんねーなら本一冊買って出直して来い
うわー
冷たい
しかも叩く時だけは一気にレスがつくんだね
>>532 >>533 わからないなら無理にレスしなくていいです
さいきんの、このバカの質問な感じのには >>わからないなら無理にレスしなくていいです に類する文言が書き込まれる率が高いな、て思えるんだが、これは 1. この手のバカは結局バカだから、おなじようにしか考えられない 2. 実は同じヤツが何度も釣りに励んでいる のどちらか、ということだろうか?
シェルを作るのは結構高度な作業だからな。
>>536 真・教えて君養成マニュアルとかがどっかにあるんじゃないか?w
>537 最近はGUIの環境もシェルと呼んだりするらしいしね. ところで,シェルスクリプトをシェルと略す感覚が信じられない.せめてスクリプトのほうを残すべきじゃないのか,意味的に…
>>539 GUIのシェルってのはそう最近でもないと思う。
DOSSHELLとか、X68kのVS.Xとかあったじゃないか。
>>531 うわーきもい。シェルを作るという表現はおかしい
シェルの作り方って、VBの作り方、Javaの作り方
聞いているのと同じ。それをKY言うのは異常。
for文とifを組み合わせれてループさせれば。
>>535 >わからないなら無理にレスしなくていいです。
たぶんここの人は9割以上わかっていると思う。
やる気がおきない。 態度の豹変に腹が立つ。 mv -i `neko a.list` a mv -i `neko b.list` b mv -i `neko c.list` c
>>544 単純にnukoするよりもls -1 | grep -f a.list
とかしてより分けた方が良くないか?
546 :
login:Penguin :2008/01/31(木) 19:50:10 ID:/M27f8ta
for 変数名 in 10 20 30 do echo $変数名 done この構文の変数名ってなんでもいいんですか? あとこれを実行すると 10 20 30 になりますよね?
>>546 変数名に使える文字は英字と数字、アンダースコアのみな。
すると、うちのbashはおかしい。。。 $ for 9_var in 10 20 30; do echo $9_var; done bash: `9_var': not a valid identifier
もしかして
>>351 ==
>>548 なんか?
こんなところで釣りなんかすんなよ...
もし釣りじゃなくってバカなんだったら、せめてmanするとかググるセンセに聞くとか、な?
550 :
548 :2008/01/31(木) 22:00:40 ID:m8vTasa1
>>550 う゛、勘違いとかtypoとか。いかんな、落ち着かんと。
でもってマヂレスしとくと、変数の1文字目は数字じゃダメな。
kakikomi.txtというテキストファイルがあったとします。 STRING1 を含んでいて、かつ STRING2も含んでいる行だけを 印字しようとおもうのですが、 grep STRING1 kakikomi.txt| grep STRING2 くらいしか思いつきません。二度手間な気がします。 もう少しいい方法ありませんか?
>552 -e
>>552 それ前スレ(UNIX板のほうだったかも試練)で話題になったな
「STRING1とSTRING2を『順不同で』含む行をイッパツで引っ掛けようとしたら
egrep '(STRING1.+STRING2)|(STRING2.+STRING1)'
となってしまう。2個ならまだいいが、3個、4個...と増えていくと正規表現がキモいことになってしまう。
順不同という条件なら、
>>552 のやり方が一番シンプル
awk '/STRING1/&&/STRING2/' kakikomi.txt とか。
>>554 ,555
ありがとうございました。
最近暇なので本でいろいろ勉強してみます。
557 :
login:Penguin :2008/02/02(土) 02:58:37 ID:jQtmOvcu
例えばここに置いてある松金洋子のデスクトップ用壁紙画像をターゲットとする。
http://www.sexydesktop.co.uk/youko.htm ここには全部で4ページ分48種類の松金洋子の画像がある。
## このサイトの画像はすべてデスクトップ用の壁紙を目的としているので、
## 一つの画像に関して数種類の解像度・縦横比の画像が用意されており、
## アクセスしてきた人の使っているディスプレイ解像度を検出しては、
## 最適な解像度のものを優先的にプッシュするようになっている。
## また、画像ファイルの命名ルールは非常に単純かつ形式的で、
## たとえば例に挙げた松金洋子の画像の場合、
## まず画像の名前を表す youko1 から youko48 までの48種類の画像が用意されている。
## さらにそれぞれの解像度を表す 1280x800 や 800x600 の文字列が続き、
## 最後に拡張子 .jpg が付けられている。
## 注意する点があるとすると、例えば youko48 に対して youko01 だとか、
## 1280x1024 に対して 0800x0600 といった「桁数合わせ」が一切行われていないということ。
558 :
557 :2008/02/02(土) 02:59:35 ID:jQtmOvcu
ここから先が質問。やりたいことは、 1). サイトがプッシュしてくるこちらのディスプレイ解像度に関係なく、 すべての画像について、解像度のより大きいバージョンを、 番号の一番若いものから古いものまで全種類取って来たい。 2). その際、取って来た画像のファイル名を修正して、 youko48 に対しては youko01 、1280x1024 に対して 0800x0600 などの「桁数合わせ」をしたい。 3). さらに、ファイル名の中の画像名を表す文字列と、解像度を表す文字列とを _ で結ぶようにしたい。 具体的には、youko11600x1200.jpg と名付けられた youko1 という画像の 1600x1200 版のファイル名を、youko01_1600x1200.jpg としたい。同様に、youko481280x1024.jpg と名付けられた youko48 という画像の 1280x1024 版のファイル名を youko48_1280x1024.jpg としたい。 以上をまとめると、参考例の松金洋子の画像で言えば、 youko11600x1200.jpg から youko481280x1024.jpg までの画像を、 youko01_1600x1200.jpg から youko48_1280x1024.jpg として保存したい。 これを実現するスクリプトをどう書けばいいでしょうか? なお、好みのタレントの画像が何種類用意されているか(松金洋子の場合は48種類)については、 ダウンロードを開始する前に手作業で調べることとします。
560 :
557-558 :2008/02/02(土) 03:17:30 ID:jQtmOvcu
んー、俺はスクリプトに無知だから、一から十まで全部取って来て、 後で手作業で仕分けする、みたいな超バカなことしかできんのです。 だからエロい人に教えてほしいんです。。 ダメならヒントだけでもいいので下さい。
地道にループ回すしかないのでは たぶんリネーム関連はperlか何か使ったほうがラクじゃね?
2).3). youko0123456789x0123456789.jpg というファイル名はどのように整形すれば?
564 :
login:Penguin :2008/02/02(土) 10:16:29 ID:2Gx0/Giv
$cat test.txt aaaaaaaaaaaaaaaaaaaaaaaaaa +bbbbbbbbbb cccccccccccccccccccccccc +ddddddddddddddd 長い行は先頭に+をつけて折り返しているという内容のファイルを $cat test.txt aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbb cccccccccccccccccccccccc ddddddddddddddd というように+の折り返しを前の行の後ろに空白付で結合させるにはどうすればいいでしょう?
cat test.txt | tr '\n+' ' 'とかどう?
>>565 実行したら
$cat test.txt
aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbb cccccccccccccccccccccccc ddddddddddddddd
みたいになりましたが
$cat test.txt
aaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbb
cccccccccccccccccccccccc ddddddddddddddd
これが出力としてほしいです。
\nと+が別で判断されているのでしょうか・・・
間違った.cat test.txt | tr '\n\+' ' 'で.
ごめん,俺嘘ばっかり言ってるから気にしないでorz
>.567 同じ結果でしたw レスありがとう!
570 :
557-558 :2008/02/02(土) 10:50:34 ID:jQtmOvcu
>>563 どうもです。
えー、そういう名前のファイルは存在しないので考えてもみませんでした。
>>562 もし $name$no1024x768$suffix がある時 $name$no1024x0768$suffix にせよ、
みたいなことを延々とやる、ということなんでしょうか?(←無知)
うーん。。。
>>564 if 先頭が+じゃない then
echo ""
else
echo -n " "
fi
echo -n 行
>>564 sed 'N;s/\n+/ /;t;P;D'
/tmpにあるディレクトリをリストし そこからディレクトリ名だけを切り取りたいと考えています。 /tmpには a b c というディレクトリがあるとして $ find /tmp -type d -maxdepth 1 -mindepth 1 | xargs awk -F/ '{print $NF}' を実行すると a だけが出力されてしまいます。 望んでいる出力は a b c なのでうまく出力されるようにしたいです。 findのみを実行すると /tmp/a /tmp/b /tmp/c と出力されることは確認しました。 申し訳ないのですが良い方法をご教授ください。
find /tmp -maxdepth 1 -mindepth 1 -type d | awk -F/ '{print $NF}' find /tmp -maxdepth 1 -mindepth 1 -type d | sed -e 's/.*\///' find /tmp -maxdepth 1 -mindepth 1 -type d -exec basename {} \;
576 :
574 :2008/02/05(火) 19:21:21 ID:E60rvXpx
>>574 で実行したコマンドは
$ find /tmp -type d -maxdepth 1 -mindepth 1 | xargs echo | awk -F/ '{print $NF}'
の間違いでした。
よろしくおねがいします。
577 :
574 :2008/02/05(火) 19:22:58 ID:E60rvXpx
>>575 望みどおりの出力を得ることができました!
早い回答感謝します。
ありがとうございます。
すみません、次の表現ってどういう意味なんでしょうか ($Fはlsの結果が入る) if expr "$F" : '[[:alunum:]_-]\+$' > /dev/null 2>&1; then ... 特に : '[[:alunum]_-]\+$'の箇所が分かりません 自分で調べて分かったのは [:alunum:]が数値を表すPOSIX準拠の文字クラスであること :はヌルコマンド []が正規表現とすると[[:alnum:]_-]\+$は以下のいずれかという意味でしょうか 数値+$ _+$ -+$ だとしても前半の:とのつながりもよく分からないです..
そのコロンはexpr の引数であって、パターンマッチを行わせるもの。 ヌルコマンドではない。 [[:alnum]]_-]¥+$ は、 「英数もしくは _ もしくは -」([[:alnum]]_-])の繰り返し(¥+)で末尾になる($)パターン。 つまり$Fが↑のパターンにマッチするかで判断するif文だな。 出力を/dev/nullに捨てている理由は、exprの動作を調べればわかる。
>>579 ありがとうございます。やっと理解できました!
exprについては、nullまたは0を返した際に0を返すという仕様のため
/dev/nullに出力していることはすぐ分かったんですが
「:」もexprの構文だったんですね
ずっとシェルのパターンマッチの構文として「:」を調べていたため
ハマってました,thx!
リダイレクトで先頭5行目から行末から5行目前までを出力したいのですが、 ??? | head -n xx | tail -n xx 以外に良い方法はあるでしょうか
なにをしたいのか、君の示した例は本当に目的を満足してるのか、 もういちど確認した方がよいと思われ
では、headとtailは使わずに。 sed -n '5,$p' file.txt | tac | sed -n '5,$p' | tac …意義が見出せない。。。
584 :
581 :2008/02/08(金) 15:35:34 ID:aAYt8gpF
>>583 sedは習ってないので提出できないんですよ
他にないですか?
{ read a;read a;read a;read a;tac; } | { read a;read a;read a;read a;tac; }
習っていないと使えないって、そんな小学校じゃあるまいし
>sedは習wwwwってwwないのwwwで提出でwwきないんですよww >他になwwwwいですか?www のように、wを適当にまぶすスクリプトを誰か考えてくれ。
>>588 こんなwwのを作っwwwwてみたんwwだがww
どうだろうかwww
とりあえずwwwwちゃんwwと動いてるよwwうだがwwww
どんな例外wwがあるwwかわからんwww
#!/bin/sh
CHAR='w'
insertw() {
i=0
w=`expr $RANDOM % 3 + 2`
while [ $i -lt $w ]; do
i=`expr $i + 1`
echo -n $CHAR
done
}
while read LINE ;do
while [ "$LINE" ]; do
r=`expr $RANDOM % 6 + 2`
echo -n `echo $LINE | cut -c -${r}`
insertw
r=`expr $r + 1`
LINE=`echo $LINE | cut -c ${r}-`
done
echo ""
done
590 :
589 :2008/02/08(金) 21:45:59 ID:Z8wDJkcZ
初心wwww者でサーセンww $RANDwwwwOM使wwってるのwwwで本wwww当のshではww動かなwwwいはずだけど,wwwここはwwLinux板wwwってことwwwで許wwwwしてもらえるwwよね?
あの〜、正規表現についてお聞きしたいのですが [a-z]で小文字のアルファベット全てにマッチですよね。 ならば [あ-ん]でひらがな全てにマッチしますか?
yes
「ぁ」はマッチしないのでは? それはそうと、多バイト文字の正規表現って、大抵のアプリケーションで普通に使えるものなのか。 知らなんだ。
質問です。ファイルの対象部分に別のファイルを挿入するコマンドってありますか? % cat file1 aaa%sbbbccc % cat file2 ZZZ % hoge %s file2 < file1 aaaZZZbbbccc のような動作を期待しています。 挿入するファイルは少し長めなのでsedで置換ではできない気がしています。 awkあたりでfile1を%sが出るまで出力 -> file2を出力 -> file1の%s以降を出力 という方法を考えていますが、もし専門のコマンドがあれば教えてください。
595 :
594 :2008/02/10(日) 01:12:39 ID:bq0IfXwT
誤爆先でm4というのを教えてもらいました。 一旦使ってみます
596 :
login:Penguin :2008/02/10(日) 01:14:06 ID:AyxHcvsn
そういうのはエディタで
>>595 おまえFedoraすれにいなかったか?
>>594 printf "`cat file1`\n" `cat file2`
>>593 grep でやってみたらマッチしやがったよ。
文字列として検索できるということと、 全角文字も一文字として扱える、というのとでは意味がぜんぜん違う。
[あ-ん]と[\xe4\x1c-\xe4\x5f]ではまるで別物だしな(コードは適当)
#スレ違いだが。 MS-Windowsとの可搬性に最も富むスクリプトは何ですか? ただし、cygwin環境とperlは除外して。
>>602 awk,ruby,Python つーかなんでperlダメなの?
たしかにWinのperlめんどいけどね。
ディレクトリにあるmp3ファイルを1行に3つずつ番号付きで表示して 指定されたファイルを再生するスクリプトを考えてみました。 これだとファイル表示の見た目がいまいちなんですが、カラムを揃えて 表示するようなうまいやり方はありますか? i=1 for file in *.mp3 do #3カラムで出力する x=`expr $i % 3` if [ $x -eq 0 ] then echo -e "\033[1;31m$i\033[0m.$file" else echo -en "\033[1;31m$i\033[0m.$file " fi a[i]=$file (( i=i+1 )) done echo -n "number? >" read n if [ -f "${a[n]}" ] then mplayer "${a[n]}" else echo "ファイルがありません" fi
>>605 #!/bin/sh
FS=`zenity --file-selection`
#このままだと動画なんかもいけるけど、どうしても*.mp3のみにしたい場合は↑行を
#コメントアウトして↓行を有効にする
#FS=`ls *.mp3 | zenity --list --column "Files"`
if [ -z "${FS}" ]
then
exit
fi
mplayer "$FS"
なんつってってねw
zenityってなんだろーと思ってググったら……反則すぎ。
>>604 perl.exeの他に色々MS-Windows側に入れなきゃならないものがあるので可搬性に欠けるという理由を考えてみましたが、実は嫌いなだけです。
>>605 3列にこだわらないのなら、bashのselectはどうでしょう。
#!/bin/bash
select name in *.mp3
do
echo "mplayer ${name}"
#break
done
>>605 printf で頑張るという選択肢もある。
610 :
605 :2008/02/15(金) 19:02:00 ID:BuE7cyMU
>>605 の件ですが、レスしてくれた方々、ありがとうございます。
selectを使うのが簡単でイメージどおりなので、それでいきたいと思います。
久しぶりに来たけど相変わらず キモいね
シェルに閉じこもってるスレですから
ちょっとは環境変数も気にしろよ
export KIMOI=false
$ export KIMOI=false > if [ $KIMOI ]; then > echo kimoi > else kimokunai > fi kimoi となります.助けてください><
釣られてやるが if $KIMOI; then
いやいや、キモイとかキモクナイを超越することこそが答なのだよ。 export KIMOI= が正解なのだ。
/usr/bin/[≒/usr/bin/test
>>618 if文やwhile文の条件部に書くのは、実はコマンド。
コマンドの終了コードが0なら条件が成立したとみなされる。
で、true(0を返す)やfalse(1(非0)を返す)というコマンドがあるわけだな。
ちなみに [ もコマンドだ。
みんな釣られ過ぎ… $KIMOIに"false"という文字列を代入してるだけ。
629 :
login:Penguin :2008/02/18(月) 07:12:54 ID:AGIm4SRV
zenity でファイルの選択をさせるのに、最初に任意のフォルダを開くにはなんと書けばいいのか教えて下さい。
カレントディレクトリを開くみたいだから、サブシェルを使ってこんな感じでどうかな (cd /; zenity --file-selection)
631 :
login:Penguin :2008/02/18(月) 13:16:10 ID:AGIm4SRV
>>630 ありがとうございます。
やってみます。
シェルスクリプトを覚えるとなにが出来るようになるんですか?
>>632 ルーチンワークで楽できる(場合がある)
>>632 作業の自動化や、例えばユーザを100人登録しないといけないとか言う、膨大な作業を
物凄い速度で短時間で終わらせる事が出来るようになるとか。
ほほうって、コンピュータに仕事をさせるという観念のない人なんだろうか。 高級な紙と鉛筆だとしか思ってなさげな人。たまにいるけど……。
魔法の箱だと思ってるよりマシだと思う
コンピュータは ある機能を実現させる為の方法(アルゴリズム)を示してやれば どんなにそれが重労働だろうが難しい計算をしないといけなかろうが、 忠実に高速かつ正確、大量に実行させる事が出来るから凄いよ・・・。 ただし、その仕事の仕方を教える(アルゴリズムを教える)のがかなり苦労するんだけどな・・・。
基本的に人間がやってもできることを高速ですることしかできないということを知らない人が多すぎる
それは、一秒間に3ギガ回も足し算したり、地球の裏側に光の速度で手紙を届けたりなんつーのは
基本的に人間には絶対できない、ということを知らない者は
>>639 だけだというだけの話かと。
君も頭悪いな。 639は高速で、と書いてあるんだから、「速度を問わなければ」人間が…と 読むのが妥当という答にしかならないぞ。 どうせそういう突っ込みするなら空間計算量でやればよかったのに。
理論ばっかりのたまって生産性の無い人ってよくいるよね。
まとめ。 Q) シェルスクリプトを覚えるとなにが出来るようになるんですか? A) 理論ばっかりのたまって生産性の無い人ってよくいるよね。
>>632 シェルスクリプトでやりたいと思ったこと。
俺は…彼女にパイズリして欲しいな…。 乳はAAだけど orz
>>645 基本的に彼女ができないことなのでシェルスクリプトでもできません。
>>647 AAでもいいということなので,アスキーアートでおっぱいを表現することならシェルスクリプトで可能です
さらに最近のターミナルエミュレーターはアンチエイリアスがきいてるのでなめらかですよ
すごいな。
>>641 は地球の裏側に手紙を届けたりなんてことが「ゆっくりならできる」そうだ。
できるというなら精々一生をかけて歩いて船をこいで手紙を届けにいって、それを証明してほしいものだ。
コンピュータという人間が使うモノが、人間以上の方法(アルゴリズムなどの知性)を知らないのは当然のことだが
最近ではその知性すら、コンピュータを使ったシミュレーション解析などで
得ることが増えているのが現実だったりするわけで。特に知の最先端ほどそうだ。
もはや人類はコンピュータを使わないと新しい知識を得ることすら「できない」状況なんだけどね。
そういう現実が見えない人はやっぱり自分の納得を唯一の判断基準とする文系人かな。
人間は遠くのものが見え、遠くの人と話し、より多くの知識を得、共有できるようになった。
100年前に比べたら、ほんとうに夢の魔法かコミックの世界だ。コンピュータはほんとに魔法の箱みたいじゃないか。
そのセンスは逆にあまり間違っていない気がするけどな。
「高度に進んだ科学技術はもはや魔法と見分けがつかない」アーサー・C・クラーク
>>649 日本語でおk
電報というものがあるんだが最近のゆとりは知らないのか?
ゆとり言いたいだけちゃうんかと
ネタはよそでやっとくれよ。
このスレの
>>640 や
>>641 の意見が興味深い。面白いな・・・。
>>648 そういうシェルスクリプト作って公開してよwwwwぜひ実行してみたい・・w
>>649 こういう無駄な長文を書ける才能には素直に感心するよ。
時間を持て余してるんだろ?
ある意味うらやましい知性だ。
slコマンドってなかった?画面いっぱいにSLを表現 あれはシェルスクリプトではないから違うか・・・。
>>658 つ www.tkl.iis.u-tokyo.ac.jp/~toyoda/
bashです。 cdするたびに一緒にlsもして欲しいんですが、どうやって書いたらいいでしょうか? aliasだとうまくできないです。
alias cls='cd $1 && ls'
clsといったらCLear Screenだろうに
そうなのか。うちにはそんなコマンドないって言われたもので。
そりゃDOSのコマンドだからな。
>>661 できないみたいです。
カレントディレクトリが切り替わりません。
>>665 うちでは動作確認したんだが・・・なんでだろね。
あ、ほんとだ、切り替わらないねw
PROMPT_COMMAND='if [ "$PWD" != "$PWD2" ]; then ls; PWD2="$PWD"; fi'
>>667 ぢゃあ関数にしちゃうとか。
function cls {
cd $1 && ls
}
cdはシェルの内部コマンドだから親プロセスには反映されないんだねえ。 #!/bin/sh cd $1 ls として、foo.shとして、 alias cds='. foo.sh' かなあ。動作確認はしたw
できればclsじゃなくてcdでやりたいです。
>>669 ,670 でcdにするとなぜか動かない。
でも参考になりました。
>>668 わかんないです。
#!/bin/sh 'cd' $1 ls として、foo.shとして、 alias cd='. foo.sh' でできました。(・∀・)イイ! ありがとう。
cd() { builtin cd $1 && ls }
( ゚д゚)……
>>673 ビルトインか。やっぱりman読まないとダメだな。
ありがとう。
ほう、すげっ
668は逆にわかりやすいと思うが・・・なぜ分からぬ
>>659 slねぇ・・・Vine 3.2だとmakeしてもエラーが出てmake出来ないんだけど・・・?
apt-get install build-essential は入ってる環境です。
>>673 cd に -P とかオプションつけると機能しなくなるぞ。
cd() { builtin cd "$@" && ls; }
>>673 ,
>>681 それしばらく使ってみるとわかると思うけど、
そのままではナイーブすぎて少し不便だよ。
zshで同じようなことやってるけど、次の点は考慮した方がいいです。
・サブシェルで実行されたときにはlsしない
・行数が多すぎるときは適当な長さで切り、省略した旨を表示
同一内容のファイルを調べるシェルスクリプトなんだけど、過去にここかUNIX板の方で出てたっぽい。 結局やらず仕舞いだったようだし、どうせならシェルスクリプトの勉強がてらやってみようとおもった。 作りたい理想は以下のとおり ・コマンドラインでオプション指定を行い、検索ディレクトリとサブディレクトリへの再帰検索をするかどうか、あとファイルサイズ閾値を指定できる ・走査しているディレクトリにあるファイルパス&ファイルサイズのペアをリストとして吐く ・ファイルサイズ閾値未満で、ファイルサイズが一致したものに対してmd5sumを実行し、両方が同一のハッシュを吐いた場合、表示する。 ・ファイルサイズ閾値を設定する理由はmd5sumが時間がかかりそうだから。閾値以上のサイズ一致ファイルはmd5sumすることなく表示する。
ちなみにサブディレクトリの再帰検索をせず、指定したディレクトリの全てのファイルのハッシュ値を比較して表示するだけなら #!/bin/sh md5sum $1/* | uniq -D --check-chars=32 | sed 's/^[0-9a-f]* \*//g' 上のだけで済むかな。標準エラーがうざいけど・・・ まずはディレクトリの再帰検索について質問したいところです。
あ、uniqの間にsortを入れてあげるとより親切か うちの場合はwgetで自動保存したファイルの整理だから、ファイル名が必然的に「DLファイル名+.連番」だから気にならないけど まったく違うファイル名かつ内容は同一ってときに、ハッシュ値でsortしてあげていた方がいいよね そう考えたらsedでハッシュ値をわざわざ消す必要もないか・・・ md5sum $1/* | sort | uniq -D --check-chars=32
再帰検索はこの場合、find $1でファイルリストを列挙してからreadで"ls->ファイルサイズ取得"やら"md5sum"やらした方がいいのかな?
不恰好だけどサブディレクトリまで調べて、全てのファイルにmd5sumして表示するのはこんな具合か・・・ #!/bin/sh TMPFILE="filelist" touch $TMPFILE find $1 | while read FILENAME; do if [ -f "$FILENAME" ]; then md5sum "$FILENAME" >> $TMPFILE fi done sort < $TMPFILE | uniq -D --check-chars=32 rm $TMPFILE もうちょっとスマートにならないかなあ・・・ あとユニークなサイズのファイルはmd5sumさせたくないなあ
書いてみた。 #!/bin/sh # finddup.sh -- find . | finddup.sh while read -r FILENAME do [ -f "$FILENAME" ] && printf "%14d:%s\n" `stat -c %s "$FILENAME"` "$FILENAME" done | sort | uniq -D -w14 | cut -b 16- | xargs md5sum | sort | uniq -D -w32
uniq -f のほうが良さそうだね
>>687 find . -type f -print0 | xargs -0 md5sum | sort | uniq -D -w32
>>688 ありがとう!
あ、ただファイルやディレクトリ名にスペースが入るとmd5sumにしっかり渡せないみたいです
bash on cygwin環境だとWindowsの「コピー (2) 〜 hoge.txt」という名前が恨めしい
>>690 出力結果同じだΣすげえ
ちょっとman読んでこよう・・・
xargs --delimiter " " md5sum でどうかな。ちゃんとテストしなきゃだめだね まあ改行文字を含むファイルがあるとだめなんだけど、面倒だから他の言語でやらせたほうがいい
>>693 全部のファイルにmd5sumかけたら遅いだろ
あ、
>>688 のxargs md5sumを
>>690 のようにxargs -0 md5sumにすればOKなのかな
>>695 んで、printf 側でも \n じゃなく \0 を使うようにする。
uniqとcutはどうするよ
printfで囲ってやればイケました(`・ω・´) #!/bin/sh # finddup.sh -- ./finddup.sh target-path find $1 | while read -r FILENAME do [ -f "$FILENAME" ] && printf "%14d:\"%s\"\n" `stat -c %s "$FILENAME"` "$FILENAME" done | sort | uniq -D -w14 | cut -b 16- | xargs md5sum | sort | uniq -D -w32
久々にまともな流れだな
ついでに以下のような動きが出来ないか色々試してみています。 どうも二進も三進も行かない $ ./findup.sh ~/pic/jun.2chan.net/ 2件の一致ファイル:8f7c1e2adb45adbfdb4d86adb1b9e894-------------------------- ~/jun.2chan.net/b/src/1192805081129.jpg ~/jun.2chan.net/b/src/1192805081141.jpg ------------------------------------------------------------------------------- ~/jun.2chan.net/b/src/1192805081129.jpgを削除しますか?[y/N/a] ~/jun.2chan.net/b/src/1192805081141.jpgを削除しますか?[y/N/a] y ~/jun.2chan.net/b/src/1192805081141.jpgを削除しました。 3件の一致ファイル:6fc4bdc4bc3bb06882bc98d9cbeb60c3-------------------------- ~/jun.2chan.net/b/src/1192800164913.jpg ~/jun.2chan.net/b/src/1194189136460.jpg ~/jun.2chan.net/b/src/1194189137115.jpg ------------------------------------------------------------------------------- ~/jun.2chan.net/b/src/1192800164913.jpgを削除しますか?[y/N/a] y ~/jun.2chan.net/b/src/1192800164913.jpgを削除しました。 ~/jun.2chan.net/b/src/1194189136460.jpgを削除しますか?[y/N/a] y ~/jun.2chan.net/b/src/1194189136460.jpgを削除しました。 ↑同一として列挙されたパスの残りが1になると削除せず次へ
>>700 そこまで行くとシェルスクリプトには荷が重いんじゃないか?
>>701 以下の点でハードルがあがってるみたいですね
・一致したファイルのグループ分け
・ファイルを一つだけ残して削除した場合、残りの1ファイルは削除しない
列挙した全ファイルに対して、質問→削除というのは簡単にいけそうな感じ。
自分の知識だけで無理と判断して投げるのはアレだと思ったんだけど、やっぱ難しいかなあ
#!/bin/bash # askdelete.sh -- find . | finddup.sh | askdelete.sh # よくテストされてませんので注意 TMPF=`mktemp /tmp/askdelete.XXXXXX` trap 'rm $TMPF' 0 CURHASH= COUNT=0 (cat; echo DUMMYHASH /dev/null) | while read -r HASH FILENAME; do if [ "$CURHASH" ] && [ "$CURHASH" != "$HASH" ]; then echo "------------------------------" echo "$COUNT 件の一致ファイル:$CURHASH" tail -n $COUNT $TMPF | cut -b 33- echo "------------------------------" tail -n $COUNT $TMPF | while read -r HASH FILENAME; do [ $COUNT -eq 1 ] && break echo -n "$FILENAME を削除しますか? [yN] " while read ANSWER do case "$ANSWER" in [yY]) echo rm "$FILENAME" COUNT=`expr $COUNT - 1` ;; esac done < <(head -1 /dev/tty) done COUNT=0 fi echo $HASH $FILENAME >>$TMPF CURHASH=$HASH COUNT=`expr $COUNT + 1` done
done < <(head -1 /dev/tty) とか、絶対おかしいよこれ。 違う言語で書き直したほうがいい。
おおすげええΣ ちょっとテストしてみます!
#!/bin/sh
# askdelete.sh -- find . | finddup.sh | askdelete.sh
TMPF=`mktemp /tmp/askdelete.XXXXXX`
trap 'rm -f $TMPF' 0 1 2 3 15
CURHASH=
COUNT=0
(cat; echo DUMMYHASH /dev/null) |
while read -r HASH FILENAME; do
if [ "$CURHASH" ] && [ "$CURHASH" != "$HASH" ]; then
echo "------------------------------"
echo "$COUNT 件の一致ファイル:$CURHASH"
tail -n $COUNT $TMPF
echo "------------------------------"
tail -n $COUNT $TMPF | while read -r FILENAME; do
[ $COUNT -eq 1 ] && break
echo -n "$FILENAME を削除しますか? [yN] "
while read ANSWER; do
case "$ANSWER" in
[yY]) echo rm "$FILENAME"
COUNT=`expr $COUNT - 1` ;;
esac
break
done < /dev/tty
done
COUNT=0
fi
echo $FILENAME >>$TMPF
CURHASH=$HASH
COUNT=`expr $COUNT + 1`
done
すこしよくなった
参考になる
http://www.nurs.or.jp/~asada/FAQ/UNIX/section3.8.html
理想的な流れだ。
>>706 サブシェルをわざわざ使う必要は無いのでは?
--- (cat; echo DUMMYHASH /dev/null) |
+++ { cat; echo DUMMYHASH /dev/null; } |
こんなのじゃ駄目? find . -type f -print | xargs md5sum | sort | while read i do set -- $i test -e .$1 && rm -i $2 touch .$1 done 削除して残りが1つなら消さずに次、ということは最初の1つは 無条件で残して、2つ目以降についてのみ rm -i で削除確認すれば いいんだよね? 記憶用に .<md5sum> なマーカ作ってるけど、ここは md5sum な ダミー環境変数の方がいいかも。
>>709 全ファイルにmd5sumしたら遅くならない?
>>708 パイプを使うと結局はサブシェルが起動されるんだから () のほうがわかりやすいと思うよ
>>710 どうせシェルスクリプトなんて使い捨てなんだし
多少遅くてもいいんじゃない?
実行時間の長さより
思いついたことをちゃちゃっと実行できる手軽さが大事でしょ。
>>712 もっともな意見だと思うが、肝心なことを棚に上げてるな
シェルスクリプトの本質は処理を効率化するための機能なんだから、
手軽に加えて「より早くスマートに処理」できる方がいいだろうよ
どうせ使い捨てとか言い出したら、いつまで経っても遅くて低機能なスクリプトしか書けないぜ?
まあせっかくいい方向で流れてるから、俺も最適化してみるか。
手作業で30分かかる作業を、わずかワンライン5秒で済ます。 どうよ、この快感、すごいよ、俺!! ただしスクリブト書きに3時間かかるけどなっ!!、 みたいな・・・・
5分で書いて実行時間3分にできればそれでおkだよな。 その作業を200回繰り返さなきゃいけないなら 3時間かけて書いて5秒に短縮してもいいけど、 そういうのはシェルじゃなくて別な言語を使った方がいいと思う。
>>714 良いスクリプトを早く書けるスキルを養うといった考えはないのかよw
まぁ価値観が違うなら仕方ないが
>>715 言いたいことは分かるし仕事では俺も同じスタンスだ。モトが取れない作業をするのはアホだと思う。
さらに
>>1 にあるようにPerlやPythonを使ってもいいと書いてあるように、別にシェルスクリプトに固執はしてないさ。
ただID:fTf5K0mTみたいに質問を丸投げせずに分かってないながらも自分で試してみている奴も居るんだから
「どうせ使い捨て」や「パンがなければケーキを」じゃなくて、しっかりした見本を見せてやろうぜw・・・と思ったんだ。
勝手に限界を作っちゃダメさ・・・!
頑張るところが・・・まっいっか。人それぞれだな。
>>717 茶化すだけならWindowsに切り替えてフリーソフトスレにでも行け。
同一ファイル発見ソフトなんていくつもあるから。
自分で作ろうと思わん奴はウザイだけだ。
Windowsに切り替えて同一ファイル発見ソフトを探すってのもこれまた手間だよな
ああそういう意味か。 Linuxならawkでもperlでもpythonでもgccでも大概入ってんだろうになんで >Windowsに切り替えてフリーソフトスレにでも行け なのかマジで理解できなかった。 なるほどな、そういう考え方もあるか。これは考えが及ばなかったな。 まぁうちext3だしなぁ。
>>711 サブシェル一個より分かりやすさを重視、ってのも分かるが
プロセスを fork するコストはバカにできないぞ。
たった 10 回でもこれだけ差が出る。
$ time for i in 0 1 2 3 4 5 6 7 8 9 ; do { :; } ; done
real 0m0.001s
user 0m0.010s
sys 0m0.000s
$ time for i in 0 1 2 3 4 5 6 7 8 9 ; do ( :; ) ; done
real 0m0.221s
user 0m0.140s
sys 0m0.140s
今回のはともかく、ループの中で無駄なサブシェル起こすと
かなり処理速度に効いてくるから、「より早くスマートに処理」を
目指すなら気にした方がいいと思うよ。
>>721 そうじゃなくて、パイプではサブシェルが起動されるでしょう?
$ { FOO=foo; echo $FOO; } | cat
foo
$ echo $FOO
$
>>722 popenってfork & execvじゃなかったっけ?
724 :
login:Penguin :2008/02/28(木) 01:04:44 ID:2c894vLr
$cat a001 abc $cat a002 def $cat a003 ghi という内容の連番ファイルがあるときに、 a001,a002,a003ファイルそれぞれの先頭に 自身のファイル名を追記していくにはどのようにすればいいでしょうか? $cat a001 a001 abc $cat a002 a002 def $cat a003 a003 ghi
for a in *; do echo $a > temp cat $a >> temp mv temp $a done
csvの編集をしているのですがカンマを含むデータがある場合に特定の列を削除するいい方法はないでしょうか? 例: 編集前) aaa,bbb,"ccc,ddd","eee",ff 編集後) aaa,"ccc,ddd",ff カンマを含むデータは必ずダブルクォーテーションで囲まれているのですが どの列にカンマを含むデータが存在するかは不明です。 192の方法だと特定の列は出せるのですが、複数列を表示することができないので。。。
>>727 無駄にがんばってみた。PerlとかSQLiteとか使った方が絶対いい。
#!/usr/bin/awk -f
BEGIN {OFS=",";}
function csplit(s,a,c,f,i,j,k){delete a;for(i=j=1;;i++){
c=substr(s,i,1);if(c==""){a[k++]=substr(s,j,i-j);break;}
else if(c=="\""){if(f>0){if("\""==substr(s,i+1,1))i++;
else f=0;}else f=1;}else if(c==","&&f==0){a[k++]=substr(s,
j,i-j);j=i+1;}}return k;}
{n=csplit($0,array);print array[0],array[2],array[4];}
吐きそうだ。 字下げを知らないやつがまだこの世にいたのか。
死ぬまで
>>729 記法で頑張りゃいいんじゃね?
それも個性だ。
敗北宣言はええ
2ch に貼る時気をつけないと空白スペース詰められちゃうよね
そこで&nbsp;
行末にタブがある行を検索しようと egrep '\t$' としてもマッチしません。awkだと awk '/\t$/' でマッチするのですが、grepだとどう書けばいいのでしょうか?
元々、\tなどのメタキャラクタはgrepにもawkにもなかった。 GNU awkがPerlの影響を受けて拡張しただけ。
そうなのかー・・・ちょっとしょぼーん。拡張されてもいい感じなんだけどね。 grep sed awk ぐらい正規表現は統一して欲しかったorz
タブを¥tと書きたかった理由が シェルからコマンドラインにタブを打とうとして補完機能に取られるから、 であれば、Ctrl-V TAB でたぶんOK。
くだ質からこちらに誘導されたので、こちらで質問させて下さい。 ド素人質問で悪いのですが $ cat text1.txt 1 2 3 $ cat text2.txt 3 4 5 という二つのファイルがあるとして、それを1行ずつ割り算したいのです。 結果としてこういう形になれば満足です。 $ cat result.txt 0.33 0.50 0.60 どのように記述すれば良いのでしょうか、シェルは普段bashを使っていますが、 もちろんshでも構いません。宜しくお願いします。
>>740 ぱっと思いついたもの。
( echo 'scale=2' ; paste -d/ text1.txt text2.txt ) | bc
>>741 早速ありがとう御座います。こんな結果になりました。
.33
.50
.05
(standard_in) 5: parse error
53
4
5
pasteってこういうときにも使えるんですね。
parse errorとかbcとか知らないものも調べてみます。
743 :
740 :2008/02/29(金) 09:58:48 ID:HrPH8ECW
>>741 すいませんでした、エラーは自分の不備によるものでした。
きちんと結果表示されたので満足しています。ありがとう御座いました。
スクリプトで2台のDebian間を rcp でコピーしようと思っています。 expect を使って、スクリプトを作成し、それがうまく動作するところまでは こぎつけたのですけれど、cronに登録すると動かなくなってしまいます。。。。 どうすれば解決するでしょうか?アドバイスをいただけると嬉しいです。 ちなみにスクリプトは ==========================- #!/bin/sh expect -c " set timeout 20 spawn rcp -r {コピー元} {コピー先} expect sword:\ ; send \"{パスワード}\r\" " ============================== こんな感じです。 ご教授のほどよろしくお願いします。
>>744 カレントディレクトリがどこになってるのか、とか
権限に問題はないか、とか。
つーか rsync あたり使った方が楽じゃない?
シェルスクリプトでは無いのかもしれませんが、今日2度目の質問をさせて下さい。。 スレ初心者なので、スレ違いだったらすいません。 LPIC試験の勉強のために初めてjoinコマンドを使うのですが、うまくいかず困っています。 1.txtと2.txtに、1〜999999の中から任意に500個程度選び出した数字を それぞれフィールド1に、その他データをフィールド2以降に並べた テキストファイル(↓こんな感じにソートしたのものです) $ cat 1.txt $ cat 2.txt 50 aiu 50 abc 1111 80 eoka 140 def 2222 ↓ ↓ 999999 wawon 531243 xyz 3333 があるのですが、フィールド1に同じ数字が書かれた行を joinで繋げたいんです。色んなサイトやLPICの勉強本を参考にしたのですが $ join -1 1 -2 1 1.txt 2.txt $ join -j 1 1.txt 2.txt 上の2つでは、300個くらいHITするはずなのですが、数個しか出てきません。 全く同じ行に同じ数字がフィールド1に入っているものだけが出力されているようです。 行数が数行しかないファイルではきちんと違う行でも結合してくれるのですが、 行数が多いとjoinでは無理ってことはありますか? 500行くらい処理してくれるものだと思ったんですが・・・泣。 シェルスクリプトでうまくいくのであればヒントを下さい、シェルはbashです。
>>746 いまいちやりたいことがわからん。
5行くらいのファイルで例示してみてくれ。
しかし join なんて使ったことないな。
そんなん知らなくても実務ではまったく困らん。
perl かなんかで書く勉強でもした方が役に立つよ。
>>747 初めて学ぶスクリプト言語をシェルスクリプトにしようと決めたところでして、
perlとかは全く知らないんです・・・。ですが実務ではなく趣味なので楽しんでいます。
それと説明が下手ですいません(泣)再度説明させて下さい。
$ cat join1.txt
157 A B
160 C D
1291 I J
1373 K L
$ cat join2.txt
157 C D
160 E F
1373 K L
この2つのファイルをフィールド1個目でくっつけて
$ join -j 1 join1.txt join2.txt
157 A B C D
160 C D E F
1373 K L K L
にしたいんですが(上のファイルだとくっつきました)、各フィールド数が7個
各行数が500行程度、各ファイルサイズは30KBくらいになると、フィールド1個目の
数字が一緒でも、行が1個でもずれているとくっつかなくなり、行が同じものしか結合しなくなりました。
joinの精度が低いのが原因なのだとしたらお手上げなのですが、
何か他の原因は思いつきますでしょうか。perlとかSQLは全く無知なのでシェルで済ませたいんです。
749 :
746 :2008/02/29(金) 18:07:44 ID:HrPH8ECW
自己解決したわけではないのですが、やっぱり精度の問題みたいです・・・。
>>748 の join1.txt と seq 150 200 > seq1.txt でjoinコマンドを使ってみたら結合できましたが
>>748 の join1.txt と seq 1 2000 > seq2.txt でjoinコマンドを使ってみたら1つも結合出来ませんでした。
何か他の工夫で切り抜けたいと思います・・・失礼しました。
>FILE1 と FILE2 は実行前に join フィールドの昇順にソートしておかなければならない(数値順のソートはだめ)。 だとさ。
月に一度、メールログを調べたいのですが、 下記スクリプトを毎月1日朝に走らせています。 --- #!/bin/sh pre_month_days=`date -d '1 days ago' +%d` zcat /var/log/maillog.{1..$pre_month_days}.gz | 引き渡し先プログラム --- これをシェルで走らせると zcat: /var/log/maillog.{1..29}.gz: No such file or directory となります。 ですが、 #zcat /var/log/maillog.{1..29}.gz と手打ちすると、ズシャーっとログが表示されます、エラーも最後まで出ません。 変数展開されていないならまだしも、まったく原因がわかりません。 どういう理由で「No such file or directory」が出るのでしょうか?
変数が入ってると{}って展開されないんじゃね?
x=29 echo {1..$x} してみようぜ。
754 :
751 :2008/03/01(土) 17:46:18 ID:IgLZSOLf
>>752-753 {1..29}
・・・ってことは、{1..29}そのものを探す=「No such file or directory」
ってことでしょうか?
ということは、pre_month_daysの文だけfor文で回して、
$temp_textにためていってから、解析プログラムに引き渡すと今思ったのですが、
この$temp_textというのは、シェルスクリプトが終了したときには、
消えてなくなるのでしょうか?どこかに残っているものなのでしょうか?
$temp_textだと、120万行ぐらいあるので、どこかに残っていれば圧迫しかねませんし・・・。
755 :
751 :2008/03/01(土) 19:12:07 ID:IgLZSOLf
す、すいません、 bashのfor文ってわけわかりません、( )とか{ }とか使うと思っていたのですが・・・。 zcat /var/log/maillog.$x.gz >> $temp を繰り返して、 引き渡しプログラム $tempとしたいのですが、 for文(他のやり方もある?)をどう使えばいいのでしょうか?
for文はCみたく配列を添え字でループするのと違って、 並べた要素1つ1つに対してループするというもの。 for x in 1 2 3 4 5; do echo $x done とかな。 1から先月末日までの日の並びを作るために、Linuxならおそらくseqが使える。 # BSDだとjot for $x in `seq $pre_month_days`; do zcat ...$x... done とか。
bash なら for (( i = 0; i < 10; i++ )); do echo $i done みたいな C っぽい for 文も使える。
758 :
751 :2008/03/01(土) 20:32:55 ID:IgLZSOLf
>>756-757 seqを使ってもエラーが出るので、
Cっぽくやってみました。
aaa.1.txt
aaa.2.txt
aaa.3.txt
を用意して、
------------------
#!/bin/bash
x=3
temp=""
for (( i=1 ; i < $x+1; i++ )); do
cat aaa.$i.txt >> $temp
done
cat $temp
-------------------
./test2.sh: line 5: $temp: ambiguous redirect
./test2.sh: line 5: $temp: ambiguous redirect
./test2.sh: line 5: $temp: ambiguous redirect
マズー(;´Д`)
am・big・u・ous[ mbjus ]
[形]
1 2通り(以上)の解釈を許す
2 (正体の)あいまいな;紛らわしい;はっきりしない, ぼんやりした, もうろうとした, おぼろげな
temp="" 書き込み先がないじゃんか。 temp=nulpo.txt とか書き込み先がないと。
760 :
759 :2008/03/01(土) 21:51:32 ID:IgLZSOLf
い、いけました。 1ヶ月のメールログ1.4GBを食わせることができました。 ありがとうございます。
>>760 最初の>751をよく見てなかったんだけど、maillog.*がそんなに多くない(毎月かならず1〜29になっている、てので)なら
for file in `ls /var/log/maillog.*`
do
zcat $file | 処理プログラム
done
でいいのでは。
それと焦って名前欄間違えないように〜w
762 :
760 :2008/03/01(土) 23:08:45 ID:IgLZSOLf
あぅ、すいません。 logrotateはdailyの120でcompressなんです。 で、月次解析なんで、 その日の前日の「日にち」を取って、 zcatしなくちゃならなかったんです。 でも、これで月次の解析ができます〜
いい流れた
>>760 ファイルに落とさない方法もあるぞ
引き渡し先がワンパス処理で無い場合は失敗する可能性
があるのでおすすめ出来ないが...
#!/bin/sh
pre_month_days=`date -d '1 days ago' +%d`
( for i in `seq 1 $pre_month_days` ; do
printf "/var/log/maillog.${i} "
done ) | xargs echo zcat | 引き渡しプログラム
exit $?
##
括弧はいらないね
>>751 eval zcat /var/log/maillog.{1..$pre_month_days}.gz | 引き渡し先プログラム
んー
簡単なApacheログ解析&集計用スクリプト組みたいんだけどシェルスクリプトだとパフォーマンス悪いかな?
RubyやPythonは使えないんで、bash系シェルスクリプトかPerlでやってみたいんですが
ちなみにログフォーマットはこんな感じ
mxxxxxx.dynamic.ppp.asahi-net.or.jp - - [27/Feb/2008:15:46:04 +0900] "GET / HTTP/1.1" 200 101323 "
http://hoge.piyo/ " "Opera/9.25 (X11; Linux i686; U; ja)"
1リクエストに対して1行記録され、日付毎にファイルがある。(ファイル名の例:access_log_20080227)
465日分で容量2.5GB超とちょっと多いです。
やりたいことは項目別のランキングをテキスト出力だから、スクリプト自体は簡単そう
それはanalogとかでできないものでしょうか(´-`)
>>768 実はそんな気がしてた
ありがとう('`)〜♪
ウワー早い 2分ちょいでこれだけ解析できるのかー ああでも肝心なRefererランキングが出てないわ Analogスレは4ヶ月近く誰も居ないみたいだしドウシタモンダカー
771 :
login:Penguin :2008/03/04(火) 09:48:48 ID:kUaxbjJj
Bashを使ってシェルスクリプトの練習をしています ファイルに特定の文字列が記載されていたら処理を分岐させるというシェルを書きたいと思っているのですがなかなか上手くいってくれません 何かいい方法がありましたら教えていただけないでしょうか やりたい事はファイル内にHTMLという文字列が入っていたらAの処理 入っていなかったらデフォルトの処理をしたいと考えたので 下記のようにしてみました TMP=`cat $YEAR$MONTH$DAY.csv |grep HTML`; echo $TMP case "$TMP" in HTML)echo "HTML file" ;; *) echo "##################" esac
>>771 if grep HTML "$YEAR$MONTH$DAY.csv" >/dev/null; then
echo "HTML file"
else
echo "##################"
fi
>>772 ありがとうございます
教えていただいた通りにやったら問題なくできました
なぜcat|grepのときは上手くできなくて
grepの時は問題なくできるのかがちょっと分からないのですが
いろいろ調べてみようと思います
HTML) を *HTML*) としてみようぜ。
grep -q を使わないのはポータビリティー重視だから?
論文を書くときに使うグラフをTopazというソフトを用いて作成しております。 その結果、グラフがepsファイルとして作成されるのですが、Windowsにもってくるとフォント関係でエラーが生じてしまいます。 なのでLinuxでフォントをアウトライン化しようと思い「eps2eps」というコマンド(シェルスクリプト?)を用いて epsファイルのフォントをアウトライン化しました。 しかし、そうするとbounding boxがおかしくなってしまいます。 ですので元のepsをテキストエディタで開き、bounding boxの項目をコピペして対応しています。 それでようやく本題なんですがw 上のような作業を、複数のファイルに対して一括で行いたいのです。 for file in *.eps do eps2eps $file ${file%eps}2 done のようなシェルスクリプトを使えば一括でアウトライン化epsができると思うのですが さらに、インプットファイルをテキストエディタで開きbounding boxの項目をコピー アウトプットファイルにbounding boxの項目を貼り付け というような機能を持たせることはできるのでしょうか?
ed
>>778 スクリプトに慣れた人ならすぐに作れる。
ああ、無情
シログミガンバレ
basenameが第二引数を取ることを今知った。
echo hoge=1で代入、表示両方できる知った件
>>786 $ echo hoge=1
hoge=1
$ echo x"$hoge"x
xx
bash 2.05b@debian ではできないぞ。
環境を教えてくれ。
そんなのできたら困る。
789 :
login:Penguin :2008/03/21(金) 01:53:30 ID:Mk2nPfge
>>539 >>537 最近はGUIの環境もシェルと呼んだりするらしいしね.
>ところで,シェルスクリプトをシェルと略す感覚が信じられない
>.せめてスクリプトのほうを残すべきじゃないのか,意味的に…
javascriptをjavaって呼ぶ奴おおいし、むきになんなよ
ちっせーな、何度も何度も
>>789 javascriptとjavaだって別物じゃねーか
まったく別の意味にとられる表現は避けるべきだろ。
javaの開発と言われて行ってみたら、javascriptの案件だった…… 経験者を求めていた筈なので確認をとったら速攻で別案件に回されたけど。 (だれがどこでまちがったのかはしらない。たぶん、えいぎょうのアレがマタやらかしたんだろうけど)
そうだよね、文字の"あ"を"い"って発音してもいいじゃん?
>>792 頭の構造が粗雑なんだろうね。
しかし無能とは決めつけられないよ。土方としては有能かも知れないじゃないか。
javascriptをjavaと呼ぶ井戸の外の世界
もうすべて「あれ」と「あれ以外の何か」でいいんじゃね? 「この開発にはあれが必要だな」 「そうですね、あれも必要です」 「あれのほうはどうだ」 「あれはあれ以外のあれでやりましょう」 「あれはあれだったからな」 募集要件にはエスパー希望と書けば何も問題ない。
残念なことにハードディスクドライブをハードと略すおっさんを結構見かけるのがリアル世の中なのねん。
javascriptをjavaと呼んじゃうおばちゃん、ねーちゃんだってざらにいるよ。
どっちかというと
>>789 のほが常識的な気がす
>>789 perlスクリプトをPerlと呼んだりPerlでやると言ったり
awkスクリプトをawkと読んだりawkでやると言ったり
それと同じでは
省略したら同種の別の言葉になるかどうかだな。
厳密なことをいえばさ、シェルって単体で言う場合はシェルスクリプトの略じゃないのよね。
(
>>537 ,
>>539 はこれにつっこんでいる)
OSのカーネルに対する、(コマンド)インターフェイス外殻(カーネルの外層を覆う殻の概念)を
現在はCUI/GUIの別を問わずにシェルと呼んでる。このうちGUIの場合はグラフィカルシェルとか
CUIの場合はコマンドラインインタプリタとか呼ぶのだけど、このコマンドラインインタプリタを
Linuxを含めたUNIX系OSでは単にシェルと呼ぶ慣習がある。昔UNIXにはGUIなんて無かったらね、
シェルといったらコマンドラインインタプリタのことだ、ということに定着していたわけね。
いわゆるsh, bash, csh, tcshのshがシェルだ罠。
シェルスクリプトの略がシェルじゃなくて、シェルで動くスクリプトがシェルスクリプトなの。
順番が逆なのよ。
awk/perlもawk(言語)/perl(言語)のスクリプトがawk/perlスクリプトなのであって
awk/perlスクリプトの略がawk/perlなんじゃないよ。
まぁどうでもいいけどな。
以上を踏まえてあえて言えば
たしかにシェルとシェルスクリプトは別物だしjavaとjavascripは別物だし、
細かいこと言えばGUIだってグラフィカルシェルなのだ(
>>539 )が
あんま細かいことをいうとバカみたいだ。つーか狭量に見える。
というわけで
>>789 のほが同意できる。聞き上手って言葉があるじゃない?
でだ、
>>539 がシェルスクリプトをシェルと略さずにせめてスクリプトと略しゃ
いいだけじゃねーかと建設的な提案をしたのに、他の軽量プログラミング言語
までもちだし、略した言葉を受け取った人間の能力の問題じゃね?
となるこのスレの流れに、思わず小岩井ミルクコーヒーを噴いた。
>>791 の様に読解および対話能力が備わってないと、悲惨な状況のド真中に
パラシュート降下させられる奴がわんさかでそうだ。単語の略し方の問題で。
>たしかにシェルとシェルスクリプトは別物だしjavaとjavascripは別物だし、
>>800 の言う通り、
シェル・スクリプトをシェルと呼んでも文脈から意味は通じるが、
javascriptをjavaと呼んでしまうと別のものを指してしまう。
混同するな。
WikipediaをWiKiとかね。
では、世の間違いをどこまでも正していってくれ。 思い浮かべて欲しい世の人々は道の傍らでJavaとJavascriptの違いを 切々と説く君たちに聖者が来れり、天国は来れりと歓喜することであろう。 が、まぁ少なくとも営業の彼と経理の彼女、はす向かいの鈴木さんに 今後一切飲みに誘われなくなるのは間違いと思うけどね。
モヒカン族と村人ですから
>>805 AとBは異なるという説明し、その異なりを無視して同一のもととして扱うと
余計なコストが発生するから、次からはきちんと区別してくれという依頼が
出来ない風土、もしくは、意思決定にかかわる情報を扱うやつが説明しても、
その異なりを理解できないなら、そんな会社つぶれるだろ常考。
また、痛いレスみてJavaとJavascriptも区別して話す新入りが入ってきたら、
それこそ大迷惑だ。
>>791 のえいぎょうのアレは赤っ恥ですめばいいけど。発注元からみると、
大丈夫かこの営業さんと思ったに違いない。
という燃料を補給してみた。
まぁ派遣は大変だよな。ガンガレ。
>>810 だが、今見たら言い方が悪かった。なんだか煽っているようにもとれるかもな。
すまんかった。そういう意味じゃなくて、今時、派遣ぽい職場の人は技術職まで
そんな感じになってきて大変だと思う。漏れにも似たような経験あるからさ、
マジ、ガンがって欲しいと思ってる。
言われたのと行った先で条件が違うなんてのはちょくちょくあって
アホな会社にも言えなくて当人が泣きをみてしまうつーのは辛いよな。
やる気ならなんとかユニオンとかそっちに話をもってくしかないわけだが
自分の身を守るのが第一かと思うよ。
まぁここでそんなこと言っててもしょうがないわけで、そういう言い方になった。
教えて先生。つーか、自分がやった時に苦労したんだけど、 プロな人はもっと簡単な方法を知ってるんじゃないかな的なお題。 ひょっとして歴代のスレで既出の可能性ありだけど許して。 ディレクトリに お宝画像(1).jpg お宝画像(2).jpg .... お宝画像(100072).jpg お宝画像(100073).jpg が入っている。ファイル名はutf8の日本語、連番はカッコ付きで 連番途中に欠番がある可能性がある。これらのファイルをすべて ero-pic000001.jpg ero-pic000002.jpg .... ero-pic100072.jpg ero-pic100073.jpg という風にリネームしたい。どうしたらいいでしょう?
プログラミングの基礎を学べば余裕でできると思うよ
実は漏れは結局Cでやったんだけどね。シェルで簡単にやるにはどうするの?
rename や mmv を使うかな。
perl版renameで rename '/\d+/ and $_=sprintf(q{ero-pic%06d.jpg}, $&);' お宝画像*.jpg とか?
ls > file_list.txt して中身を mv "お宝画像(1).jpg" "ero-pic00001.jpg" とかに変えて sh file_list.txt するかな
>>816 mmvというのは? うちにはないみたいだけど。
>>817 perl版renameというのは普通のrenameとは違いますよね?多分。
>>818 基本的にはその方法を用いましたが、
> mv "お宝画像(1).jpg" "ero-pic00001.jpg" とかに変えて
ここがエディタでも番号を取り出す文字列操作を伴うマクロかなにかを使う必要があるわけです。
10000行以上あるので手動では無理ですし。私はCでやりましたが。
やっぱそもそも結構めんどくさいことだったんですかね。
なんか簡単そうな感じはするんだけど。
Perl版renameといえばラクダ本に載っている正規表現でリネームパターンを
指定できるスクリプト(使い方は
>>817 )のこと。
>>819 でも、正規表現使ったら5回くらいの置換でいけるから、
それでやっちゃうなぁ。俺だったら
vi で
:%s/.*\(.[0-9]\).*/ero-pic0000\1.jpg/gc
:%s/.*\(.[0-9]{2}\).*/ero-pic000\1.jpg/gc
みたいな感じで
自信ないけど
>>822 > :%s/.*\(.[0-9]{2}\).*/ero-pic000\1.jpg/gc
これダメっぽいような?
あと「お宝動画」は例えばの例でどうかわかんないけど
日本語大丈夫かしら?
perl-rename のGTK版見付けた。 gprename しかしprel-renameみつからない・・・
って ubuntu のrenameはprenameだった。
debianのperlのパッケージに標準で含まれてるのよ
今思いついたのだが、ひょっとしてスクリプトで #!/usr/bin/perl rename old-filename, new-filename; みたいな話とか?なるほどそれならいけそだけど。
Perl版renameはこんな感じのスクリプト $op = shift; foreach (@ARGV) { $was = $_; eval $op; die $@ if $@; rename($was, $_) unless $was eq $_; }
>>813 あえてシェルスクリプトで書くのならこんな感じかな。
#! /bin/bash
for file in "$@" ; do
num=${file#*(}
num=$( printf '%06d' "${num%)*}" )
mv "$file" "ero-pic${num}.jpg"
done
bashism が嫌いなら sed に置き換えれば
/bin/sh でも動くんじゃないかな
zshだが許せ。 for n in {1..100073}; mv お宝画像($n).jpg ero-pic`printf %06d $n`.jpg
>>817 >>820 >>827 >>829 >>826 =
>>828 だけど、ええとそれってシェルスクリプトで使えるの?
/usr/bin/rename が置き換えられているとか?
どうなっているんだろう。
>>830 うちでは動かないようだ。
日本語が混じるとためかな。あとかっことか。
で結局こうやったのだけど。
$ls | sed s/.*\(//g | sed s/\).*//g | awk '{printf("mv \"お宝動画(%d).jpg\" \"ero-pic%06d.jpg\"\n",$1,$1)}' | sh
前やったときはawkの代わりにcのプログラムでやってた。まぁawkでも同じか。
>>813 いろんなやり方があるけど、スクリプト内でいきなりmvなりrenameして
失敗すると悲劇なので、
mv "旧いお宝画像1.jpg" "新しいお宝画像1.jpg"
mv "旧いお宝画像2.jpg" "新しいお宝画像2.jpg"
mv "旧いお宝画像3.jpg" "新しいお宝画像3.jpg"
mv "旧いお宝画像4.jpg" "新しいお宝画像4.jpg"
mv "旧いお宝画像5.jpg" "新しいお宝画像5.jpg"
mv "旧いお宝画像6.jpg" "新しいお宝画像6.jpg"
(以下略)
みたいに一旦テキストに落として、それざっと眺めてからshで流しなおしたほうが良いよ。
以前、
mv "旧いお宝画像1.jpg" "新しいお宝画像1.jpg"
mv "旧いお宝画像2.jpg" "新しいお宝画像1.jpg"
mv "旧いお宝画像3.jpg" "新しいお宝画像1.jpg"
mv "旧いお宝画像4.jpg" "新しいお宝画像1.jpg"
mv "旧いお宝画像5.jpg" "新しいお宝画像1.jpg"
mv "旧いお宝画像6.jpg" "新しいお宝画像1.jpg"
(中略)
mv "旧いお宝画像1000.jpg" "新しいお宝画像1.jpg"
ってやっちゃった(´・ω・`)
>>819 > perl版renameというのは普通のrenameとは違いますよね?多分。
renameがperl版renameじゃないUNIX類って具体的には何があります?
UNIX類じゃないけど、VMSはそうでした。
>>832 > 日本語が混じるとためかな。あとかっことか。
括弧の方だな。すまん。クォートするなりしてやってくれ。
>>836 $ whereis rename
rename: /usr/bin/rename
$ less /usr/bin/rename
"/usr/bin/rename" may be a binary file. See it anyway?
多分debianが変わり者では?
そういやDebianはprenameとかいう名前になってんだっけね? 古典的なLinuxはこのrenameなのかな。 /* * rename.c - aeb 2000-01-01 * -------------------------------------------------------------- #!/bin/sh if [ $# -le 2 ]; then echo call: rename from to files; exit; fi FROM="$1" TO="$2" shift shift for i in $@; do N=`echo "$i" | sed "s/$FROM/$TO/g"`; mv "$i" "$N"; done -------------------------------------------------------------- * This shell script will do renames of files, but may fail * in cases involving special characters. Here a C version. */
それ自身はポータブルなPerlスクリプトだから もし使いたかったら$HOME/binあたりに突っ込めばいいんじゃない
>>813 ls -1 ero_dir | sort | ruby -nle 'printf "mv " + $_ + " " + $_.sub("お宝画像\(", "ero-pic").delete("\)")' | sh
訂正orz ls -1 ero_dir | ruby -nle 'print "mv " + $_ + " " + $_.sub("お宝画像\(", "ero-pic").delete("\)")' | sh
>>841 > prenameは Debian のパッケージメンテナが独自にパッケージ生成時に追加したスクリプト
↓だってさ。
# This script was developed by Robin Barker (
[email protected] ),
# from Larry Wall's original script eg/rename from the perl source.
ラクダ本のだってのはだいぶ上の方で言及されとるがな。
>>845 prenameは Debian のパッケージメンテナが独自に
「the perl source(perlのオルジナルセット、いわゆるラクダ本)」から
パッケージ生成時に追加したスクリプト、つーことですね。
/usr/bin/renameがC版の代わりにこれで置き換えて拡張してあるのが
debianの方言ということで。
実はラクダ本のやつは見たことがあるな。
・
>>840 にある元のシェルスクリプトはsed版正規表現を理解する
・Here a C versionは正規表現を全く理解しない
・perl版はperl版正規表現を理解する
というわけでLinuxでも三種類あるんですね。
こういう微妙な違いってひょっとするとトリごとに結構あるのかもしれないね。 スレからはずれるけど、apache/httpdのコンフィグがバージョン系列は 一緒なのにDebian系(ubuntuも)とRH系(RedHat/Fedora/CentOS)で まるっきり違ってて面くらったことがある。
コマンドなんかもちょっと違うくらいだから、設定ファイルの書き方なんて違っていて当たり前。
ツリー表示について find / -type d|sort|sed -ne'1b;s/[^\/]*\//┗━━/g;s/┗━━┗━━/┃ ┗━━/g; s/┗━━┗━━/┃ ┗━━/g; s/┗━━┃/┃ ┃/g;p' これだと下記のような表示になるのですが ┗━━proc ┃ ┗━━1 ┃ ┃ ┗━━attr ┃ ┃ ┗━━fd ┃ ┃ ┗━━task ┃ ┃ ┃ ┗━━1 ┃ ┃ ┃ ┃ ┗━━attr ┃ ┃ ┃ ┃ ┗━━fd ┃ ┗━━1106 ┃ ┃ ┗━━attr 不要な線を無くして見栄えを良くしたいのですが、何か良い方法はありませんでしょうか ┗━━proc ┃ ┗━━1 ┃ ┃ ┗━━attr ┃ ┃ ┗━━fd ┃ ┃ ┗━━task ┃ ┃ ┗━━1 ┃ ┃ ┗━━attr ┃ ┃ ┗━━fd ┃ ┗━━1106 ┃ ┃ ┗━━attr
よくわからんけど tree -dA じゃダメなの?
853 :
851 :2008/03/26(水) 22:04:51 ID:B6BxqxUi
そういうコマンドがあるのは知ってるのですが # which tree /usr/bin/which: no tree 残念なことに入ってないんです。 いろいろ調べまわった結果がこれなんです。 もう少し自分でも調べてきます。
そうかtreeのないトリもあるのか。
yumとかaptで入れられないっけ?
>>853 PATH が通ってないだけとか。locate 辺りで調べてみたら?
他に何かあったっけ>探す方法
857 :
851 :2008/03/27(木) 00:35:50 ID:yDbPGpUf
なんとか自己解決できました 下記のシェルスクリプトを「/usr/bin/tree」に置いて代用することにしました。 #!/usr/bin/perl use strict; my($top)=$ARGV[0]; if($top eq ""){ $top="."; } print "[$top]\n"; &tree("",<$top/*>); sub tree { my($bar,@dir)=@_; for my $i(0..$#dir){ my($bl1)=($i<$#dir)?"┣":"┗"; my($bl2)=($i<$#dir)?"┃":" "; my(@path)=split(/\//,$dir[$i]); if(-d $dir[$i]){ print "$bar $bl1 [$path[$#path]]\n"; tree("$bar $bl2",<$dir[$i]/*>); }else{ print "$bar $bl1 $path[$#path]\n"; } } } ちょっと中身を理解するのは難しいですけど、使いこなせたらperlも結構便利そうですね。
>>857 > 下記のシェルスクリプト
ちょっとマテ
どう見てもシェルスクリプトでなくPerlスクリプトだなw ちなみに、鳥は何なの?
860 :
851 :2008/03/27(木) 19:23:00 ID:yDbPGpUf
あ、確かにperlスクリプトですねw ちなみに鳥はCentOS4.6で、サーバー構築の勉強用で使ってます。 最小構成でインストールしたからtreeコマンドが入って無かったのかもしれないです。
美女の現われるスクリプトを教えて下さい。
>>861 emerge beautiful_girl
866 :
789 :2008/03/28(金) 01:42:56 ID:QgSpL7VJ
にやにや もりあがってんじゃねーかw
>>866 javascriptをjavaと呼ぶひと、こんばんはw
cshで質問です。 下記のように変数をperlに渡したいんですが、変数を認識してくれません。 どうすれば良いですか? set hoge = funi perl -pe 'print $hoge' file
>>868 シングルクォートをダブルクォートに変える
>>869 ありがとうございます。
試してみましたが、ダメのようです。
setenvで与えると上手く行きましたが、setで出来る方法も知りたいです。
無理。 あえてやるなら perl -e 'print "'"$hoge"'"' これはperlに print "funi" という式を渡したに等しい。
>>871 ありがとうございます。
やってみたら出来ました。
意味は分かんないのでこれから調べてみようと思います。
csh じゃなきゃいかんの? sh 系で書いた方がいいんじゃない?
リダイレクト 「>&-」 (ディスクリプタ番号に 「-」 を指定した場合) の振舞いについて記述している manpage を探しています。 (manpage でなくともそれに準ずる文書であれば構いません) JM Project の bash(1) などや google で検索してみたのですが見つかりません。 >&- を使用しているシェルスクリプトは見つかりましたが、そこには正式な説明はありませんでした。 google って記号検索がとても弱いようなので シェルスクリプトとか GAME言語みたいな記号で頑張るタイプのを探すのは大変。 何か効果的な検索技があるんですかね。
875 :
login:Penguin :2008/03/29(土) 22:48:22 ID:6BdICwv7
シェルスクリプトで連番を振る際に 1から100を1、2、3…ではなく 001、002、003…と出力させたい場合どうしたらよいでしょう? val=1 while $val lt 100 do echo $val val=expr`$val+1` done
>>875 for i in {0..9}; do printf "%03d\n" ${i}; done
printfが嫌なら echo "000$i" | sed 's/0*¥(...¥)$/¥1/'
878 :
874 :2008/03/29(土) 23:01:58 ID:Je2/7f5V
すみません。事故解決しました。 JM Project の bash(1) に記述されてました。
879 :
875 :2008/03/29(土) 23:02:33 ID:6BdICwv7
>>876-877 凄まじくソッコーのレス ありがとうございます。
形式を指定してるってことくらいは分かりました。
調べてきます!
ありがとございました。
>>875 単純に、必要な個数の名前のリストがありゃいいだけなら、
これでもいいと思う。
seq -f "moe_ero_guro_%03g.png" 0 9
>>876 {0..9} は bash3 じゃないと動かないはず。
まだ bash 2.05b の環境ってけっこうあるよね?
seqは、あーここLinux板だからまず間違いなく入ってるな。
seqだととびとびの値とかも作れるんだが、 単に連番がつくりたいとき個人的によくやるのは yes '' | cat -n | sed 100q とか。
seqって便利だね。知らんかった。 seq -f %03g 1 100
>>881 聞かれたから一応、答えておこう。そんな環境は知らん。
bash 2.05bなのはRHEL3かVineか、2005年ぐらいで閉鎖空間へ移行したやつだけだろ。
そうなのか。ある意味Vine恐るべしだな。
887 :
874 :2008/03/29(土) 23:41:18 ID:Je2/7f5V
組込系だったりすると bash どころか busybox ん中の sh (ash) だったりもする。 La Fonera の seq は -f オプションなんか無いので printf "%03d\n" `seq 1 10`
この仕様は初めて知ったw $ printf "%03d%03d\n" 1 2 3 4 5 001002 003004 005000
おまいらのseq には -w ってオプション無いの? seq -w 1 100
890 :
874 :2008/03/30(日) 00:48:35 ID:VLE1BQAD
BusyBox v1.1.3 (2006.11.21-19:49+0000) multi-call binary Usage: seq [first [increment]] last Print numbers from FIRST to LAST, in steps of INCREMENT. -w ? そんなオプション見たこと無い。(笑)
拡張子の変換ってどうやってる?俺は for f in *.hoge; do mv $f ${f%.hoge}.fuga done っていちいち打ち込んでるんだけど、なんかいい方法ない?
ニコ動の動画IDをwgetで落とせる直リンに変換するスクリプトないっすか?
$ oppai bash: oppai: command not found
897 :
login:Penguin :2008/04/04(金) 13:09:23 ID:Lie/X+/S
質問させて下さい。 ubuntu7.1 server を使用しています。 シェルスクリプトを勉強し始めてLinuxの設定セットアップシェルを作ろうとしています。 ■入力受付状態を省略し、自動入力にするにはどのようにすればいいのでしょうか? 例えばsambaのコマンドですが smbpasswd -a root をするとパスワードの入力を求められます。 普段なら手動でxxxxと入力するのですが、この作業を自動化したいのです。 色々調べてsedの使い方等はわかりファイルの書き換えによる設定はおおむね出来たのですが 上記のやり方は見つけることができませんでした。 どうかアドバイス頂けないでしょうか? 宜しくお願い致します。
>>897 Windowsから接続しているなら、TeraTermのマクロで何とかできるかもね。
ただユーザー名やパスワードが見えてしまう状態でファイルに保存するから
セキュリティ上には良くないかも
sambaの設定ファイルだけバックアップ取って
ユーザーとパスワードはその都度入力するのが無難かと
>>897 expectスクリプト
expectに突いてくるサンプルを読んで
すまん、サンプルついてないわ。 apt-get source expect して、サンプル見て。
シェルスクリプトできるけどPerlスクリプト出来ないやつなんなの?
単にawkとかpythonが好きなんじゃないの?
>>901 シェル・スクリプトは基本だが、perl は awk やら python やらのワン・オブ・ゼムに過ぎないので、それが普通。
MS-Windows95の頃、cgiはperlスクリプトでという謎の風潮があった名残で、あなたのような疑問が出て来るのだろう。
904 :
login:Penguin :2008/04/07(月) 02:13:58 ID:WGY+O99D
>>903 そうそう。
別に、cgiがシェルスクリプトでも問題ないし(使いにくいけど)、なんでもいい。
perlだろうが難だろうが、所詮手段なんだから、どうでもいいじゃんw
>>901 多分、
同じ構造化手続き型言語なのに何で方言によって使える使えないみたいなこと言ってんの?
ということかと。
>>905 そうなら「シェル」スクリプトスレで何言ってんだこのバカは?
ってな話しにしかならんからそれはなかろ。
つまり、シェルスクリプターはアホです。
ahoさんはawkの偉い人でしょ
フィンランドではよくある名字。
えっほ
スキーでアホネンさんっていたな この人もフィンランドだったな
だれがあほやねん!
>>911 ,913
しょーもないレスして悲しくなってこないか?
$ shoumo bash: shoumo: command not found
$ which show /usr/local/mh/bin/show なんていう時代もありました。
000から999までリストを作りたいんですが、どうすればいいでしょう?
seq -w 0 999
>>918 めちゃくちゃありがとうございます!!!
最近の bash なら echo 00{0..9} 0{10..99} {100..999} zsh なら echo {000..999}
端末に他の端末から書き込むようなデーモンとクライアントが欲しいです 例として、mltermとurxvtを立ちあげ、 mltermでhogedを起動して、もうurxvtでhogec -e 'echo aaa'ってやったら mltermの画面にaaaとか表示されるようなものです 同時に複数の作業をさせてるときにその進捗を1つのコンソールで見通せたらなとか思いまして…
適当なログファイルに書き出して、端末の方にはtail -f (tailf)で流せば
端末A $ echo 'term A' > /dev/console 端末B $ echo 'term B' > /dev/console に類したことは、まれにやる。
>>921 mlterm$ screen
urxvt$ screen -x
つ ttysnoop
rm -rf /* ┐('〜`;)┌ モウツカレタ
dd if=/dev/zero of=/dev/hda
運用しているマシンでちょっとした作業を行うとき、 nice bash したシェルで作業することがあるのですが、 いま自分が動かしているシェルの nice 値を簡単に 知る方法ってないですかね・・・
$ ps -o %n $$ そんなことも知らない人がniceするの? それに対話型のコマンドにniceはあまり意味がない。
その中でmakeしまくるので
alias make='nice --adjustment=-30 make'
reniceじゃダメなんでしょうか?
alias nice='ジャズ + クラシック / ロック'
nice boat.
937 :
login:Penguin :2008/04/19(土) 13:43:25 ID:khf4hkQE
>>934 >reniceじゃダメなんでしょうか?
topでもいいよな。
938 :
login:Penguin :2008/04/19(土) 16:17:44 ID:SCXXqtIf
bashのシェルスクリプトで、 文字列に正規表現のフィルタをかけたいのですが 以下の場合、なぜエラーになるかわかりません。 何が悪いですか? expr `ps` : ".*" -> expr: syntax error var1="aaa" expr $var1 : ".*" -> expr: syntax error
expr "`ps`" : ".*" var1="aaa" expr "$var1" : ".*"
940 :
login:Penguin :2008/04/19(土) 20:46:24 ID:SCXXqtIf
>>939 それで出来ました。ありがとうございます。
でも理由がいまいちわかりません。
” ”で囲っていない為 → 文字列型ではない為 → では$var1は何を返すのか?
hdやbdみたいに 2進数表示するプログラムありませんか?
odだと2進数は表示ですう。 もう自分で作っちゃいました・
944 :
login:Penguin :2008/04/20(日) 10:43:22 ID:C3cqRfnQ
>>940 >” ”で囲っていない為 → 文字列型ではない為 → では$va
>r1は何を返すのか?
確かに、おれも気になるぞ
なんというか、このスレで話をするための最低限の知識レベルを、
>>940 や941は遥かに割り込んでいる気がするんだが。
946 :
login:Penguin :2008/04/20(日) 14:55:30 ID:3JVOMAOF
>>938 は、自分なりに考えた結果、以下のような結論になりました。
シェルスクリプトは、型だのなんだのはなくて
C言語でいう単純なマクロの展開レベルのものしかしない。
例えば、先の例だと、
expr `ps` : ".*"
↓
expr PID TTY TIME CMD
2295 pts/1 00:00:00 bash
2407 pts/1 00:00:00 ps : '.*'
↓
シンタックスエラーでNG
""で囲うと、
expr "`ps`" : ".*"
↓
expr 'PID TTY TIME CMD
2295 pts/1 00:00:00 bash
2407 pts/1 00:00:00 ps' : '.*'
↓
OK
「echo "aaa " `ps`」が通るんで矛盾しているなぁと思っていたんですが
よく考えるとそんなことは無かったですね。
逆に文字列処理を一通りしてから実行させられるから、
>>938 が最初考えていたみたいに単語区切りが強い場合より、
出来ることが増えるんだけどな。
その代わりプログラマがちゃんと構文構成の責任を持たないといけないけども。
grepの結果で AAAとBBBのOR検索をしたいのですが、 tail -f /var/log/maillog | grep [AAA|BBB] とやってもだめでしたorz どうすれば、OR検索ができるのでしょうか? ANDは、パイプで追加すれば可能なのですが・・。
なんで tail -f なんてする必要が有るんだ?
>>948 grep -E "(AAA|BBB)" もしくは
egrep "(AAA|BBB)"
951 :
948 :
2008/04/24(木) 04:44:09 ID:8uaGXJVC >>950 egrepでしたか、ありがとうございます。
>>949 1秒に100行以上流れるログなので、速すぎて読めないのよねw