1 :
ミスターシェル :
2006/09/07(木) 13:00:11 シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(
>>1-6 くらい)をご覧ください。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashなので特に注意。
・csh/tcshのシェルスクリプトは推奨されません。
(理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
manや参考リンクを見ましょう。
aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
2 :
ミスターシェル :2006/09/07(木) 13:01:14
3 :
ミスターシェル :2006/09/07(木) 13:02:10
4 :
ミスターシェル :2006/09/07(木) 13:03:23
5 :
ミスターシェル :2006/09/07(木) 13:06:03
6 :
ミスターシェル :2006/09/07(木) 13:07:12
□人間初心者へのお願い: ・このスレはシェルスクリプトについてのスレです。 シェルの対話的な利用についての話やスクリプトと関係ないコマンドの 使い方の質問などはスレ違いなので無用に願います。 □シェルスクリプトでよく使うコマンド: 制御・条件判定系: [,test,expr,true,false,yes,getopts テキスト処理系: cat,awk,sed,tr,sort,uniq,grep,wc,head,tail,cut,paste,comm,join ファイル検索系: find,xargs (スペースなどを含むファイル名を正しく処理するため、 findは -print0、xargsは -0オプションを常に付けることを推奨 ただし、Solarisでは未対応。どうするんだろ?) ディレクトリ系: basename,dirname 出力系: echo,printf 対話コマンド制御系: expect http/ftpの処理自動化: wget,curl テンプレは以上です。引き続きよろしくお願いします。
うむッ
9 :
質問 :2006/09/07(木) 17:25:28
お願いします。 awkの中で変数を使いたいんですが出来ません。 例えば #!/bin/sh a=xyz awk '/^${a}/{print $2}' abc 行き詰まってしましました。 解決策を教えてください。
>>9 awk '/^'"${a}"'/{print '"$2"'}' abc
>>10 $2 は awk側の変数だろ。
awk '/^'"${a}"'/{print $2}' abc
>>9 せっかくシェルスレなんだからawk何か使わずに
シェルだけでやれ。
↓
#!/bin/sh
a=xyz
while read f1 f2 f3
do
case "$f1" in
"$a"*) echo "$f2";;
esac
done < abc
>12 前スレから見てるけど、改良や改善などの挙げ句どのみち何らかの スクリプト言語になっちまうのは、避けられない宿命っぽいよ。
awkまではセーフ。
sedも含めてあげようじゃないか
16 :
名無しさん@お腹いっぱい。 :2006/09/08(金) 16:10:48
whoamiもOK
>>16 つながりがよくわからんが、Solarisにはwhoamiコマンドが無かった希ガス。
なかったらどうだと言うんだ。
なかったらOKとは言えないだろ。
Solarisにない物は不可。
Solarisにある物は可。
22 :
名無しさん@お腹いっぱい。 :2006/09/08(金) 17:35:35
>17 whoamiは sunOS 5.7には無かった sunOS 5.9には有った who am i はどちらでも使える。 5.8は使ってないからわからん。
whoami と who am i は意味が違うわけだが。 su して who am i しても、su前の一般ユーザーが表示されるはず。
>23 いや それはもちろんわかってるって w ネタとして遊んで欲しかった・・・
#!/bin/sh ps u | awk '$2 == '`echo $$`' {print $1}'
シェルでやるならこうか ↓ ps u | while read f1 f2 f3; do case $$ in $f2) echo "$f1";; esac; done
ps -o user | tail -1
そんなことしなくても、これで一発。 ps -h -o user $$
>29 それ処理系依存。Solarisじゃだめだった。
じゃあこれどう? ↓ getent passwd `id -u` | (IFS=: read user other; echo $user) まあ、id -unが使えれば一発なんだが、Solarisだと使えないし。
そこまでわかってればこれだ↓ id | (IFS='()' read f1 f2 f3; echo $f2)
>>34 絶対PATHを決めうちすると今度はSolaris以外で動かない。
psもポータブルじゃないし、
最もポータブルなのは
>>33 か?
>>36 だから、ps -o user というオプションが使えない psもあるんだって。
あと、Linuxの一部では tail -1 も使えない。tail -n 1 にしないと。
よって、
>>33 が最もポータブル。
>あと、Linuxの一部では tail -1 も使えない。tail -n 1 にしないと。 マジかよ……。 たしかに引数の指定のしかたは現代的ではないけど、 過去に作られたスクリプトとの互換性とか移植性とかってのは考えないんだろうか。
一部ってのが何を指すのかわからん イヌックスのその辺りのコマンドは全部GNUじゃないの?
GNU coreutilsの一部のバージョンで、tail -1形式のオプションが削除されたらしい。
Solarisで動けばそれでいい。
>>40 あまりに不評で戻らなかったっけ?
一部のディストリビューションで独自にやってるのかな。
readlinkコマンドってSolarisには無いよね? シンボリックリンクの内容をポータブルに読むにはどうすればいい?
不可能。OOoだかmozillaだかで ls -l "$file" | sed 's/.*-> //' というような処理をしているのを見たことがあるけど、 当然lsの実装に依存するしファイル名が->を含んでいたら終わり。 どうしても必要ならperlを呼ぶのが一番まし。
埋めは荒らしの一種だage荒らし!
/var が容量80%超えたら警告メール送るようなシェルスクリプトきぼん。 もうかれこれ10回くらいこれでサーバーダウンしてます(T_T)
>>46 dfもフォーマットがあんまりポータブルじゃないのでアレだが、
これでどうだ?
↓
while :
do
for i in `df -k /var`; do
case $i in
[89][0-9]%|100%) df -k /var | mail
[email protected] ;;
esac
done
sleep 60
done
でも、メール送っても根本的な解決にならないよ。
1分置きにメールが送るのかよ!! そしてこれが /var を圧迫し、結局サーバが落ちるのだった。続く
>>47 100%オーバーも考えたほうがいいと思う。
snmpトラップでなんとか
テンプレにある xargs の -O とか find の -printOってオプションは どういう動き?何のマニュアルなら載ってる? AIXにものってないよ。 AIXとかソラリスにもないのに載せる必要 あるのか?
O は知らんけど 0 なら GNU のにあるよ。
>>51 じゃあ逆に聞くけど、(Sambaサーバとかで)「Program Files」みたいな
スペース入りのディレクトリorファイル名がバリバリに使われてる環境で、
正しく find | xargs するにはAIXではどうやってるの?
それとも問題に気づいてない?
>>51 Solarisのxargs(1)
入力データは行の集まりとして解析されます。引数は空白文字により 区切ら
れます。xargs を使って find dir -print や ls などのコマンドの出力を、
実行対象コマンドの入力とする場合、ファイル名に空白文字や復帰改行文字が
含まれていると、処理の結果は予測できません。これを防ぐには、見つかった
各ファイル名を引用符つきの文字列に変換するスクリプトを find を使って呼
び出し、そのスクリプトを xargs にパイプでつなげるようにしてください。
なお xargs が使う引用符の規則は、シェルの規則とは異なります。同じ規則
を採用しないのは、既存のアプリケーションが現状の規則に依存しているのに
対し、シェルの構文規則はそれと互換性を持たないためです。文字列を xargs
が正しく解釈できる形式に変換 する簡単な方法は、各文字の前にバックスラッ
シュ(\fR) を付加することです。
>>51 SUSv3のxargs(1)
Note that input is parsed as lines; <blank>s separate arguments. If
xargs is used to bundle output of commands like find dir -print or ls
into commands to be executed, unexpected results are likely if any
filenames contain any <blank>s or <newline>s. This can be fixed by
using find to call a script that converts each file found into a
quoted string that is then piped to xargs.
57 :
名無しさん@お腹いっぱい。 :2006/09/14(木) 00:26:42
質問させてください。LinuxでBASHです。(長文失礼します) ファイル名:file_a データ: 1,abc,b,c 2,def,e,f 3,ghi,h,i これを先頭の数字次第で別ファイルに吐き出したいのですが、 #!/bin/sh for REC in `cat file_a` do echo "$REC" >> record.dat NUM=`cat record.dat | cut -d "," -f1` case $NUM in 1) cut -f1- record.dat >> text1.txt ;; 2) cut -f1- record.dat >> test2.txt ;; *) echo "error";; esac rm record.dat done -- forでfile_aを一行ずつ読んで、一時的にrecord.datに格納し、先頭の文字でcaseで振り分けるというやり方をして動かしています。 これで上記のデータであれば動くのですが、 データ: 1,a bc,b,c 2,def,e ,f 3,ghi,h,i という風に半角スペースが入るとそこで改行と認識されるようで、一行単位で認識をしません。 何か良い方法はないかアドバイスをいただけないでしょうか。よろしくお願いします。
>半角スペースが入るとそこで改行と認識されるようで、一行単位で認識をしません。 for に与える引数リストが改行区切りだなんてどこに書いてあった? 行単位で認識されると思ってるのがまず勘違い。 改行区切りで欲しければ read を使う。 while read a; do case "$a" in 1,*) echo "$a" >> text1.txt;; 2,*) echo "$a" >> text2.txt;; *) echo error;; esac done < file_a sed -n -e '/^1,/w text1.txt' -e '/^2,/w text2.txt' file_a
59 :
57 :2006/09/14(木) 01:43:28
>>58 さん
>for に与える引数リストが改行区切りだなんてどこに書いてあった?
>行単位で認識されると思ってるのがまず勘違い。
>改行区切りで欲しければ read を使う。
知りませんでした。
ありがとうございます、試させていただきます。
>>57 区切り文字はIFSで設定する。
↓IFSを改行に設定
#!/bin/sh
IFS="
"
for rec in `cat file_a
echo $rec
done
ファイル中に複数存在している特定の区切文字列で囲まれたブロックを、区切 文字列をも含んだ形で、それぞれ個別のファイルとして書き出したいと考えて います。ファイル名は重複さえしなければどのような名称でも構いません。 なお、 bash 上で、 $ awk '/^開始/,/^終了/{print}' ~/tmp/data.txt > ~/tmp/data2.txt のようにすることで、 data.txt 中に含まれる 開始 あああああああああああああああああああああああああ あああああああああああああああああああああああああ あああああああああああああああああああああああああ 終了 のブロックが、全て data2.txt に出力できることはわかりました。 しかし、これでは単一のファイルとなってしまい、目的とは異なります。 このような形で切り出したブロックを単一のファイルとしてではなく、それぞ れ個別のファイルとして出力させるには、条件処理を追加する必要があること はわかるのですが、どのように記述すればよいのかでつまずいています。
作ろうとしているファイルの命名則がわからないと、 もしくはそれを決めないと、何とも言えん。
>>61 awk使っていいなら簡単じゃん。
awk '
/^開始1/,/^終了1/{ print > "data1.txt" }
/^開始2/,/^終了2/{ print > "data2.txt" }
/^開始3/,/^終了3/{ print > "data3.txt" }
' data.txt
>>62 ファイルの名称は重複さえしなければ、どんな名称でも構いません。
見つかった順に 0001.txt, 0002.txt,...のような形でも構いませんし、ラン
ダムに生成した名称でも構いません。
>>63 あっ ごめんなさい。
ファイル中に複数存在するブロックというのが、数百のオーダーで存在してい
ます。
また、区切り文字列は全て同じもの(今回の例では「開始」〜「終了」)です。
情報小出し、仕様あとづけキタ。俺はパス。awkスレ行け。 シェルスクリプトと直接関係ないし。
>>64 簡単じゃん。
↓
awk '
BEGIN { n=0 }
/^開始/{ n++ }
/^開始/,/^終了/{ print > n ".txt" }
' data.txt
>>65 情報を小出しにするつもりはなかったのですが、結果
としてそうなってしまいました。
書き込む前にもうちょっと冷静に読み返すべきでした。
ごめんなさい。
>>66 ありがとうございます。
ご教示頂いた方法で希望通りの処理を実現できました。
終了マーカーがいるみたいだから厳密には目的と違うかもしれないけど、 csplitも使えるかな。
>53 なるほどブランク入り等のファイルね。 find は大丈夫そうだけど [root@cis_svr_p]# find . -name *bb* -exec ls -l {} \; -rw-r--r-- 1 root system 0 Sep 15 15:16 ./xx/aa bb -rw-r--r-- 1 root system 0 Sep 15 15:17 ./xx/aa bb dd -rw-r--r-- 1 root system 0 Sep 15 15:17 ./xx/ aa bb dd xargs はないと困りそうだね。 15年以上UNIXシステムに携わってるけどブランク入りファイルが メンテナンスの対象になるシステムは見たことないや。 学校系に多いのかな。
>>69 だから Sambaサーバーって言ってるだろ。
スペース入りのファイルなんて日常茶飯事的にユーザーが作るよ。
Samba なんて使わんしなぁ。 Windows でかためた方が楽じゃん。
最近だと、KDE/GNOMEを使ってるユーザー(シェル不使用)だと、 UNIXユーザーでも普通にスペース入りのファイル名作るよ。
Windows serverライセンス料高い。
>70 ちなみにユーザーが作ったファイルを find やら xargs で何するの?
学校とかなら、setuidされたshがホームに転がってたりしないかくらいは チェックするんじゃないか。
そういうディレクトリはnosuidだRO
それだとsetuidというものを教えられないじゃん。
tmpの掃除とか。
教えるときはその時だけ、専用のディレクトリ使えばよい。
いずれにしても、スペースが入ると誤動作する xargsの仕様を正当化する理由にはなってない。 find ... -print0 | xargs -0 が使えない環境では、xargsを使わず、 find ... -exec ... で個別に -exec するのが正しい。(プロセスが無駄でも)
>>80 -print0がつかえず、かつファイル数が多すぎるときは?
test
って、コマンドだったんですね。目から鱗です。
85 :
名無しさん@お腹いっぱい。 :2006/10/04(水) 16:47:35
UNIXTIMEをテキストファイルに500行ほど書き込んであるのですが、 それをシェルで一括で変換したいんです。 echo ########## | awk '{print strftime("%c",$1)}' >tempuni.txt みたいな感じで どのようにやればいいでしょうか? お願いします
>>85 イマイチ仕様が不明確だが、
$ echo 1157601611 | date -d "1970-01-01 `cat` seconds"
Thu Sep 7 04:00:11 JST 2006
↑みたいにできればいいのかな?
タイムゾーンは別途考慮のこと。
では、後出しの仕様どうぞ
↓
シェルってゆうなクズ。
「シェルで一括変換」ならOKっしょ。
何かのパズルか宿題じゃなければシェルでやらない方がいい問題だな。
90 :
名無しさん@お腹いっぱい。 :2006/10/04(水) 17:01:41
>>86 そんな感じです。
それをファイルの中のUNIXTIMEを1行目から500行目まで一括で変換したい。
1157601611
1157601612
1157601613
1157601614
・
・
・
みたいにならんでます
>>87 すいません。コマンドでした。
でもシェルでも出来ると思って・・・。
>>90 じゃあ、hoge.txt に
1157601611
1157601612
1157601613
1157601614
が書かれてるとして、
以下を実行
↓
for t in `cat hoge.txt`
do
date -d "1970-01-01 09:00 $t seconds"
done
92 :
名無しさん@お腹いっぱい。 :2006/10/04(水) 17:12:32
>>91 ありがとう御座います。
temp.txtに書き出しながら処理するにはどうしたら良いですか?
>>92 done の行を
done > temp.txt
にすればいいだろ。ただのリダイレクトだよ。
というか、質問者の
>>85 自体がすでに答えになってるのに、
何を質問したいのか意味不明。
>>85 のやりかたでやるなら、
awk '{print strftime("%c",$1)}' > tempuni.txt < hoge.txt
で桶。
もしかして、単に入力ファイルのリダイレクト方法を知らなかっただけ?
95 :
名無しさん@お腹いっぱい。 :2006/10/04(水) 18:40:49
質問です( ・ω・)∩ CSVファイルの特定のフィールドの日付を書き換えなきゃなりません。 たとえば三番目のフィールドを199912から200001のように全行書き換える にはどうしたらいいのでしょうか。 日付計算は終わってます。${B_YEAR}${B_MONTH} →${A_YEAR}${A_MONTH} に入れ替えたいのですがsed使ってもなかなかうまくいきません。 awkで特定のフィールドを表示する方法ならわかるのですが、特定のフィールド を置き換えた上で他のフィールドをそのまま表示する方法がわかりません。
CSVはどういう書式のCSVかによって難易度がまるで違うので 厳密な仕様をください。""中の"や,の扱いとか。
>>91 date -f hoge.txtは使えないのかなあ
>>97 date -f は、UNIX時間の形式(ただの数字)には対応してない。
(やってみればわかるが)
なので、
>>91 で正解。
>>98 cat hoge.txt |sed -e "s/.*/1970-01-01 & second/;" |date -f -
で出来た
101 :
名無しさん@お腹いっぱい。 :2006/10/04(水) 20:38:07
CVSファイルには日付とか入っています ""はないです。 YYYYMM,HOGE,0,YYYYMM,YYYYMM,------中略-------,YYYYYMM,0,0,0,0 のような感じで日付が何箇所あります。現時点では各日付の関係 がわかりません。 m(_ _)m
>>99 いや、わざわざ sed 通すくらいなら
>>94 でいいだろ。1プロセスで済むし。
>>102 manにdate起動のオーバーヘッド云々って書いてある。
awkはbash以上に使えるなw
WINDOWS上でシェルスクリプトを作成して、UNIXサーバー上で実行させたいのですが、 WINDOWS上でシェルスクリプト動作確認をする方法はありますか?
bashからawk使えばいいじゃん バカくせぇ
>>101 cutやpasteコマンドを使うところなのかもしれないし、
シェルスクリプトとは言い難いが
perl -apF, -e '$, = ","; $/ = "\n"; splice(@F, $n, 1, $F[$n]を加工); print @F' < csvファイル
で出来ない?
-apF,のとこ、pじゃないやnだ。
>>95 GNU sed を使うという手もある。
例)
$ echo 'abcdef' | sed 's/a\(b\)c\(de\)f/x\1y\2z/'
xbydez
112 :
名無しさん@お腹いっぱい。 :2006/10/07(土) 03:06:18
>>109 >>111 ありがとぅございますっっヽ(●´∀`)人(´∀`●)ノ
Solaris環境で自分で勝手にはgnu sed使えないのですが
perlは入っているので試してみます。∩(´∀`)∩ワァイ♪
シェル内の変数が0の時の挙動についておしえてください。 Windowsで使う下記のような内容のバッチファイルを作るために、 Solaris8上で簡単なスクリプトを作成しますた。 <バッチファイルの中身 (期待している実行結果)> lha32 a D:\save\0.lzh D:\work\0\ lha32 a D:\save\1.lzh D:\work\1\ lha32 a D:\save\2.lzh D:\work\2\ : lha32 a D:\save\9999.lzh D:\work\9999\ (←9999部分は、実際は第1引数で指定) <作ったスクリプト> #!/bin/sh COUNT=0 LAST=$1 while [ $COUNT -le $LAST ] do echo "lha32 a D:\\save\\$COUNT.lzh D:\\work\\$COUNT\\" COUNT=`expr $COUNT + 1` done
114 :
続き :2006/10/07(土) 10:55:42
ところがこのスクリプトを実行すると、最初に実行されるCOUNT変数が0のときに 0の値が消えてしまう現象が出てしまいまつ。(´・ω・`) <shの実行結果> lha32 a D:\save.lzh D:\work ←0が消えている lha32 a D:\save\1.lzh D:\work\1\ lha32 a D:\save\2.lzh D:\work\2\ : 試しにシェルの種類を変えてみたところ、ksh, zsh は sh と同じ挙動を示し、 bashのみ期待していた出力となりますた。 <bashの実行結果> lha32 a D:\save\0.lzh D:\work\0\ lha32 a D:\save\1.lzh D:\work\1\ lha32 a D:\save\2.lzh D:\work\2\ : この現象について、 ・何故、0が消えるのか? ・/bin/shを使った場合に0を表示させる方法 について教えてください。 おまいら、よろしくおながいします。
man echo
>>113 それは、echoコマンドの仕様が違うため。
Solarisなどの /bin/sh の echo は、bashの echo -e に相当する。
echo -e 相当だと、\ が、シェルと echoで2回解釈されるので、
単純な \ を出力させたければ、\\\\ と書かないと行けない。
よって↓で桶。
echo "lha32 a D:\\\\save\\\\$COUNT.lzh D:\\\\work\\\\$COUNT\\\\"
117 :
113 :2006/10/07(土) 12:08:24
>>116 回答ありがとうございますた。
\がシェルと echoで2回解釈されるとは知りませんですた…。
\0になりうる場所のみ二重化すればよいから、 echo "lha32 a D:\\save\\\\$COUNT.lzh D:\\work\\\\$COUNT\\" でもいいな。
>>118 ashとかだと、\1 でも 8進数の1と解釈するから、それはお勧めできない。
すべて \\\\ にするのが吉。
エスケープだらけでややこしいな。 echo時は無難な/にでもしといて |sed とかしてまとめてエスケープつけると 見やすいかも。好きずきだが。
ash(´゚c_,゚` )プッ んな中途半端なもん使うなや それに\1になりうるのは\\$COUNTのところだけだろ。
D:\\save じゃなくて、 D:\\tave とかだったら困るだろ。 \\\\ にしとけ。
UNIXのコマンドは\をエスケープキャラクタとして使用するものが多い。 ディレクトリ区切りは/としておいて、最後に一括変換すればよい。 #!/bin/sh COUNT=0 LAST=$1 while [ $COUNT -le $LAST ] do echo "lha32 a D:/save/$COUNT.lzh D:/work/$COUNT/" COUNT=`expr $COUNT + 1` done | tr '/' '\\'
\(´゚c_,゚` )プッ んな中途半端なもん使うなや
適当に'〜'を混ぜて、\の部分をシェルには解釈させないようにすればいい。 というかむしろ変数展開部分だけ"〜"使え。ややこしいときは。 echo lha32 a 'd:\\save\\'"$COUNT.lzh" 'd:\\work\\'"$COUNT"'\\'
echo に関してだけはbashがGJだとおもうな。 printf があるのに、エスケープシーケンスを解釈してしまうようなままにしとくのがいけない。 バッドノウハウの典型だな。
やっぱ bash使えば直るよねぇ
echoがエスケープシーケンス解釈しないのはBSD由来なわけだが。 んで、echoがエスケープシーケンスをデフォルトで解釈するビルドもできちゃう どっちつかずなbashがGJなのかよw
デフォルトは有効でもいいが、オプションで無効にできたりするといいがな。
大多数のshができないものは基本無効、オプションで有効だろ?
ちゃうだろ。 Solarisなどのecho(/bin/echoも含む)が、エスケープシーケンスを無効にする方法がないことをいってるんジャマイカン?
132 :
95-101 :2006/10/10(火) 14:04:36
m(_ _)m アリガトォ〜 ゴザイマス★ /usr/bin/sed /usr/ucb/sed /usr/xpg4/bin/sed でも動作しました。
133 :
名無しさん@お腹いっぱい。 :2006/10/16(月) 01:05:51
sambaで共有している関係で「スペース」の入ったdirがある状況で、 特定拡張子のファイルを一括処理しょうと思い、 for file in `find . -name "*.hoge"` do のようにやると、スペースごとに変数fileに入ってしまうのだが 簡単な回避方法ありますか?
find . -name "*.hoge" | while read line;do echo "@ $line @";done
>> 134 ありがと。勉強になりました。 while 使えば行処理できたのか〜。
与える先がxargsなら find ... -print0 | xargs -0 もあり。
137 :
名無しさん@お腹いっぱい。 :2006/10/17(火) 17:36:58
変数 $1111 には aaa bbb ccc ddd eee fff といった文字列(6行)が入っている。 変数$2222には bbb ccc といった文字列(2行)が入っている。 $2222の中身を、「1行ずつ」grepキーワードとして、 cat $1111 | grep bbb cat $1111 | grep ccc と個別にcatを実行したい。 どうしればいいだろう。
宿題は自分で。
>>137 $2222 って、2,222個目の引数のことだぞ。普通のシェル変数じゃない。
で、勝手に $hoge1 $hoge2 と置き換えさせてもらうが、答えは echoを使うこと。
echo "$hoge1" | grep bbb
echo "$hoge2" | grep ccc
ダブルクォート " " で囲むのが重要。
変数$2222の値を見ながら手でコマンドを入力する。
いや139は正解じゃないだろ... $2222でループまわすことが求められていると思うのだが。
いや、問題自体が間違っている
>>137 が悪いな。
後付けで問題訂正されるより、
>>137 がもう一度正確な問題を書くまで待機した方が良さそう。
もしかしてこういうことか? ↓ for keyword in $hoge2 do echo "$hoge1" | grep "$keyword" done $hoge2のところは " " なし(←これ重要) $hoge1のところは " " あり(←これ重要)
echo じゃなくて cat でしょ?
>>146 勘違いかどうかわかんないじゃん。
決めつけはよくないよ。
>>145 オマエアフォだな。もし catだと、
aaa
bbb
ccc
ddd
eee
fff
という改行付き6行もある変態的なファイル名のファイルを読み込むことになるんだよ。
echoの間違いだとエスパーしてあげたのは親切と言えよう。
だからぁ、
>>137 がもう一度正確な問題を書くまで待機しろ、と言っただろ。
本当に catなら、「catが無駄です」の例になるな。 ↓こういうことか? for file in $hoge1 do for key in $hoge2 do grep "$key" < "$file" done done
>>148 変態的なファイル名の可能性もあるし、
複数のファイル名が変数に格納されてるのかもしれない。
勝手な解釈しちゃいかんよ。
いや、実際に bbb とか ccc とか、grepで一致する例が含まれてるし、
変数 $1111 改め $hoge1 の内容はファイル名じゃなく、文字列そのものだろ。
>>144 のエスパー(echo)が正しいに1票。
>>150 だと、「変数 $1111には1行ずつファイル名が入ってます」とかいう表現になるはず。
>>152 その可能性もあるけど、あくまで可能性。
そこは本人に言わせなきゃだめだよ。
ほんにんはにげだした・・・ 0ポイントのけいけんちかくとく
155 :
137 :2006/10/17(火) 22:47:25
>>139 あ、そうだった。1111番目のひき数って意味ではなく、ご認識の通り。
catはファイル名対象が前提なんですね。
スクリプト内での処理ですので、echoのことです。訂正します。
>>144 氏ので行けそうな気がする。ありがとうございます>各位
今回は"ファイル名"というものは存在しません。
156 :
137 :2006/10/17(火) 22:59:57
Cygwin動かないので明日会社で試す。 というか、変な質問してしまったことに今気がついた。 迷惑かけた。 今日8時間ぐらいずっとそれで悩んでたんだ。 googleで調べるとreadって命令を見つけたのでずっとそれと格闘してた。
157 :
名無しさん@お腹いっぱい。 :2006/10/18(水) 10:08:51
>$hoge2のところは " " なし(←これ重要) >$hoge1のところは " " あり(←これ重要) これなんで? あっても無くても同じじゃないの?
>>157 word splittingが行われるので違ってくるんだな。
同じじゃないよ。
for keyword in $hoge2 do echo "$hoge1" | grep "$keyword" echo TEST done 別人だけど、これを実行しても aaa bbb ccc ddd eee fff TEST と表示されてしまうぞ。 bbb TEST ccc TEST とならなってくれないとおかしいのでは。
161 :
157 :2006/10/18(水) 10:17:06
つまり、 echo $hoge1 としたのでは、 下手すると $hoge という文字列そのものが表示されてしまう恐れがあるってことかな。
単語の分割 シェルはパラメータ展開・コマンド置換・算術式展開 (ダブルクォートの内部ではこれらの展開は行われません) の結果をスキャンし、 単語分割 を行います。シェルは IFS のそれぞれの文字を区切り文字として扱い、他の展開の結果をこれらの文字によって単語に 分割します。 IFS が設定されていないか、その値が正確にデフォルト値の <スペース><タブ><改行> ならば、 IFS 文字の任意の列 で単語が区切られます。 IFS がデフォルト以外の値を持っていれば、空白文字 (スペース および タブ) の列は単語の先頭と末尾 では無視されます。これは空白文字が IFS の値 ( IFS 空白文字) に含まれる限り成り立ちます。 IFS に含まれ、 IFS 空白文字で はない文字は全て、隣接する任意の IFS 空白文字と一緒になってフィールドの区切りとなります。 IFS 空白文字の列も区切り文字 として扱われます。 IFS の値が空文字列であれば、単語分割は全く行われません。 明示的に指定した空の引き数("" または '')は削除されずに残ります。クォートされていない暗黙的な空の引き数が、値を持たない パラメータを展開した結果として得られますが、これらは削除されます。値を持たないパラメータがダブルクォート内部で展開される と、これは空である引き数となり、消されずに残ります。 展開が行われなければ単語分割も行われない点に注意してください。
163 :
名無しさん@お腹いっぱい。 :2006/10/18(水) 10:42:40
echo ${hoge1} これでもいいんだよね
>>163 だめ。
echo ${hoge1} と echo $hoge1 は全く同じ。
echo "$hoge1" と同じなのは、echo "${hoge1}"
>>160 zsh 使ってるんじゃない?
zsh だと、$hoge2 と書いても "$hoge2" と同じに解釈される糞仕様なので、、、
shかbashでやってみろ。
>今日8時間ぐらいずっとそれで悩んでたんだ。
168 :
名無しさん@お腹いっぱい。 :2006/10/18(水) 13:51:26
質問です。 ファイルに ID,ファイル名,1,sed7s/(正規表現)正規表現/正規表現/',と並べてます for LINE in ${LINE} ; do IFS=',' FILE="$1" SW="$2" CMD="$3" case $SW in "0" ) コピーするだけ。;; "1" ) cat $FILE | $CMD" > hogehoge ;; esac done <ファイル echo "$hoge1" | grep "$keyword" done <FILE どやってみたのですがうまくいきません。 設定ファイル上にかかれた正規表現や変数を含むコマンドを実行するには どうしたらよいのでしょうか?
169 :
名無しさん@お腹いっぱい。 :2006/10/18(水) 13:52:49
下記二行は間違いです >echo "$hoge1" | grep "$keyword" >done <FILE
170 :
名無しさん@お腹いっぱい。 :2006/10/18(水) 14:30:50
syslog02# cat list.txt EAST,01,blue,192.168.1.1,3:1 EAST,03,blue,192.168.1.1,3:2 EAST,05,green,192.168.1.2,3:3 EAST,03,green,192.168.1.2,3:8 EAST,05,red,192.168.1.3,3:12 syslog02# cat 2ch_sh #!/usr/local/bin/bash IFS=$'';SORT=(`cat $1 | sort -t, -k3`) IFS=$'';UNIQ=(`cat $1 | sort -t, -k3 | awk -F , '{print $3 }' | uniq`) for keyword in "$UNIQ" do echo "$SORT" | grep "$keyword" echo test (本当はここでファイルを作成したい) done ------------
171 :
名無しさん@お腹いっぱい。 :2006/10/18(水) 14:33:46
【理想】 syslog02# ./2ch_sh list.txt EAST,01,blue,192.168.1.1,3:1 EAST,03,blue,192.168.1.1,3:2 test EAST,05,green,192.168.1.2,3:3 EAST,03,green,192.168.1.2,3:8 test EAST,05,red,192.168.1.3,3:12 test 【現実】 syslog02# ./2ch_sh list.txt EAST,01,blue,192.168.1.1,3:1 EAST,03,blue,192.168.1.1,3:2 EAST,05,green,192.168.1.2,3:3 EAST,03,green,192.168.1.2,3:8 EAST,05,red,192.168.1.3,3:12 test
172 :
名無しさん@お腹いっぱい。 :2006/10/18(水) 19:00:48
>>168 全然駄目。shの文法を読み直す。set -xで動作を追跡することを憶える。
その上で判らない場合に出直しなさい。
条件もダメダメだし。(sed7sってなんだよ。'が閉じてねーぞ)
> ファイルに ID,ファイル名,1,sed7s/(正規表現)正規表現/正規表現/',と並べてます
173 :
名無しさん@お腹いっぱい。 :2006/10/18(水) 20:25:31
cshの環境で、アプリケーションログを /backup/apl -mtime +6 -exec rm {} \; 上記のようい週次バックアップしています。 これを、直近のデータのみリストアする場合、 (最新のデータのみで、あとはいらない) どのような表現を使えばいいのでしょうか?
>>170 それでできるはず。ちゃんとbash使ってる?
175 :
名無しさん@お腹いっぱい。 :2006/10/18(水) 22:02:08
170のやり方だと for keyword in "$UNIQ" でそもそも複数行一括で処理するような気がする
おまえら、もう一度 "$hoge" と $hoge の違いを復習汁。
177 :
名無しさん@お腹いっぱい。 :2006/10/19(木) 03:50:14
過去ログを参行にもう一度挑戦しました file -------------------------------------------------- hoge:0: hoge:1:sed "s/a\\(b\\)c\\(de\\)f/x\\1y\\2z/": hoge:1:sed 's/a\(b\)c\(de\)f/x\1y\2z/': ------------------------------------------------- hoge ------------------------------------------------ abcdef ------------------------------------------------ #!/bin/sh while read LINE ;do IFS=':' set -- ${LINE} FILE=$1 SW=$2 CMD=$3 case $SW in "0" ) echo HOGE ;; "1" ) cat $FILE | $CMD >hogehogehoge;; esac done <file
178 :
名無しさん@お腹いっぱい。 :2006/10/19(木) 03:51:43
sh -x ./hogehoge + read LINE + IFS=: + set -- hoge 0 + FILE=hoge + SW=0 + CMD= + case $SW in + echo HOGE HOGE + read LINE + IFS=: + set -- hoge 1 'sed "s/a\(b\)c\(de\)f/x\1y\2z/"' ' ' + FILE=hoge + SW=1 + CMD='sed "s/a\(b\)c\(de\)f/x\1y\2z/"' + case $SW in + cat hoge + 'sed "s/a\(b\)c\(de\)f/x\1y\2z/"' ./hogehoge: line 13: sed "s/a\(b\)c\(de\)f/x\1y\2z/": No such file or directory
179 :
名無しさん@お腹いっぱい。 :2006/10/19(木) 03:52:19
+ read LINE + IFS=: + set -- hoge 1 'sed '\''s/a(b)c(de)f/x1y2z/'\''' ' ' + FILE=hoge + SW=1 + CMD='sed '\''s/a(b)c(de)f/x1y2z/'\''' + case $SW in + cat hoge + 'sed '\''s/a(b)c(de)f/x1y2z/'\''' ./hogehoge: line 13: sed 's/a(b)c(de)f/x1y2z/': No such file or directory + read LINE + IFS=: + set -- + FILE= + SW= + CMD= + case $SW in + read LINE
180 :
名無しさん@お腹いっぱい。 :2006/10/19(木) 03:53:51
このようなメッセージが出て先に進みません(T-T) どう改善すればよいのでしょうか ./hogehoge: line 13: sed "s/a\(b\)c\(de\)f/x\1y\2z/": No such file or directory
>>180 そのエラーメッセージの意味がわかるように中学からやり直す。
./ほげほげ: 13番線: sed "s/a\(b\)c\(de\)f/x\1y\2z/": 番号、そのようなやすり、さもなければ登録簿。 訳してみましたが、意味がわかりません。
183 :
名無しさん@お腹いっぱい。 :2006/10/19(木) 12:18:27
ここがおかしいのはりかいできるのですが・・・ cat $FILE | $CMD >hogehogehoge;; $CMDの部分に実行できるコマンドを代入するほうほうはないでしょうか?
「sed "s/a\(b\)c\(de\)f/x\1y\2z/"」という名前のコマンドを実行しようとして
ないと言っているのがそのエラーメッセージ。
「sed」コマンドに引数「"s/a\(b\)c\(de\)f/x\1y\2z/"」を与えるのがやりたい
ことだろうがそうはなっていないわけだ。
で、どうしてそういうことになってるかは
>>162 で引用されているシェルの
マニュアルの単語分割のところをよく読め。特にお前さんの場合はIFSを
いじっているのでそこらへんも効いている。
ShellScript ↓ 日本語訳 貝???
189 :
名無しさん@お腹いっぱい。 :2006/10/20(金) 02:09:28
>>185 >>186 IFSをループの外にしてevalでSolaris環境では解決しました。
ありがとう。 Cygwinでは改行コードで怒られます。
#!/bin/sh
IFS=','
while read FILE SW CMD
do
case $SW in
"0" )
echo HOGE ;;
"1" )
cat $FILE | eval $CMD >hogehogehoge;;
esac
done <file
file
-------------------
hoge,0,
hoge,1,sed 's/a\\(b\\)c\\(de\\)f/x\\1y\\2z/',
-------------------
hoge
--------------------
abcdef
------------------
hogehogehoge
------------------
xbydez
-------------------
190 :
名無しさん@お腹いっぱい。 :2006/10/20(金) 02:12:15
>>184 catが無駄というのは$CMD $FILE >hogehogehoge
という事でしょうか。
$FILEにファイル名が複数入っている可能性があるのならそのcatもあながち 無駄ではないかもしれない。
>>194 その可能性はあり得ない。
>>189 で
while read FILE SW CMD
↑
って書いてるから。よってやはり「catが無駄です」
catが無駄かどうかがこんなに盛り上がるとは。
freebsd の sleep 議論ってやつやね
シェルスクリプトって便利で好きだけど、限度があるからperlに逃げる。 シェルスクリプトならでは、という美しいサンプルはどの辺に行けば見れますか?
/etc/init.d
シェルスクリプトは美しさを求めるもんじゃないと思う。
工エエェェ(´д`)ェェエエ工
シェルスクリプトならではのねじれ曲がったサンプルなら./configure
203 :
名無しさん@お腹いっぱい。 :2006/10/23(月) 16:20:35
Linuxの~/.bashrcに unalias vi という行を追加しました。というのは、ディフォルトのviだと、文字が緑ではなく、いろんな色でカラフルに 表示されるので、unaliasしてみたら、緑一色で表示できたので。 これでviは快適に使えるようになったのですが、別の問題が起こりました。 それは、bashを起動して別のシェルを動かした場合に.bashrcがもう一度実行されるので、 既にviはunaliasされているにもかかわらず、再度unaliasしようとして以下の警告が表示されます。 bash: line 49: unalias: vi: not found 警告が出ても、処理は問題なくできるので、気にしなければ、いいのですが、 でも気になるので、何か良い解決方法を教えてください よろしく。
>>203 単に
alias vi=
の行を.bashrcから削除すりゃいいのでは、と思ったが、
/etc/のどこかで定義されてるのかねぇ。
alias | grep '^alias vi=' >/dev/null && unalias vi
alias して unalias すればいーじゃん
>>203 ~/.bash_profile に書けば?
ちっともシェルスクリプトじゃない。
>>205 それするくらいなら、
unalias vi 2> /dev/null
でいいじゃん。メッセージを捨てるだけ。
211 :
名無しさん@お腹いっぱい。 :2006/10/23(月) 18:44:40
>206 この方法で解決しました。 ありがとございます。
遅レスだが
>>165 > zsh だと、$hoge2 と書いても "$hoge2" と同じに解釈される糞仕様なので、、、
setopt SH_WORD_SPLIT あるいは明示的に${=hoge2}とする。
213 :
名無しさん@お腹いっぱい。 :2006/10/25(水) 16:35:32
第一フィールドがmm/dd/yyyy 第二フィールドがhh:mm:ss 第三フィールドが""で囲まれたアカウント名 となっている。 「アカウント名が重複しているものは、その最新日付のみを残して、 他の重複行はすべて削除」 という具合にしたい。 uniqを使えばいいのかもわからないが、やっぱりわからない。 どうすればいいだろう。 08/11/2006 14:29:50 "yamamoto" 03/03/2006 06:40:53 "yamada" 05/17/2005 07:45:07 "yamada" 07/13/2005 04:18:04 "yamada" 07/13/2005 13:17:56 "yamada" 08/04/2005 11:03:05 "yamada" 08/11/2005 05:54:56 "yamada" 08/11/2004 07:58:53 "yamada" 12/07/2005 13:54:19 "yamada" 12/22/2005 00:26:49 "yamada" 08/05/2005 02:48:41 "kinosita" 08/05/2005 11:49:58 "kinosita" 08/05/2004 11:51:45 "kinosita" 08/06/2005 04:55:50 "kinosita" 02/21/2005 16:34:40 "akie" 02/21/2006 17:20:21 "akie" 02/21/2006 17:22:56 "akie" 02/21/2005 17:41:45 "akie" 02/21/2005 17:47:14 "akie"
>>213 こんなんシェルスクリプトでやりたくないな。
perl かなんかで。
連想配列使える言語(awk, perl, csh)を使わない理由は?
>>213 シェルで簡単にできるよ。
ちょっとパイプが多段だけど。
↓
while read dt tm user
do
echo $dt $tm `date +%s -d "$dt $tm"` $user
done | sort -nr | uniq -3 | while read dt tm sec user
do
echo $dt $tm $user
done
ポイントは、dateで単純な秒数に変換する前処理をしてから
フィールドスキップして uniq すること。
その後で秒数フィールドを削除して元に戻してる。
GNU dateが必要かも知れない。
perl とか 連想配列とか言ってる香具師は弱もの。
弱ものってなんだろ。
218 :
名無しさん@お腹いっぱい。 :2006/10/25(水) 17:04:25
どうもです。 perlなどでやったほうがお手軽なんですね。 覚えがあるのがshellだけなので、やむをえず・・・。 Cygwinじゃdate -dでエラーになるので、FreeBSDで試してみます。
>GNU dateが必要かも知れない。 こんな俗物に頼る方が、頭がヨワイ。
>>219 08/11/2006 14:29:50
を、
2006/08/11 14:29:50
に変換する前処理を入れれば、
date使わなくても
>>216 の方法で行けるよ。
>>216 って短時間に良くこんなシェルスクリプト組めますね。
さてはかなりのプロと見た。
>>216 >done | sort -nr | uniq -3 | while read dt tm sec user
sort -k 3 -nrだろう
>>216 それだと名前の順序が変わるから
> その最新日付のみを残して、他の重複行はすべて削除
を満たさない。
それと、uniq ではスキップするフィールドを指定するんだから uniq -2 だし、
uniq が削除するのは連続した場合だから名前フィールドでの sort も必要。
>>223 いや、uniq -3 は合ってるよ。1フィールドを追加してるから。
date で追加するフィールドを頭に持ってきて、 sort -nr | uniq -3 で最新日付だけ残して 最後に頭のフィールドを削除するのが奇麗だな。
>>227 確かに。時間毎にユーザーがバラバラな場合も考慮するとそうだな。
cat -n | \ sed 's,^[[:space:]]*\([0-9][0-9]*\)[[:space:]]*\([0-9][0-9]*\)/\([0-9][0-9]*\)/\([0-9][0-9]*\)[[:space:]]*\([^[:space:]][^[:space:]]*\)[[:space:]]*\(.*\),\6 \4/\2/\3 \5 \1 \6,' | \ sort -r | uniq -4 | sort +3n | \ sed 's,^\([^[:space:]]*\)[[:space:]]*\([0-9][0-9]*\)/\([0-9][0-9]*\)/\([0-9][0-9]*\)[[:space:]]*\([^[:space:]][^[:space:]]*\).*,\4/\2/\3 \5 \1,'
連想配列サポートしている言語の方が楽じゃないかね。www
>>230 シェルスクリプトでの回答例が出ている後でそんなこと言っても,みっともないだけw
まとめてみた。 while read dt tm user; do echo $dt $tm $user `date +%s -d "$dt $tm"` $user done |sort -k 3 -r |uniq -4 |cut -d" " -f 1-3
>>232 date の -d オプションは標準ではない
入力ファイルの順序が保存されてない
>>233 dateを使わない方法は
>>220 が示している。
入力ファイルの順序は、もともとの質問では問うていない。
>>234 > dateを使わない方法は
>>220 が示している。
>>219-220 抜かしたらまとめにならんだろ。
> 入力ファイルの順序は、もともとの質問では問うていない。
元の質問は「他の重複行はすべて削除」ね。入力ファイルから重複行を削除した
ものは当然に入力ファイルの順序が保存されてる。
順序を変えていいのは順序は問わないと明記されてる場合だけ。
いや、もともとの
>>213 の質問の意図からすると、
各ユーザ毎に最新時刻の行だけを抜き出したら、
それらの行全体が時刻順にソートされていた方が都合がいいだろう。
そういう意味でも、たまたま入力された順序にユーザーが並ぶ必要は全くない。
>>232 09/09/2001 00:00:00 "name"
09/10/2001 00:00:00 "name"
sed で文字列を抽出して sh の変数に入れたいんですが、 抽出させたい文字列が二つあります。 一回の sed で二つの出力を二つの変数に入れるのにはどうしたらいいですか? なんか read を使えばできそうな感じなのですが、 なかなか難しくてできていません。
>>238 sed でどう出力するのか分からんけど
パイプを使って代入しても意味が無いから気をつけろ。
sed '処理' | read a b
とかやっても a や b の中身はパイプの中でしか
参照できない。
set -- `sedでほしい2つだけを抜き出す` とかかね?
sedじゃないものを使ったほうが上手くいくと見た
242 :
238 :2006/10/26(木) 03:53:46
read を使って代入しても
サブプロセスの中の変数にしか影響を与えない場合が
あるとかなんとかで(
>>239 さんの言ってることですね)、
exec 使ってリダイレクションをかえるとかそういうのに挑戦しましたが
生半可な知識ではたちうちできず、
結局別の方法で逃げました。
>>240 さんの方法は今回は使えませんでしたが勉強になりました。
いやー難しい。
>>232 改良してまとめた
while read dt tm user; do
printf "%s %015d %s\n" $user `date +%s -d "$dt $tm"` $user;
done |sort -nr |uniq -2 |while read user sec user1; do
echo `date "+%m/%d/%Y %T" -d "1970-01-01 00:00:00 UTC $sec sec"` $user;
done;
>>244 2 回目の read はいらんだろ。変換前の値もつけとけばいい。
しかし、なんで標準外の date の -d オプションにこだわるんだ?
while read dt tm user; do
tmp=${dt%/*}; x=${tmp#*/}
echo $user ${dt##*/}/${dt%%/*}/$x $tm $dt $tm $user
done | sort -r | uniq -f 5 | cut -d ' ' -f 4-
入力順も保存したいなら
cat -n |
while read num dt tm user; do
tmp=${dt%/*}; x=${tmp#*/}
echo $user ${dt##*/}/${dt%%/*}/$x $tm $num $dt $tm $user
done | sort -r | uniq -f 6 | sort -nk 4 | cut -d ' ' -f 5-
2 つのフィールドを持つ A, B ファイルを結合したいのですが、 一方にしか存在しないフィールドはそのまま出力し、 それ以外は第二フィールドを B に変更したいのです。 例えば次のようなファイルを: foo 0 bar 0 -- foo 1 qux 1 次のように: foo 1 bar 0 qux 1 順序は不同なのでソートしちゃっても構いません。 どのような方法があるでしょうか?
cut -f1 -d ' ' uniq uniq -d を使って適当に。
>>247 ありがとうございます。
join(1) あたりで出来るかと思ったんですが、いまいち上手くいかないorz
もう少し頑張ってみます。
for aa in a b; do cat $aa |sed -e "s/ / $aa /;"; done |\ sed -e "s/\([^ ]*\).*/& \1/;" |sort -r |uniq -3 |cut -d" " -f 1,3
あなたが書いた最大のシェルスクリプトの文字数は?
251 :
名無しさん@お腹いっぱい。 :2006/10/29(日) 09:16:24
縦書き mm=80; nn=3; pp=`printf "%0${nn}d" 0`; for ((aa=0; aa<$mm; aa++)); do bb[$aa]=$pp$aa; done; for ((aa=-$nn; aa<0; aa++)); do for ((aa1=0; aa1<$mm; aa1++)); do echo -n ${bb[$aa1]:$aa:1}; done; echo; done;
>>252 脈絡なく何を言いたいかわからんが、
zsh依存乙。
bashですら動かない依存スクリプトは、Bourne-sh互換に書き直して出直すこと。
254 :
246 :2006/10/30(月) 20:11:41
>>249 なるほど. そういう使い方もあるのですね.
これで上手くいきそうです. ありがとうございました.
>>252 俺の環境ではこうなったが、これでいいのか?
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000001111111111222222222233333333334444444444555555555566666666667777777777
01234567890123456789012345678901234567890123456789012345678901234567890123456789
$ bash --version
GNU bash, version 3.1.17(9)-release (i686-pc-cygwin)
不定個のコマンドをパイプで繋げて処理する方法はないですか?
>>256 文字列でパイプライン組み立ててevalしる
evalを使えば何でも出来る。
ディレクトリ名の引数から末尾の名前だけを取り出すにはどうすればいいでようか? たとえば % hoge /usr/local/bin bin % hoge ~/etc etc % pwd /usr/local/bin % hoge .. local みたいな。
x=$(cd "$dir"; pwd); x=${x##*/}
basenameは反則?
退場
hoge=/usr/local/bin/allneeded % echo $hoge:r /usr/local/bin/allneeded % echo $hoge:t allneeded csh/tcsh/zsh だがね。sh だったら basename だろ?
相対パスがやっかいだな。
basenameはPOSIXにすらあるんだからどんどん使うべし。
basename なんて使わなくても
>>260 でいいじゃないか
bshで使えないからダメ。
POSIX sh で使えるから別にいいんじゃん
これならBourne Shellで動く。 ↓ arg=/usr/local/bin (IFS=/; set $arg; shift `expr $# - 1`; echo "$1")
basenameは外部コマンドでも存在「しなければならない」。
たとえ意味がなくてもcdが外部コマンドとして存在「しなければならない」のと同じ。
だから、
>>266-267 ,269の言ってることは意味がない。考えるだけ無駄。
> たとえ意味がなくてもcdが外部コマンドとして存在「しなければならない」のと同じ。 どこの世界の話だ? SUSv3: > Since cd affects the current shell execution environment, it is always > provided as a shell regular built-in.
お前の挙げているSUSv3の世界だよwwww 1.13 Built-In Utilities However, all of the standard utilities, including the regular built-ins in the table (中略) shall be implemented in a manner so that they can be accessed via the exec family of functions as defined in the System Interfaces volume of IEEE Std 1003.1-2001 and can be invoked directly by those standard utilities that require it (後略)
どこにも「外部コマンドとして存在しなければならない」なんて書いてないが? そこで要求されてるのは they can be accessed via the exec family of functions つまり execve 等から呼出せれば外部コマンドである必要なんてない。
274 :
名無しさん@お腹いっぱい。 :2006/11/06(月) 01:39:02
はいはい、そうでちゅよねーwwww
"in a manner"というニュアンスなんで、なければならない というほどでもないのでは?外野ですが。
in a mannerはso that節につながるだけだよ。 むしろ"shall be"という強い書き方に注目しないといけない。 んで、exec系の関数の説明には The exec family of functions shall replace the current process image with a new process image. The new image shall be constructed from a regular, executable file called the new process image file. と書いてあるわけだ。ちゃんと規格書をあたる点は誉めてやってもいいが、 かなり調べ方が足りないゾwwww
はいはい、そうでちゅよねーwwww
cd の方に nohup cd なんて例があるくらいだから cd が実行ファイルとして存在することを仮定してるんじゃないかな。
うん、仮定っていうより、そう決まってるんだけどね。
ていうか、それはもう
>>272 ですんだ話。
相対パスが多少面倒だな。
マタマタごジョーダンを
cdが外部コマンドになってると何がうれしいのか俺にもわかるように説明してくれないか。 POSIXで決まってるからというのはなしね。なぜそう決めたかの背景を知りたい。
>>282 POSIXで誤ってそう決めてしまった、という説が有力。
後付けの言い訳としては、対象ディレクトリに実際に cdできるかどうかを
テストする目的で使える(返り値で結果判定)、と説明されているが、そんな例あまりないし、
内部コマンドの cdで、
(cd hoge) とやれば済む話。
% cat /usr/bin/cd #!/bin/sh # $FreeBSD: src/usr.bin/alias/generic.sh,v 1.1 2002/07/16 22:16:03 wollman Exp $ # This file is in the public domain. ${0##*/} ${1+"$@"}
>>284 ${1+"$@"} って、 "$@" だけでよくねぇ?
>>283 cdだけならそれでも説明はつくんだけど、外部コマンドとしても存在する
ビルトインコマンド(regular built-in utility)は、cdだけじゃないのがややこしいところ。
alias, bg, cd, command, false, fc, fg, getopts, jobs, kill, newgrp,
pwd, read, true, umask, unalias, wait
謎だよなあ… fcやcommandに至っては、何のために存在するのかすらわからない。
シェル関数はbシェルにも存在するから、外部コマンドのcommandはそれなりに意味があるんじゃね?
うう、わからない… もうちょっとやさしくして
意味のある外部コマンド: (cronとか、inetdとかから直接起動されるとか、 env/nice/time/nohupとかの引数として起動するために外部である必要があるもの) command, false, kill, newgrp, pwd, true 意味のない外部コマンド: alias, bg, cd, fc, fg, getopts, jobs, read, umask, unalias, wait
それより、教育上、「:」の外部コマンド版 (/bin/:)を 配置するべきだ。/bin/[ はあるのだから。
Solarisには /bin/[ (/usr/bin/[)は無い。教育に適さないOSだ。
へーーー
waitはpidを引数にとれるからまったく意味がないわけでもないんじゃないか。
初心者な質問ですが シェルの格納場所を取得できるような変数とかコマンドとか 誰か知りませんか?
which じゃないの ?
>>297 whichは cshのコマンド。それを言うなら type。
typeでは、type shとかやって、/bin/sh とかの PATHは得られるけど、
「この OSにインストールされていて使えるシェルを調べたい」
という質問の回答としては不適当。
>>294 外部コマンドとして起動したwaitだと、どんな pidに対しても、
wait: pid 1234 is not a child of this shell
と言われるが、それに意味あるのか??
bash入門講座してください
起動スクリプト読んでたら set start ってあったんだけどこれ何?
ファイル実行しようとして実行できないときに表示されるエラーなど(まぁ、エラー表示全般)を 表示しない方法ってありますか? /dev/null は試してみましたが、無理でした。
305 :
304 :2006/11/08(水) 01:14:06
いい忘れたけど、Bashでう
エラー表示って、/dev/null にどうやって投げるんだ? 無理だろ
>>307 だから、 2> /dev/null でエラー表示消せるんだってすでに
>>306 が言ってるだろ。
>ファイル実行しようとして実行できないときに表示されるエラーなど は実行しようとしているコマンドではなくシェルが出してるので、 /dev/null にリダイレクトしても消せない。 つーわけで、シェルの出力をリダイレクトしてやればいい。 sh -c 'hoge fuga' 2>/dev/null
>>309 欲嫁。
>>305 で bashだと言ってる。bashなら消せる。
bash$ hoge
hoge: command not found
bash$ hoge 2> /dev/null
bash$
>>299 execすれば同じプロセスだろ。どの程度意味があるかは俺にもよくわからんが(笑)
>>311 execしても、PIDが変わらないだけで別プロセス扱いになるので、
exec前にバックグラウンドで起動したプロセスを wait で待つことはできないよ。
>>312 ありゃーwaitpidはできたよなと思ってよく調べたらshellのwaitコマンドはシステムコール
呼ぶ前にチェックしてるのか(bash調べ)。知らんかった...
314 :
名無しさん@お腹いっぱい。 :2006/11/08(水) 17:15:17
touch で使える書式で、あるファイルの更新時刻を取得したいのですが、 もっとシンプルor可搬性のある方法はあるでしょうか? hoge=`stat -c %y FILENAME|sed -e 's/..\..*//' -e 's/-//g' -e 's/://g ' -e 's/ //g'` touch -t "$hoge" FILENAME2
-rオプションが使えるtouchならそれを使うのがいいと思われる。 -r, --reference=FILE use this file's times instead of current time
316 :
314 :2006/11/08(水) 18:05:29
ファイルを編集したあと、その更新時刻を編集前に戻したい というのが動機なので、それだとだめなのです。
別のファイルを作って、更新時刻だけコピーして、 編集してから更新時刻をコピーし戻せば?
動機が不純
>>316 それだって touch -r で行けるじゃん。
$ touch -r hoge temp
$ vi hoge
$ touch -r temp hoge
$ rm temp
↑で、hogeを編集したあと、もとのタイムスタンプに戻せる。
シェルスクリプトでC言語のscanfみたいなことやるためのコマンドは何でしょうか?
touchもいろいろあるのでよくわからんが、gnuなら時刻指定に@<epochからの秒数>が 使えるはずなので、 hoge=`stat -c %Y FILENAME` でとりだして touch -d @$hoge FILENAME とするのがシンプルじゃないか。
>>320 強いて言えば read が近いと思うが、シェルスクリプトとCじゃ考え方が違う。
scanfと同じものを探すより頭を切り替えたほうがいいと思われる。
外部コマンドとのやりとりがシェルスクリプトなみに簡潔で 変数や構文の取り扱いがperlとかruby程度に洗練された スクリプト言語って何かない? zshとかbashの専用機能使えばそこそこましなのかな?
Perl とか Ruby でいいじゃん。
continuation がまともに使えない ruby は屑 使えないんだったら実装するなと小一時…
ここはそういうスレではありません。
シェルスクリプトの変数について質問です。 以下のように値が格納された3つの変数があるとします。 hoge1=10 hoge2=20 hoge3=30 これを、 for i in `jot 3` do echo $hoge$i done のようなイメージで、変数名を展開し、 それから変数の値を展開したい場合の方法は シェルスクリプトではどのように行うでしょうか?
/etc/rc* 等を見れば例があると思うけど。キーワードはeval。 あなたのしたいことを実現するためには、 echo $hoge1 のような文字列をevalさせればいい。ということは、evalに与えるための echo $hoge1 のような文字列が作れればいい。 そのまま$hogeとなる文字列に、1を作る変数展開をくっつけて echo '$hoge'$i と書くとそれは作れる。 ということは、答えは eval echo '$hoge'$i 例 $ hoge1=foo $ hoge2=bar $ hoge3=baz $ for i in `jot 3`; do eval echo '$hoge'$i; done foo bar baz
安易にevalをつかうな。 配列にした方がいい。
配列はbash依存。evalを使うのが普通。
配列はksh起源ニダ。
evalを安易に使うなというのは同意。
でも、
>>329 の場合は使ってよいケース。
set使ってもいいけど。
bashだけだろ? eval使えるの
みなさま、ありがとうございます!! evalは初めて知りました。 早速試してみますー
evalが使えるからってえばるなよ。
bashの良いところはこれだな。 echo ls |bash
どのシェルでも出来るだろ?
シェルスクリプトの中で vi を起動しているのですが、 そのスクリプトの標準出力をリダイレクトしてしまうと nvi の場合は ex/vi: Vi's standard input and output must be a terminal と出て終了し、vim の場合は Vim: Warning: Output is not to a terminal と出て画面が表示されなくなってしまいます。 リダイレクトしてても普通に vi を操作できるようにする ことはできないのでしょうか?
>>343 できない。そういう場合は ed とか sed とかを使う。
>>343 そのスクリプトの目的が中でviに適当なコマンドを与えて自動的に編集させたいということなら
expectでも使わないとだめだろうが、スクリプトで前処理や後処理はするけどそこから起動した
viは普通にインタラクティブに操作したいというのであれば、vi > /dev/tty とかすればいいと
思われる。どっちを意図してるのかはわからんわけだが。
>>346 前者です。>/dev/tty でできました。
ありがとうございます。
あ、後者だった。
ls|grep -v hoge|xargs rm -i ではまってしまった。 rm -i `ls|grep -v` でごまかした。
351 :
名無しさん@お腹いっぱい。 :2006/11/17(金) 10:38:58
カレントディレクトリにある、拡張子のないファイル「だけ」を消すために、 rm * を実行したら、すべてのファイルが消えてしまいました。(rm *.*じゃないのに) これって、シェルのバグじゃないでしょうか? あと、消してしまったファイルを復活する方法を教えてください。
仕様です。 >> あと、消してしまったファイルを復活する方法を教えてください。 バックアップから戻せばOK
そもそも UNIX では拡張子に大した意味ないんだよ。(一部アプリ以外) 普通は「拡張子」なんて言わず単に「suffix」って言うし。
そうか、Makefileとかは例外の「一部アプリ」だったのか、、
>>351 拡張子の無いファイル名に一致するシェル表現かー
.loginのようにドットで始まるファイルは対象なのか対象外なのかむずかしい
>>356 .loginとかは対象外だろ(つーか、cshの例出すなよ)
hoge.c hoge hage.c hage
↑がある時、hogeとhageだけ消したいということだろ。
そう言えば、拡張子なしのファイルに一致するワイルドカードって
シェルにはないんだな。DOSだと「*」で桶なんだけど。
zshなら*~*.*
>>357 find . -maxdepth 1 \! -name \*.\* -delete
分からないので教えてください。 シェルの中で、あるシェルを呼び出すことを考えています。 2つのシェルはカレントであれば、実行可能なんですが、 パスを変えて実行するにはどうすればよいでしょうか? 例: # pwd /home/hoge1 # ls ../hoge2 A.sh Z.sh # cat ../hoge2/A.sh #! /bin/sh date ./Z.sh # cat ../hoge2/Z.sh #! /bin/sh echo "Call OK!" # ../A.sh 2006年 11月 17日 金曜日 23:15:46 JST ../A.sh: line 4: ./Z.sh: そのようなファイルやディレクトリはありません
A.sh #!/bin/sh pwd
拡張子の無いファイルを消すというか、「.」が無いファイルを消せば。 rm `ls * | fgrep -v .` ファイル名にスペースがあると不十分かもしれん。
>>361 ありがたいのですが、意味がわからないです。
IFSで区切られた必要なファイルのリストがあって、そのリストには載ってないが 実在する余計なファイルを削除するにはどうしたらいいでしょうか? #必要なファイル100個とか files="a.txt 1.html hoge.jpg" #実在するファイル100+1個以上 e_files="1.html a.txt fuga.gif hoge.jpg"
>>363 ディレクトリというのがUNIXにはあるんだけども。
>>365 試してないけどこんな感じで
contains () {
local x="$1"; shift
for i; do
[ "x$i" = "x$x" ] && return 0
done
return 1
}
for f in $e_files; do
contains "$f" $files || echo "rm $f"
done
>>366 ディレクトリというのがUNIXにはあるんだけども。
ls ではディレクトリは出力されませんがな。
alias 付けてなければ。
>>370 こんなんなるんだけど。
$ touch fff
$ mkdir ddd
$ touch ddd/fff
$ /bin/ls *
fff
ddd:
fff
$ rm `/bin/ls * | fgrep -v .`
rm: cannot remove `ddd:': No such file or directory
rm: cannot remove `fff': No such file or directory
$
>>369 大変失礼しました。で、そうのようなコメントがあるのであれば
どうすればよいのでしょうか。
>>350 ちょっとメッセージが違うけど、これでいけることがわかった。
ls|grep -v hoge|xargs -p -n 1 rm
374 :
370 :2006/11/18(土) 12:58:27
>>371 ああ、そういうことか。
>>370 は変なツッコミだった。スマソ。
ls * だとディレクトリの下のファイルがでちゃうから ls -d * だな。
さらに、はじめからディレクトリを除外するとしたら
for x in `ls -d * | fgrep -v .`; do
if [ ! -d $x ]; then
echo $f
fi
done
かな
ls -d * | fgrep -v . | xargs file | fgrep -v 'directory' | awk -F: '{print $1}' | xargs rm
ってのもあるけど
>>365 安直なやり方として、
rm `fgrep -v -f files e_files` # 最初は rm じゃなくechoで試す
ってのがある。
ただし、files と e_files は 1行1ファイルでリストされたものとして。
さらに、files の中に "hoge.jpg" があると、e_files に中にある "hogehoge.jpg" は
削除されないけど。
>>360 シェルとシェルスクリプトは別物だぞw
Z.shのところ絶対パスでやれ。
それだけだ。
378 :
名無しさん@お腹いっぱい。 :2006/11/18(土) 17:32:26
('з')
for文について質問です。 内容はfor文のループ変数に配列を代入することは可能なのか?ということです。 for STARTEND in "(1 100)" "(101 200)";do START=${STARTEND[0]} END=${STARTEND[1]} echo -e "&Avestart\nAve_start=${START}/\n&Aveend\nAve_end=${END}/" > namelist/namelist${START}to${END} done なるスクリプトを書いてみたのですが、 ./speccalc.sh: line 15:(1 100): missing `)' (error token is "100)") なるエラーが出ます。 もしbashで配列を配列のまま代入するということが不可能であるとして、それ以外のシェルで配列のまま代入することが可能なものはあるのでしょうか? あるいはもっと他のツールを使った方がよいのでしょうか? 教えていただけないでしょうか?
380 :
名無しさん@お腹いっぱい。 :2006/11/18(土) 17:35:51
#/bin/bash hairetu=(a b c d e f d) for i in ${hairetu[@]} do echo $i done exit 0 こんな感じか?
>>380 違うだろ。複数の配列を for 文の要素として使いたいらしいが。
bash Uzzzee.. よそ行け
>内容はfor文のループ変数に配列を代入することは可能なのか? 配列をFor文のループ変数に使えるかってことじゃないのか?
どのような結果が得たいのか書けよ
forという事はborne shellだな。 borne shellには配列などというデータタイプは無い。
>>385 "borne shell"って何ですかww
for i in "(1 100)" "(101 200)";do eval STARTEND=$i START=${STARTEND[0]} END=${STARTEND[1]} echo $START, $END done キモい。ただでさえキモい bash でさらにこんなキモいことするのか。
>>387 いんじゃないか。
こんなインチキしか思い付かなかった
perl -e 'foreach $a ([1, 100], [101, 200]) {
print "$a->[0] $a->[1]¥n";
}'
evalが使えるからってエヴァるな。
>>380-390 みなさん早速にレスいただき恐縮です。外出しておりました。申し訳ありません。
質問したかったのは
>>383 さんが書かれたとおりです。
>>387 さんが書かれたスクリプトでうまくいきました。ありがとうございました。
ところで、配列がサポートされているCシェル、Kシェル、Zシェルでは「for文(に相当する構文)のループ変数に配列を用いること」は可能でしょうか?
>>366 ありがとうございます。
とりあえず片付いたらそれをテストしてみます。
>>366 関数を作らず、変数を1個使ってうまくいきました。
>>395 そういう状況で適用したい人は自分で考えるってことで。
今使っている参考書に : ${VAR:="exit script because VAR is not set."} と記述すると、VARに値が設定されていない場合に実行中のスクリプトを 終了させることが出来る、と書かれているのですがうまくいきません。 これはなぜなんでしょうか?わかる方教えてください。お願いします。
>>397 なんていう本? そんな間違った本捨てて、別の買え。
正しくは、
: ${VAR:?"exit script because VAR is not set."}
399 :
397 :2006/11/20(月) 18:43:53
>>398 早速のレスありがとうございました。うまくいきました。
けっこう長い時間これで悩んでたので本当に助かりました。ありがとうございました。
ちなみに参考書は
「入門UNIXシェルプログラミング シェルの基礎から学ぶUNIXの世界」
です。他のところで聞いたらこれを勧められたのですがダメな本なのでしょうか…。
ミスプリ程度の間違いだろ。
別紙とかで訂正とかないのか?
ミスプリなのか書き間違いなのかは知らんが、おかしいと思ったらマニュアル 読んで調べるぐらいした方がいいぞ。
404 :
名無しさん@お腹いっぱい。 :2006/11/21(火) 00:06:55
はじめまして。 最近シェルスクリプト始めたのですがわからないことが あって困っています。 小数の比較ってどうすればできるんですか? --------------------------------------- #!/bin/bash if [ 0.0001 -ge 0.00001 ] then echo "success" fi --------------------------------------- という風に書いて実行するとinteger expression expectedが出てしまうんで すけど、どうしたらいいのでしょうか?
どうもこうもない。 あきらめろ。 awkやperlなど使うしかないだろ。
シェルスクリプトで痩せられんですか??? evalつかえばなんでもできるって…
case $(echo 0.0001 - 0.000001 |bc) in -.*) echo fail ;; *) echo success ;; esac
409 :
名無しさん@お腹いっぱい。 :2006/11/21(火) 02:31:42
こんばんわ。アクセスログの集計をやっています。 元ファイルを加工して1レコードが2フィールドで 接続開始時刻:接続終了時刻 の形式のファイルをawkを使って抽出してあります。 時刻は数値化(Excelの日付表示を数値表示に変換したもの) されているので直接比較可能です。 スクリプトで処理したい作業は あるレコードの接続開始時刻から接続終了時刻の間に A 全レコード中、接続開始時刻が何件含まれているか B 全レコード中、接続終了時刻が何件含まれているか を各レコードの情報とともに表示させることです。 接続開始時刻:接続終了時刻:A件数:B件数 みたいに。 実際には同時接続数がどれぐらいあるかチェックしたいので おおざっぱに掴めればなあと。 awkでレコードを1行読むごとに、全行比較という形で スクリプトを書きかけたのですが、そもそも全行と 比較できず終わってしまっているようです。 {x=0;y=$1;z=$2;if ($1<=y && z<=$2) x=x+1;print x} readlineが必要そうであれこれ試しているのですが、 こちらは全く使ったことがないので苦戦しています。 どなたかお知恵拝借させてください。
>>409 まず
> A 全レコード中、接続開始時刻が何件含まれているか
> B 全レコード中、接続終了時刻が何件含まれているか
を実現する関数かスクリプトを作って
レコードを1行読むごとにそれを実行する、という方法はどう?
awk で関数なんて作ったことないから外しているかも。
同時接続数をチェックするのが目的なら 時刻 接続開始or終了 という形式のレコードを時刻でソートしてから頭からなめて 開始が来たら同時接続数++, 終了が来たら同時接続数-- としたほうが簡単じゃないか。
それなら接続開始・終了をそれぞれ+1,-1にしておいて足せばいい。
readlinkコマンドがない場合、ファイルのリンク先を知るには どうすればいいんでしょうか?
ls -l そして awk
ls -l hoge | sed -e 's/^.* -> //'
readlink を入れるといいよ。
今後は coreutilsは必須として標準化するべきだな。
>>415 ファイル名に -> が入っている場合はアウトかと思っていましたが
やってみたらOKでした。ありがとうございます。
シェルスクリプト環境によって動いたり動かなかったり不便・・・じゃない?
ある環境で確実に動くってことは、それだけで重要な事なのです。 全ての環境で共通に動かせるようにする道は死屍累々ですから。
>>419 笑止。
真にマルチプラットフォームな言語なぞ無い。
そんなあちこちに持ってったりしないしなぁ。 動かなかったら直せばいいだけ。
いや、シェルスクリプトは異なる環境でも少ない修正で動く、だと思うけどな。 所詮テキストファイルだし。
>>423 異なる環境で動かすことを考えて作成されたシェルスクリプトに限定すれば真。
お前ら その昔 「Cはポータブル」 って言われてたんだぞ
>>425 いまでもアセンブリ書くよりはるかにポータブルだが…
結局、どれだけ多くの環境に移植されてるかってことじゃねーの?
その昔「ポータブルC」と呼ばれていたものは、 Cコンパイラ自身がポータブル。
>>425 C言語のソースはポータブルだが、バイナリはポータブルじゃない。
だから、実行形式そのままをポータブルにしたい場合は
Cを使わずにシェルスクリプトで書くというのが常識。
C で書くような規模だけどポータビリティが欲しい時にシェルスクリプトは使わないな。 そういう時は C で極力ポータブルに書く。
>>429 シェルスクリプトにヒアドキュメントでCのソース埋め込めばポータブル。
configure?
>>430 「バイナリが」と言ってるだろ。
どこの世界に、バイナリレベルでポータブルなCがあるんだよ???
そういう場合は Java かなあ。 シェルスクリプトで書くのはシェルスクリプトで良いやと判断した時だけ。
Javaは重いから論外。
Perl/Python/Rubyあたりのスクリプト言語で。
JavaはJavaVMがインストールされている環境でしか動かない、 という意味ではポータブルではない。 同様のことがperlとかにも言える。 シェルがインストールされていない環境はあり得ないので、 そういう意味でシェルスクリプトが最もポータブル。
現状で /bin/sh のポータビリティってどの程度確保されてる? bash に link されてる奴は論外として…
>>437 シェルだけで完結することはほとんどない。
さまざまな外部コマンドを使うことによって機能を実現できる。
つまり外部コマンドの仕様や配置などによって修正を余儀なくされるから、
ポータビリティはかなり低い。
また、それとは別にシェルそのものの実装違いもあるし。
>>439 それは人のレベルによる問題。
普段からポータビリティを気にしてシェルスクリプトを書いていれば、
たとえ外部コマンドを使うにしても、どのOSでも使えるコマンドとオプションの
範囲だけで書く癖が付いているから、ポータビリティの高いスクリプトを
書くことは簡単にできる。逆に、別のOSで動かす予定がなかったのに、
たまたま別のOSでも動かす機会があった時に、そのまま動いてしまうことがほとんど。
一方、Java/perlとかだと、インストールされていなければそこで終り。
ポータブルな範囲で使うならシェルスクリプトが最もポータブル。 シェルスクリプトがポータブルな範囲でのみ仕事を受け付けます。
UNIX板なので別のOSがWindowsだって可能性は考えなくて良いのかな。
なんでこの文脈からWinが出てくるのか理解不能w
でもPowerShellは凄そうだぜ?
どこらへんが?
パイプにテキストじゃなくてオブジェクトが流れるとか。
プロセスコンテクストが違うプログラム同士でどうやってオブジェクトを受け渡すの? シリアライズして渡すのかな。ネットワーク越しにも渡せるの?
cmd.exeより100倍ほど重いけどなw
まさかVMが毎回起動する訳じゃないよね?
シェルスクリプトの中で、リダイレクトされているかどうかを 判定するにはどうすればいいのでしょうか?
>>452 標準出力が、端末か、それ以外(ファイル)かの判定なら、
[ -t 1 ]
でできる。
454 :
452 :2006/11/23(木) 22:31:08
>>453 まさにそれでした。ありがとうございます。
シェルスクリプトを最近勉強し始めた初心者なのですが、クォートのことで ちょっとわからないことがあるので質問します。 $ ABC=100 $ VAR=`echo "'\$ABC'"` $ echo $VAR $ '100' (\はバックスラッシュです) このようになるのですが、実行結果が'$ABC'ではなくて'100'になるのが理解できません。 展開するときに\によって$の効果が打ち消されると思うのですが…。 なぜこうなるかどなたかお教え下さい。お願いします。
>>455 VAR=`echo "'\\$ABC'"`
↑
にする必要がある。バッククォートの中の \ は \\ にする。
あと、ここでは結果的に関係ないけど、
最後の echo $VAR は echo "$VAR" にした方がいいな。
457 :
455 :2006/11/24(金) 12:20:02
>>456 なるほど。$を一つ加えると結果はうまいこといきました。
でもなぜこうなるのかが納得できません。
\\$ABCの部分で一つ目の\が二つ目の\の効果を打ち消して、
$ABCは普通に変数として解釈されechoに渡されると思うのですが…。
それともバッククオートの中では何か特別なルールがあるのでしょうか?
>>457 ($を加えるんじゃなくて \ を加えるんだけどね)
>バッククオートの中では何か特別なルールがある
と言ってるとおり。
\\$ABC は、バッククォートで1回解釈される時に
\$ABC となってから、その中身が解釈される。
`echo "\\$ABC"`
の中身が解釈される時に
echo "\$ABC"
に変わってから実行されるので。
ちなみに、推奨しないが、バッククォートの代わりに $( )を使うと、
VAR=$(echo "\$ABC")
みたいに、\はひとつで良い。
$( ) 使える環境では使っとけ。
460 :
455 :2006/11/24(金) 13:15:21
>>458 ありがとうございました。やっと理解できました。
>>459 $()についても少し調べてみます。使える場合はこっちの方がすっきりしますね。
ご回答いただいた皆様本当にありがとうございました。
$( )は使うな。シェルはポータビリティ大切。
462 :
名無しさん@お腹いっぱい。 :2006/11/24(金) 13:17:14
eval ${ifconfig_args}=\$ifconfig_${ifn} ってどういう風に解釈されるんですか?
>>462 ifconfig_args=AAA
ifn=hoge0
だとすると、
1回目の解釈で、
AAA=$ifconfig_hoge0
になるわな。
で、2回目にifconfig_hoge0の中身がAAAに代入される。
>>461 > シェルはポータビリティ大切。
場合によるでしょ。
コーノウ(←英語は発音大事)
hoge.192.168.0.1 という文字列から 192.168.0.1 の部分を抜き出したいのですが どのようにすればよいのでしょうか?
$( )や配列、算術演算は使っとけ。 スクリプトが読みやすくなるから。
>>466 ↓を実行。標準入力から hoge.192.168.0.1 の文字列を読ませる。
IFS=. read hoge a b c d
echo $a.$b.$c.$d
>>467 そういう理由は軟弱。却下。
読み易さに勝るポータビリティはない。
>>469 ???? 「読み易い」って、書き直すってこと?
そもそもポータビリティの意味を誤解してます。
/bin/shが$()を扱えない環境ってどれ?
>>471 伝統的なBourne shellが/bin/shであるような環境では使えない。
Solarisとか。
Solarisなら無視して桶。ユーザーほとんどいないし。 そのうちSolaris側が /bin/sh -> bash にリンクしてくる可能性すら考えられる。
sh の実体が ksh になることはあっても bash になることはないと断言しよう。
いまさらkshもなかろうw
476 :
名無しさん@お腹いっぱい。 :2006/11/25(土) 02:19:05
アプリの関係でcshで書いてます。 ------------------------ #!/bin/csh set i=`ps axwww|grep -i aaaa | grep -v grep | wc -l` echo $j ------------------------ aaaaは存在しないプロセス。 この実行結果、 「0」でなくて「1」になるのはなぜですか?
477 :
476 :2006/11/25(土) 02:23:46
訂正です。 ------------------------ #!/bin/csh set i=`ps axwww|grep -i aaaa | grep -v grep | wc -l` echo $i ------------------------
>>477 パイプで一気に処理している中身を細切れにして中身を確認してみろ。
あと、pgrep があるならそっちを使った方がいい。
479 :
476 :2006/11/25(土) 02:55:11
>>478 レスありがとうございます。
パイプ grep -v /bin/csh の追加が必要でした。
せめて csh -f にしろや。
ifconfigを使ってネットワークにつないでいるインターフェースのデバイス名だけを 取得するにはどう記述すればよいのでしょうか?
>>481 OSによってifconfigの出力書式が違うかも知れんが、
↓みたいな感じで行ける。
ifconfig -a | sed -n 's/^\([^ ][^ ]*\).*/\1/p'
HP-UXだと、 lanscanだな。
FreeBSD だと ifconfig -l で。
自分で作ったシェルスクリプトの引数に"*"と指定したら、 クォートされずに*が展開されて位置パラメタに入っちゃうんだけどなんでなんでだろ。 echoとかの組み込みコマンドだと上手くクォートされるんだけどなぁ。
>>487 どこかでクォートし忘れているって事なんだろうな。
そのスクリプトを晒してみな
age
noglob とかそういうのを使ってみたり
>>490 それは csh。cshは帰れ。
/bin/shでは set -f
ただし、ちゃんとクォートすれば set -f は必要ない。
$10以降の引数ってどのshでも使えるんでしょうか?
>>492 Bourne Shellでは $10以降は使えない。
bashとかkshとかでは使えるが、${10} とする必要あり。
zshでは $10 でも使える。
$10は ${1}0と解釈されるから、${10}としないとだめ。
zsh は使用料が 10 ドルから、っていう意味?
>>494 Bourne Shell では ${10} でもダメ。逆に zsh では $10 でも桶。
497 :
492 :2006/12/01(金) 00:40:19
皆さんありがとうございます。 shで最後の引数を取得したかったのですが、無理なのですね。
shiftするとかいくらでも方法はある。
GNU Autoconf付属のinfo内の "Portable Shell:: Shell script portability pitfalls" が非常に詳しくて面白い。よくこれだけまとめあげたものだ
>>470 人間レベルポータビリティが高いということだと思う。
狭い範囲でのポータビリティを満たすためにトリックを駆使するより、
移植性のない明快な方法複数のほうが意図が読めるから未知プラット
フォームに持って行きやすい(ことがある)。
>>500 そういう概念を表すためにわざわざ、可読性(readability)とか
保守性(maintainability)とかいう用語が存在してるでしょうに。
そうなんだけど、人間を計算機の一種に見立てて、可読性と 移植性は似てる(生体計算機上で移植性がある=可読性)と 元レスはいいたかったんでないの?
503 :
名無しさん@お腹いっぱい。 :2006/12/02(土) 20:53:48
ABC DEF GHI JKL MNO という文字列を DEF GHI JKL という部分をごっそり抜いて、 ABC hogehoge1 hogehoge2 hogehoge3 JKL としたいのですが、 何か良い案はないでしょうか?
MNOはどこに消えたのか?
>>504 それくらい察してやれ。
それより、DEFやGHIなどの文字列があるものとして置換していいのか、
それとも2行目から4行目までを置換するという意味なのか、
質問の意味が複数解釈できるね。
「ごっそり抜い」 たはずのJKLは なぜ残っているのか?
>>507 だからぁ、察してやれよ、MNOの書き間違いだろ。
これでいいか? gawk だが $ cat minus.awk #!/usr/bin/gawk -f ARGIND == 1 { minus[ $0 ] = sprintf("hogehoge%d",FNR) next } $0 in minus { print minus[ $0 ] next } { print } $ gawk -f minus.awk (抜くキーワードを書いたファイル) (抜かれる方のファイル)
510 :
名無しさん@お腹いっぱい。 :2006/12/02(土) 22:37:23
すみません。改めます。 シェルスクリプトでやりたいです。 ABC DEF GHI JKL MNO という文字列を DEF GHI JKL という部分をごっそり抜いて、 ABC と MNO の間に特定の文字列を挿入して、 ABC hogehoge1 hogehogeXX hogeYY MNO としたいのですが、 何か良い案はないでしょうか? よろしくお願いします。
>>510 ↓ほれ、これでいいかい? シェルだけでやったよ。外部コマンドは使ってない。
while read line
do
case $line in
ABC|MNO) echo "$line";;
DEF) echo hogehoge1;;
GHI) echo hogehogeXX;;
JKL) echo hogeYY;;
esac
done < input_file
>>510 cat aa |sed -e '/DEF/,/JKL/c\
hogehoge1\
hogehogeXX\
hogeYY'
>>512 お約束のcatが無駄です。あと、シェルだけでやりたいと申されております。
>>510 > DEF
> GHI
> JKL
> という部分をごっそり抜いて、
これで人に通じると思ってるの? ゆとり世代?
1 ABCの次の行からMNOの前の行まで。
2 2行目から4行目まで
3 2行目から最終行-1まで
4 DEFまたはGHIまたはJKL
5 1文字目がAかM以外
6 1文字目がDまたはGまたはJ
...
>>510 お客様、仕様書が曖昧で作業に入れませんのでご確認をお願いいたします。
こいういうことでしょうか?
START-STRING
AAAA
BBB
CC
END-STRING
を
START-STRING
REPLACED-1
REPLACED-2
REPLACED-3
END-STRING
とする。
START-STRINGとEND-STRINGに囲まれた複数行を置換するんでしょ?
読み取れないのは、AAAA,BBB,CCの部分は何でも良いのか、
hogehoge1,hogehogeXX,hogeYYの部分は固定なのか、AAAA,BBB,CCそれぞれに
対応させて置換するのか。
517 :
510 :2006/12/02(土) 23:06:52
1 ABCの次の行からMNOの前の行まで。 ですので、 512 でほぼ解決です。 ありがとうございました。 説明がわかりにくくてご迷惑をお掛けしました。 また出直します。
>>517 池沼?
>>512 は
DEFとJKLではさまれている行だろうが、どこが
> ABCの次の行からMNOの前の行まで。
なんだよ。
>>518 「ほぼ」って言ってるから良いんじゃない?
sed -e '/ABC/,/MNO/c¥
ABC¥
hogehoge1¥
hogehogeXX¥
hogeYY¥
MNO'
程度の修正は誤差であるというくらい理解したんじゃないかna
520 :
名無しさん@お腹いっぱい。 :2006/12/02(土) 23:32:03
for (i=0; i<10; i++) ; do echo "$i" done Bourne Shellでも動きますか?
むりでーす。
522 :
520 :2006/12/02(土) 23:32:52
間違えた for ((i=0; i<10; i++)) ; do echo "$i" done Bourne Shellでも動きますか?
>>522 はBourne shでは使えない。
for i in 1 2 3 4 5 6 7 8 9; do
echo "$i"
done
が最もポータブル。
seqやjotはあえて使わない。
問題の出し方と内容がム板と犬板のシェルスクリプトスレに現れた奴に似てる
526 :
名無しさん@お腹いっぱい。 :2006/12/05(火) 17:00:20
aaa='"AAA AAA" BBB' for n in $aaa; do echo "$n" done だと "AAA AAA" BBB となるのですが、これを "AAA AAA" BBB とするにはどうすればいいのでしょうか?
>>526 for n in "$aaa"
常に "$hoge" みたいに " " を付ける癖を付けろ。
>>527 欲嫁。それだと逆に全部つながっちゃうが、、
>>526 ゴリ押し
aaa='"AAA AAA" BBB'
while test "x$aaa" != x
do
case $aaa in
\"*\"\ *)
echo "$aaa" | sed 's,^\("[^"]*"\).*,\1,'
aaa=`echo "$aaa" | sed 's,^"[^"]*" *,,'` ;;
*\ *)
echo "$aaa" | sed 's, .*,,'
aaa=`echo "$aaa" | sed 's,[^ ]* *,,'` ;;
*)
echo "$aaa"; break ;;
esac
done
" " ではさんだやつは " " も消しちゃいかんという仕様がなぁ
531 :
526 :2006/12/06(水) 13:55:07
う、そんなにややこしいことなんですか? 精進します
変数に入っている最初の1文字だけを取り出したいんですけど、なにか良い方法は無いでしょうか?
>>532 foo=$(echo $bar | sed -e 's!\(^.\).*!\1!')
535 :
532 :2006/12/06(水) 20:52:29
>>533 ,
>>534 ありがとうございます。
自分なりに無い知恵を絞って出した答えは
foo=`perl -e "print substr('$var', 0, 1)"`
だったんですが、
>>534 には感動しました。
>>534 は Bourne Shell で動かないからポータブルじゃない。
↓がお勧め。
printf '%c\n' "$var"
これならかなりクラシックな環境でも可 foo=`expr "$bar" : '^\(.\)'`
うぉー、さらに増えてる。
みなさん、ありがとうございます。
printfが存在を知ったり、exprの使い方がわかったりと、かなり勉強になりました。
ただ、
>>539 の正規表現は'\(.\)'`でいいみたいです。
^は正規表現の意味を持っていないので無視される。みたいなワーニングがでました。
echo "$var" | cut -c1 は?
grep hoge * | nkf -e > out というコマンドを xargs を使った形に書き換えたいんですが、どう書けばいいんでしょうか?
find * -print | xargs grep hoge | nkf -e > out? ていうか grep とか grep -r で済むなら xargs の出番なさそう。
544 :
542 :2006/12/07(木) 01:04:05
あ、すいません。説明を間違えました。 ファイルの文字コードがそれぞれ違う可能性があるから、 for i in *; do grep hoge $i |nkf -e >> out; done と同じことをしたいのでした。 この場合も for の行で外部コマンドを呼んでいないから ARG_MAX の制限はないようですね。 xargs で起動するコマンドの中にパイプやリダイレクトを 入れることはできるか、と聞きたかったのでした。
一応 find * ... -print | xargs -n 1 sh -c 'grep hoge $0 | nkf -e' > out とかでもできるけど、 find * ... -print | xargs nkf -e | grep hoge > out の方がエレガントなような。でも、 file: line 形式で grep 結果を 出したいなら、ついでに * 展開で溢れるケースも考慮して find . ... -print | while read i; do grep hoge $i | nkf -e; done > out しかし ARG_MAX の心配をするほどファイルがあるなら find . ... -print | xargs perl -MJcode -lne 'print jcode("$ARGV: $_")->euc if /hoge/' > out がちょっと長いけど速そう。
とりあえずお約束として find -print0 xargs -0 にしる、と突っ込んでおくべきなのだろうか
お約束だけど GNU のは入れられなかったりとか 仕様バグがどうこうとか。
PPPoA で接続してるんですが、モデムのログがほとんど残してもらえず(容量少い) 不安定な回線なのにどの程度不安定なのか把握できず困ってます 切断されてもすぐ再接続されるわけですが、これを記録しておきたいと思います ping 撃ちまくるのはわかりますが、切断された時と再接続された時を記録するには どんなスクリプト書けばいいですか?
1.txt ↓内容 1 11 111 cat 1.txt | grep 11 とやると 11と111の2つがヒットしてしまいます(^_^;) 11の行だけを抜き出す方法はないですかね?
>>551 かっこいいから俺も会社で真似して渋く言ってみます
zcatとかgzcatとかbzcatとかに置き換えるときに、 修正する文字数が少なくなるという、多大なメリットがある。
フィルタだってことがわかりやすいしな。 別に咎めるほどのことではないと思う。
>>555 本気で言ってんのか?
>>549 のような使い捨てのワンライナーなら「修正の手間」も糞もねぇだろ。
元スクリプトが
script
なら、
zcat foo.gz | script
とすりゃいいだけだ。一行の修正も要らないし、zcat決めうちにするより
scriptの汎用性が維持される。
こっちのがツールボックスアプローチとして正しいわな。
必要も無いcatを使ってるスクリプトを見ると、俺は不安になるね。
書き手に変な癖がついてるのか、リダイレクションすら理解して無いのか、
品質上に問題があるんじゃないのかとか。
>>557 使い捨てならわざわざリダイレクトなり引き数なりに
直す必要もないじゃん。
script の汎用性の話は意味がわからん。
使い捨てなら cat のムダくらい気にせんでもいいやんけ。
>>558 , 559
使い捨てと言いつつ、
grep -w 11 1.txt
ですむものを、
cat 1.txt | grep -w 11
と書きたがる意図が分からんのだが。
そんなにcatとタイプして無駄にプロセスを一個増やすのが好きか?
変な癖を正当化してるだけじゃないか?
>>560 おれが書いたわけじゃないから
おれも意図はわからんな。
プロセスの減らし方あれこれ考えるより
さっさとスクリプト書きあげて
仕事終わらせちゃった方がいいじゃん。
>>561 こんなことで「あれこれ考え」なきゃいけない時点でバカ。
判って無い証拠。
cat file cmd
が動作するなら
cmd <file
が確実に動作するんだから。
後者は無駄なプロセスが不要でタイプ量も少ない。
大体、タイプ量増えるのに、「さっさと仕事終わらせる」も糞もないだろ。
563 :
562 :2006/12/13(水) 12:23:13
すまん cat file | cmd な。
cat 1.txt | grep -w 11 は中身確かめて加工に合っている。
漏れは同じファイルに対して何回かgrepしたいときに cat file | grep KEYWORD1 ↓ カーソルキーの↑を押して前回のコマンドを表示し、 Deleteキー連打して、新しいキーワードを打ち込んで ↓ cat file | grep KEYWORD2 ↓ 以下、繰り返し こんな感じだけどね。 シェルスクリプトの中では使わんけど。
>>565 単にコマンドラインの右端の文字を変更しやすいという意味なら、
$ < file grep KEYWORD1
$ < file grep KEYWORD2
↑みたいにやれば良い。< fileの部分が左に来てもいいんだよ。パイプは使わない。
567 :
565 :2006/12/13(水) 22:19:02
>>566 うぉ、そんな方法があるとは知らなかった。(@_@)
ありがとん。
^1^2 とかしないの?
cshつかわんから。
>>569 bashでもzshでも、もちろんcshでも、^1^2とかできるはずだけど。
kshは知らんが。
使える環境でも、^stop^start 位しか使わんな。 ヒットした最初の部分しか置き換わらんのが意外に使いにくいしくつう。
572 :
名無しさん@お腹いっぱい。 :2006/12/14(木) 02:16:19
ディレクトリーを1〜100まで一気に作りたいのですが 1 2 3....でなく 001 002 003...としたいのですが d=0 mkdir 0$d で$dに1つづ加算すると 1 2 3…となってしまいます orz ヒントなんぞありましたら おにぃちゃんおしえて! まぅまぅ
573 :
名無しさん@お腹いっぱい。 :2006/12/14(木) 02:20:03
>>572 まちがえたぁ
d=0
mkdir 00$d
で$dに1つづ加算すると
001 002…009 になるものの 10を超えると
0010になってしまうので
010…099 100 となれば幸いです
perl -e 'for ("001".."100") { mkdir $_; }'
zsh -c 'mkdir {001..100}'
>>572 mkdir `seq -w 1 100`
>>574-576 おにいちゃん!ありがと!まぅまぅ
perl,zshも勉強しますorz
winamp のストリームで
bpsやってるよ! まぅまぅ
バトルプログラマーシラセ・・・・・bpsね
579 :
名無しさん@お腹いっぱい。 :2006/12/14(木) 15:23:17
あるプロセスが起動しているかどうかps|grepで確認するにはどうしたらいいですか? ps ax|grep XXX|wc -l で確認すると、grep自身が入ったり入らなかったりします。
>>582 プロセス名が logreport だったりするとだめ。
>>583 やるな。
grep [X]XX
なら?
585 :
名無しさん@お腹いっぱい。 :2006/12/14(木) 17:54:13
ボーンシェルってシェル関数使えるって思っても いいのでしょうか? シゥル関数使えないボーンシェルもありますか?
まゆ毛ボーンシェル
「ボーン shell」って何ですか? Bourne shellなら知ってますが、 それとは違うシェルのことですよね?
マット・デイモンのやつだろ
589 :
名無しさん@お腹いっぱい。 :2006/12/14(木) 19:04:19
シゥル関数ktkr
シゥル関数、微妙に発音しにくい。
シゥルスクリプト
はだかーのまっまっでベイベ おどろーよシゥルダンス
>>592 どう見ても米米クラブです。
本当にありがとうございました。
スクリプトのログを過去10日間保存して、それよい古いのは削除していくという感じにしたいのですが LogFile名 Script名_$(date +"%Y%m%d-%H%M%S")_プロセスID 助言よろしくお願いします。
プールン?
ミキプルーン
日付で判断出来なかったっけ? どこかでそんなScriptを見た気がする。
ファイル名から、%Y%m%dの文字列を抜き出して、 `expr \`date "+%Y%m%d"\` - 10`と比較して、これより小さければ、そのファイルを削除する。 あとはこれを、for f in `ls Script名_*` みたいな感じでループさせればいいだろう。
今まで
>>582 の方法でやってたけど、
>>583 は盲点だった
多分そんなプロセス名自分は使わないだろうけど勉強になるな
>>594 findで作成日が10日以前のログファイルを見つけて消すようにしては?
>>602 この前その方法でやったけど何故か処理重かった・・・
なのでオレは
>>600 に近い方法でやったよ。
>600のそのままだとうまく動かないと思われ
>>603 どの部分が重いのか、今後の為にも確認した方が良いと思うぞ。
>>602 ほとんどの場合はそれでいいんだろうけどな、特に削除の場合は。
作成する時に date % 10 でファイル名決めれば? 今回は 10 だけど、7 の場合は date +%w でできてもっと単純。
兄者!たすけておくんなせぇ バックアップを1日3回取りたいのですが 日付毎のディレクトリを作って mkdir /bak/`date +%d%m` と、ここまではいいのですが2回目に、このスクリプトが動くと もうディレクトリあるぞ( ゚Д゚)ゴルァ!!とエラーがでます(たいしたことはないのですが) ディレクトリー作成とバックアップ用のスクリプトは別けたほうが良いでしょうか if で あるからもう作らない 次進めとやると 速度落ちますよね? なんかいい知恵ないでしょうか?
>if で あるからもう作らない 次進めとやると これでいいじゃんw
ごめんなさい ひらめきました
cronで夜中ディレクトリ作ればいいのですね
>>608 if で毎回やるのがなんかイヤな感じがしたので
識者の方々に伺おうと思ったww
今は反省している
それと%m%d だよな
逝って来ます
つ mkdir -p
>>610 それも考えたのですが。。。なんか毎回それを入れるのも・・・・・・
別に中身は消えないんでしょうけどww
なんか気持ち悪いorz
すんませんありがとでございます
>>607 「ディレクトリがなかったら作る」でいいんじゃないの?
こんな感じ↓でやれば、1行で済むじゃん。
[ ! -d ディレクトリ ] && mkdir ディレクトリ
たまには || の事も思い出してあげてください
test のオーバーヘッド(w が気になるのなら、 mkdir dir 2> /dev/null でおけ。
藻前らなかなかできるな!! 基本を身に付けたいorz
>>614 set -e
で不都合が生じるから減点。
たまには || の事も思い出してあげてください mkdir -p dir 2>/dev/null || :
-p || || では?
確かにコマンドを形で覚えて?いるのか 標準入出力を意識(理解?)していない人は多いね。 たとえば、tar cf - . | ( cd /xxx && tar xpvf - ) とかすると "-" について9割くらいは見ていた人に聞かれるし簡単には 何をやっているか理解してもらえない。 後は、3>&1 とか使えば多少は幅広がるのにね。
- が標準入出力を表すかどうかはコマンドによって違うんで またちょっと別の話かと。
でも解凍するときは zxvf 圧縮するときは zcvf みたいに覚えてて それぞれのオプションの意味を覚えていないやつってのはいるよね 結局伸びない
FreeBSDのtarなら圧縮形式自動判定してxvfだけで展開できるしな。
jはbzipだろ zはgzだろ xは解凍 cは圧縮 vは状況表示 fはファイル指定 じゃ無かったかな。 man tar してません。
きっと、おぼえていることにポイントがあるわけじゃなくてぇ
lhaのオプション覚えてる人いてる? 普段はファイラから解凍や圧縮してたんでじぇんじぇん覚えてにゃ
マニュアルを引ければいいんじゃね?
マニュアルを脳にインストールする話じゃないのか?
いや その知識自体の価値ではなく、その人の性質というかそういうものについてだよね
なんにせよスレ違いだ。
結局は基本を覚えて延髄の反射で書けるようにしておけってことでしょうか? あと正規表現モナーですか?
>>600 月が替わったりすると無理じゃね?w
20061125
20061201
20061231
20070101
よく月の1日にはリセットだなw
文末にw付けるとwwなんかwwwいいことでもあるのか?wwwwwwwwwww
grep の -w オプションみたいなもんだな
>>633 BSD系なら
T=$(($(date +"%s") - 86400*10))
DATE=$(date -r $T +"%Y%m%d")
Linux (というかGNU coreutils) なら
DATE=$(date -d '10 days ago' +"%Y%m%d")
date -v -10d +%Y%m%d
>>637 -vはFreeBSD限定のような気がする
>>594 rm `ls -t /directory/*.log | tail -n +11`
なんて方法もあるかなと。
>>639 それいけるのか?
1日に複数個ログはいても
641 :
名無しさん@お腹いっぱい。 :2006/12/21(木) 16:23:03
date は1日引くのができるんじゃないっけ? ago だかなんかの引数で
FedoraBSDって無いんですか?
kFreeBSDならあってもおかしくない気がするよな
645 :
名無しさん@お腹いっぱい。 :2006/12/23(土) 04:10:11
大量のファイルに対して、 foo * というようなことをやりたいのですが、arg list too longというような メッセージが出ます。 で、有名な echo * | xargs foo で解決と思いきや、xargsってARG_MAXを超えた引数については、fooを呼びなおすみたいですね。 fooは全てのファイルに対して1回だけ実行されないと困るんですが、何かいい方法はあるでしょうか?
foo を改造するしかない
>fooは全てのファイルに対して1回だけ実行 xargs でいいじゃん
全てのファイル <-> それぞれのファイル
>>645 1 fooをshell functionで書き直す。
2 arglist広げてシステム再構築。
3 fooを複数回実行されても困らないよう作り直す。
まずはオナヌーして落ち着く
昔 find ... | xargs tar cvf hoge.tar で ARG_MAX にあふれたファイルだけ入ったアーカイブ作ったことある。 たぶん受け側のプログラムを標準入力からファイル一覧読むように 改造するしかない。
>>647 欲嫁。
>xargsってARG_MAXを超えた引数については、fooを呼びなおす
xargs -n 100 とかでおk、とかそういう話ではない?
>>654 欲嫁。
>xargsってARG_MAXを超えた引数については、fooを呼びなおす
>>645 の書き方がいまいち曖昧なんだが
fooで同じファイルを二度処理するのはまずいってだけの話なら
xargsでいいんでないの?
一度のfooの実行で全ファイルを処理したいっつーんなら、
引数渡しでやるのは無理だわなそりゃ
657 :
645 :2006/12/23(土) 13:58:06
色々レスありがとうございます。
書き方が悪かったですが、fooは複数回実行されると困るというよりも、
全ファイルのデータを読み込んだ上でまあ数値計算みたいなものなんですが、
計算を行いたいわけです。
一度に処理されないと意味がない、ということです。
>>653 これ試してみましたけど、-n 100000とかやってもARG_MAXの壁は越えられないんで駄目でした。
どうもfoo内でファイル一覧を読むように書き換えるか、再構築ってことみたいですね。
ガベージイン ガベージアウト
引数の個数に1万か3万の制限があったような
xargsって言ってる奴あほ過ぎる
だから
>>651 だってのに。
受け側のプログラムが引数使わないように修正する以外に方法はないって。
xargsは obsolete。別の意味でも使ってはいけない。
また湧いた
find . -exec foo {} \;
良く読んでない奴多いね。
foo file1 file2 .... (すべてのファイル)
みたいに、1回だけで実行したいという質問なので、
>>665 は 0点。
んなことはみんなわかってる
* じゃないしな。
foo のbinary ラッパーを書いて、main を直接呼び出す。 普通はプログラムを書き直すよな...
汎化してGPLで公開すればよくね?
ARG_MAXってシェルの制限ではなくてint argc, char **argvのホントの 上限なんだね。標準入力からN行読み込んでexecvpで直接渡すようなの 書いてみたら32768でアウト。 任意のコマンドのmainをフックして、単なる関数として渡すような形で 汎化しないと駄目だな。もっとも問題のプログラムが処理対象のリストを 標準入力から読んだほうがよほどいいと思うけど。
(ものすごくつまらない)ネタだと思ってたらマジで汎化してGPLとかほざいてたのか
いや検討まで含めてネタだろ バカか?
gdb でmain で止めて、 レジスタ渡し、あるいはスタック渡しの部分で、malloc()で上書き。 .gdbinit で、がんがん代入。 実行開始。 ってのは、どう?
こんなこと書いてるうちに元コード直し終わると思うけど、 -Dmain=xmain して、別途 dlsym(h, "xmain"); で呼び出すとか。 mainをそのまま直接呼ぶ方法あるのかな?ptraceとか使える?
変わったシェルを使ってるんですね
#!/bin/sh ( cat <<EOFEOF extern int printf(const char *,...); main(int ac,char *argv[]) { int i; for(i=0;i<ac;i++) printf("%d %s¥n",i,argv[i]); } EOFEOF ) | gcc -x c - ( echo "b *main" echo "run" echo 'set $r3=3' echo 'set *((char **)$r4) = "test1"' echo 'set *((char **)$r4+1) = "test2"' echo 'set *((char **)$r4+2) = "test3"' echo 'set *((char **)$r4+3) = "test4"' echo " c" ) | gdb ./a.out (Mac OS X 限定...) ってな感じで、symbol table がある場合は可能らしい。strip されている場合は、 entry point を根性で探してくれ。
おっと、 set $r4=(void *)malloc(1000) とかで malloc() するのを忘れずに。
独自rtld書いてmain呼び出す。
stripされててもmainのオフセット位置はどのプログラムでも同じ(同じ 環境なら)だから、そちらで調べた値をreadelfで得たエントリポイント アドレスに足せばgdbのブレークポイント設定位置が判るよ。 後は$espから引数にアクセスして書きかえればいい。 この一連の操作はシェルスクリプトにできるから、xargsで扱えない 例外状況の処理用ツールになる(かもしれない)。
ファイルをそのパスを含んだファイル名にしてコピーしたいです。 例えば ./foo/bar/mbox を ./foo_bar_mbox にコピーしたい。 find . -type f -name mbox -exec cp {} `echo {}|tr '\/' '_'` \; とかしても cp: ./foo/bar/mbox and ./foo/bar/mbox are identical (not copied).とエラーになっちゃう。 スレ違いだったら誘導して
>>683 シェルが先に ` ` を評価するから
実際に実行されるのは
find . -type f -name mbox -exec cp {} {} \;
になるな。
for f in `find . -type f -name mbox`;do cp $f `echo $f | tr '\/' '_'`;done
無理に one-liner にしなくてもいいんじゃね?
find . -type f -name mbox | sed 'p;s,/,_,' |xargs -n2 cp
ねーねー このスレのまとめって無いのかなぁ ここしばらくの話、めっちゃ勉強になるんですけど
わざわざ別解書いた
>>687 が不憫。
それ以前の問題で外してしまった
>>686 はもっと不憫。
/usr/fbin
>>690 >>687 はエラー出ちゃうんだよ。
どうも最初の/しか置換されなくて._foo/bar/mboxにコピーしようするの。
で原因なんだろうと調べてみてるんだけどわけわからん。
>>692 多分 sed の部分が間違っているんじゃないかな
検証してないけど
sedのところで、g が抜けてる。
#!bash2.04 echo "$(echo " $(echo "`echo "$(ps)"`")")" ちょい大げさに書きすぎたけど、こんな感じのを見かけた これはどんな決まりでトークンに切り分けてるのさ!!
697 :
名無しさん@お腹いっぱい。 :2007/01/01(月) 00:02:28
新年キタコレ 今年もよろ69
よろむく?
699 :
名無しさん@お腹いっぱい。 :2007/01/01(月) 02:23:40
>>698 Yellow Mookだろ。
それくらい察してやってくれ。
701 :
名無しさん@お腹いっぱい。 :2007/01/03(水) 19:21:38
4649?
よろシックスナイン
?
find で得られたファイルを更新時間順で並べる方法があれば教えていただきたい。
ls -t `find hoge....`
706 :
名無しさん@お腹いっぱい。 :2007/01/11(木) 20:32:03
それでいいのか… 失礼しました
argument too long
708 :
名無しさん@お腹いっぱい。 :2007/01/12(金) 00:58:20
sedでhoge.datというファイルを編集するときに sed 's/aaa/bbb/' hoge.dat > tmp.dat mv tmp.dat hoge.dat のようにして、一時的なファイルとしてtmp.datというファイルを用意するのが無駄だと 思うのですが、このような一時的なファイルを使わないで 直接、hoge.datをsedで編集する方法はありませんでしょうか? m(_ _)m
>>708 ・-i オプションをつかう
・-i オプションがないsedをつかっているなら in-place editing 対応の sed の導入を検討する
・ed をつかう
・perl を使う
・一時ファイルを必要としないファイル命名法を検討する
お好みで
GNU sedには-iオプションがある。BSDのもある。 あとinplaceというあらゆるフィルタをin-place editに使うコマンド もある。(これはぐぐって)
FreeBSD の標準 sed に -i オプションが取り入れられたのは 4.7R でそれ以前には無い。 NetBSD の標準 sed には -i オプションは無い。 OpenBSDの(ry 以前のGNU sed には in-place editing 機能はない (Changelog によると 2001-09-25 )
MacOSXのBSD由来のsedにはあるみたいだな。いつのだろ。
>>712 MacOSXのFreeBSDなユーザーランドは 最初は FreeBSD 3.xR由来で
そのうちに 5.x由来とかのになってそれから先はシラネ。
でも5.x以降だろうなと推測。
>>714 /usr/share/misc/bsd-family-tree あたりにちゃっかり書いてあったりする。
そのディレクトリの中はじめて見た。 flowers(花言葉)とかbirthtoken(誕生石)とか、妙なファイルもあるんだな。
>>715 なるほど
でもそのファイルにNeXTの話がないのが微妙
>>708 UNIXのファイルシステム上だと
(rm hoge.dat; sed 's/aaa/bbb/' > hoge.dat) < hoge.dat
でOK
ああ、なるほど。
あ、アナルほど
手順をトレースしてみました。こんな理解でよろしいでしょうか。 1. < hoge.dat ファイルディスクリプタを確保する。(&標準入力にする) このディスクリプタが開いている限り、ファイル名がなくなっても ファイルの実体は消えない。 2. (...) サブシェルを起動する。ファイルディスクリプタは継承される。 3. rm hoge.dat hoge.datというディレクトリエントリ(ファイル名)を消す。 しかし、それが指していた実体は1.のディスクリプタからまだ参照 されているため、消えない。 4. >hoge.dat 別途hoge.dat という名前でファイルを開く。(&標準出力にする) これは、もとのhoge.datが指していた実体とは別のディスク領域に書かれる。 5. 全体が終了すると、ファイルディスクリプタが閉じ、もとのファイル実体 が使っていたディスク領域が未使用状態とみなされる。
>>719 (...)じゃなくて{...;}じゃダメ?
最近のシェルは`test`や`[`が組み込みコマンドになってるとのことで 確かにpowerpc-apple-darwin8.0のbash 2.05b.0(1)-releaseでは`builtin`で呼び出せることも確認しました 一方で/bin/[や/bin/testも存在し、当然実行可能でした また、若干の差異はありますが、複合コマンド(compound command)の`[[ expression ]]`もほぼ同じ用途に利用できます そこで質問なんですが、少し上で話されていたような処理の重さ(無駄なプロセスの生成等)を考えた場合、 どれを使うのがベストなんでしょう?
当然内部コマンドでしょう。 つーか、パフォーマンス重視な場合は シェルスクリプトなんか使うな。
cat access.log | grep $URL | wc -l >> $FILE という感じで、アクセスログから、特定のURLを探して数を数えて、その数をファイルに書き込んでいるのですが、これを毎日やると、 10 20 10 15 といった感じで、改行されてしまいます。 これを 10,20,10,15 という風に、,区切りにするにはどうすればよいでしょうか?
>>728 tr -d '\n' < filea | sed -e 's/[ ]\{1,\}/,/g'
的な
tr '¥n' ','
おや、こんな時間にかぶるとは。
732 :
名無しさん@お腹いっぱい。 :2007/01/15(月) 06:03:29
sedについて質問です。 hoge.datというファイルがあるとして、 その中身が以下のようであったとします。 aaa これを、 aaa bbb ccc のように変更したいのです。 で、sedでこれを実現しようとする場合、 #!/bin/sh sed 's/aaa/aaa \ bbb \ ccc/' hoge.dat exit 0 こんな感じになると思います。 シングルコーテーションのとこがダブルコーテーションの場合は、 #!/bin/sh sed "s/aaa/aaa \\ bbb \\ ccc/2 hoge.dat exit 0 のように、\マークがふたつになると思います。 どうして、シングルコーテーションの場合は、\マークがひとつで、 ダブルコーテーションの場合は、\マークがふたついるのでしょうか? よろしく呉教授お願いします。
呉教授はいいねえ 呉智英?なんてね
734 :
sage :2007/01/15(月) 09:21:26
ダブルクオートの場合は、一つめの\がシェルに持ってかれてる。 シングルクオートの場合はシェルに持ってかれないので\一つでOK。 こんな感じでシェルを介さなければ\一つでいける。 > cat replace.sed s/aaa/aaa \ bbb \ ccc/ > sed -f replace.sed hoge.dat aaa bbb ccc > SH(1) > Double Quotes > Enclosing characters within double quotes preserves the literal > meaning of all characters except dollarsign (`$'), backquote > (``'), and backslash (`\'). The backslash inside double quotes > is historically weird. It remains literal unless it precedes the > following characters, which it serves to quote: > $ ` " \ \n
質問させてください。 以下のHTMLファイルがあるとします。 ------------------------ <html> <body> <!-- memo --> hoge </body> <html> ------------------------ これを、以下のように<!--から-->の部分を削除したいのです。 ------------------------ <html> <body> hoge </body> <html> ------------------------ このようなことをしたい場合、シェルスクリプトではどのようにすればよいでしょうか? ちなみに、うちの会社の吉田さん曰く「そんなのawk使えば一発だよ!」といってました。。
吉田、センスねーな。 awkでもできるがsedを使うのが普通の感覚じゃね? もちろん、後出しで仕様が複雑にならなければの話だけどな。 ちなみにsed的には/^<--/,/^-->/dとかだけど。
>>738 仕様はHTMLの文法通りと考えるべきだろ。後出しでも何でもない。
よって
>>738 はその意味でも間違い。
HTML の文法にしたがうとしたら シェルスクリプトでやろうというのが間違いだな。
HTMLなりSGMLをパースできる言語を使えよ
>>737 bashでやってみました
#!/bin/bash
OLDHTML=$1
NEWHTML=$2
COMMENT=0
while read LINE
do
while echo $LINE | grep -q '<!--.*-->'
do
PARTLINE=${LINE%%<!--*}
LINE=$PARTLINE${LINE#*-->}
[ ! $LINE ] && continue 2
COMMENT=0
done
if echo $LINE | grep -q '<!--'; then
LINE=${LINE%<!--*}
[ $LINE ] && echo $LINE >> $NEWHTML
COMMENT=1
elif echo $LINE | grep -q '¥-->'; then
LINE=${LINE#*-->}
[ $LINE ] && echo $LINE >> $NEWHTML
COMMENT=0
elif [ $COMMENT -eq 0 ]; then
echo $LINE >> $NEWHTML
fi
done < $OLDHTML
愚直な実装では、CDATAの中のコメントも取り除かれてしまうだろう。 真面目にやるなら、htmlパーサ使っとけってこった。
sedよりawk向きではある。
俺は743だが たぶんみんな別人だと思うぞ
750 :
吉田 :2007/01/18(木) 23:57:28
おまえら、レベルひくいなーw
とくに
>>744 は茶ふいたわ。
>>737 のいっているHTMLファイルを仮に、index.htmlというファイルとすると、
cat index.html | awk '/^<!--/,/^-->/ {next} {print}'
こうやればOK。
ばーか!
なんでわざわざcatすんだw
「cat不要」はこのスレの基本だからな。
753 :
吉田様 :2007/01/19(金) 00:06:30
754 :
吉宗 :2007/01/19(金) 00:09:27
738 グダグダだな
755 :
738 :2007/01/19(金) 00:12:12
俺は
>>738 以降は知らんぞ。正直筆が滑ったと反省して静かにしてたがな。
756 :
徳田 :2007/01/19(金) 00:14:20
すまない。754は見なかったことにしてくれ。
HTMLのコメント処理が簡単と言ってる(思ってる)ヤツは
とりあえずばけらさんとこでも読んどけ
で
>>737 は本気で回答がほしければ
全ての形式のHTMLコメントを除去したいのか
>>737 の形式のコメントを除去したいのか補足しろ
ってことでしょ
前者ならシェルスクリプト向きじゃないけど
>>750 偽物の吉田さん、本当にありがとうございますw
>>744 さんも勉強になりました。ありがとうございます。
759 :
吉田様 :2007/01/19(金) 00:24:15
>>757 茶ふいたわww
前者だろうが、後者だろうがawkでやるのが一番だろが。
ばーか、ばーかー
xmlawk
xmltwig.comが見えないのだけど
デスクトップ環境を起動するときに、/usr/X11R6/bin/startxか.xinitrcあたりに 起動する前に好きなウィンドウマネージャを選べるようにコードを追加したいのですが、 どのようにすればいいのでしょうか?
gdmはやめとけ
kdm
xdm
>>763 xmessage のような物でも使って問い合わせるとかかな
>>763 俺は$WMで分岐してる
case ${WM:-wmaker} in
wmaker) ... ;;
gnome) ... ;;
kde) ... ;;
*) ... ;;
esac
それがどうした
775 :
名無しさん@お腹いっぱい。 :2007/01/26(金) 13:49:37
やはりstartxのスクリプトに追加した方がいいんですかね・・・
gdm でいいじゃん。
gdm は死んでもやめとけ
毎日同じ時間に何やってんだ。宣伝か?
780 :
名無しさん@お腹いっぱい。 :2007/01/26(金) 17:33:13
漢ならtwm一本で行けよ!fvwm2でもいいけどw
つuwm
782 :
名無しさん@お腹いっぱい。 :2007/01/28(日) 05:14:10
「変数$listに格納された5個の小数点のついた数字」 の中で、「20以上である」という条件を満たしたものが いくつあるのかを数えたいです。 例えば、変数$listの中身が 10.4 30.2 15.4 5.2 20.2 だった場合には、答えは2と出るようにしたいのです。 n=1 sum=0 while [ $n -le 5 ] do s=`echo "$list" | sed -n "$n p"` y=`trunc("$s")` if test "$y" -ge 20 then sum=`echo "scale=0; $sum + 1" | bc` else exit 1 fi n=`expr $n + 1` done echo $sum
783 :
782 :2007/01/28(日) 05:15:34
上記のbash scriptでいいのかな、と思ったのですが、 エラーになります。 変数$sに数値がひとつひとつ代入されて行くのは確認できたのですが、 小数点を切り捨てるためのtruncコマンドのところでエラーになります。 command substitution: line 1: syntax error near unexpected token `"$s"' command substitution: line 1: `trunc("$s")' どこがおかしいのか教えていただけませんか?
最近のbashはtruncなんてあるのか。
関数にしろコマンドにしろ、呼び出しは trunc "$s" の形になるはずだろ。 というか、小数扱うなら awk 使っとけ
>>782 nn=0; for aa in $list; do if [ ${aa%.*} -ge 20 ]; then nn=$((nn + 1)); fi; done; echo $nn;
bash依存しまくりスクリプトは犬板逝け
788 :
782 :2007/01/28(日) 09:15:01
>>784 >>785 man truncしたらこんなのが出てきましたが。
つまり、truncはたぶんtrunc(数字)とかいう形で使うのかな、
と思ったのです。実際trunc "数字"ではうまくいきませんでした。
しかし、trunc()の形にしたところで
$ trunc(23.4)
-bash: syntax error near unexpected token `23.4'
こんな感じでエラーになり、たぶん正しい文法になっていないのが
ネックになっているような雰囲気です。
NAME
trunc -- truncate to integer value
SYNOPSIS
#include <math.h>
double
trunc(double x);
long double
truncl(long double x);
float
truncf(float x);
DESCRIPTION
The trunc() functions return the integral value nearest to but no larger
in magnitude than x.
SPECIAL VALUES
trunc(+-0) returns +-0.
trunc(+-infinity) returns +-infinity.
SEE ALSO
ceil(3), rint(3), math(3)
STANDARDS
The trunc() functions conform to ISO/IEC 9899:1999(E).
BSD January 29, 2003 BSD
789 :
782 :2007/01/28(日) 09:19:35
>>786 ありがとうございます。
これはなんの言語でしょうか。これがawk?
実際にこれでやってみましたがうまくいきません。
そもそも
${aa%.*}
この意味がわかりません。
けど、これを使うとtruncを使わずに済むので
便利そうですね。
いろいろと勉強してみます。
>>787 今はたまたまbashの勉強をしているので、
別にbashに依存しているわけではありません。
excelとか使った方が速いのはわかってますが、
無理やりbashでやろうとすることで
「 ( ・∀・)つ〃∩ ヘェーヘェーヘェー truncなんて関数があるんだ!」
という発見があるので、おもしろいのですよw
man bashを一通り読めと。
>>788 それ、マニュアルページの一番上に trunc(3) て書いてるんじゃない?
マニュアルのセクション3は、Cのライブラリ関数。
792 :
782 :2007/01/28(日) 17:54:08
>>791 !!!!
全くその通りです!
bashでは使えないのですね・・・orz
bashの中でCのライブラリ関数を使う方法か、
他に小数点切り捨てによい方法はありませんか?
切り捨てる必要があるのかと
794 :
名無しさん@お腹いっぱい。 :2007/01/28(日) 22:17:42
>>789 本当にbash使ってるなら、
>>786 で合ってるよ。awkは関係ない。
これ自体がbashのスクリプト。
bashじゃない普通の shでも動くように
>>786 を書き直してみた。
↓ (ちなみに俺は
>>786 とは別人)
nn=0
for aa in $list
do
if [ `expr $aa : '\(.*\)\..*'` -ge 20 ]; then
nn=`expr $nn + 1`
fi
done
echo $nn
単なるshで書ける奴って強いよな。
若干スレ違い気味な気もしますが
ttp://x68000.q-e-d.net/~68user/unix/pickup?iconv > 入力ファイルに無効な文字 (-f で指定した文字コードと矛盾するようなデータ) が
> 含まれていた場合、iconv はエラーとして終了する。FreeBSD の iconv では
> -c オプションを指定することで、無効な文字を無視して無視して続行することができる。
> 他の iconv では必ずエラーで終了してしまうようだ。
Linux で、変な文字を無視しつつ文字コードの変換をしたいときにはどうするのがベストでしょうか。
(個人的に馴染のある言語の) php で iconv//IGNORE をする、という手は思いついたのですが。
スレ違いじゃなく板違い Linuxでどうするのかを聞くなら Linux板がいいでしょう。
799 :
782 :2007/01/29(月) 21:06:29
800 :
782 :2007/01/29(月) 21:09:19
>>799 ちなみにshtmlの方は、12個の都市について
その場で気象庁からデータをとりにいって解析するので
クリックしてから表示されるまで1分弱ほど時間がかかりますので
辛抱強くお待ちくださいね。
>>800 なかなかおもしろいね。
色々応用が利きそう。
>>782 まだやってたんだね。
Mac板でのやりとりがなつかしいぜ…
803 :
782 :2007/01/31(水) 16:57:24
そのリンクを踏んだら気象庁にと〜つげきよ〜
>>802 俺も気がついた
ので教えてやった。
皮先のスクリプトはよく利用させてもらってて重宝してるし。
リモートホスト上の任意のディレクトリが存在するかチェックしたいのですが remsh $リモホ名 -n "find $ディレクトリ名 -type d -name $ディレクトリ名 -print" で値が取得できるかどうかでディレクトリがあるかチェックしようと思っているのですが もうちょっとスマートなやりかたがありますでしょうか?・・
findじゃなくtest -d $directoryでいいんじゃない?
太郎 84 花子 83 裕子 98 尚美 91 という生徒のテストの点数を記載したデータがあったとき、 これを点数の高い順番でソートしたいのですが、 いろいろ調べるとawkがこういうのを得意にしているような気がしました。 この処理を簡単に行うにはawkが最も適していますか? 他に適している言語はありますか? といいますのも、awkについて調べてみたのですが、 点数を加算する、とかはわかったのですが 点数の高い順番でソート、は無理なような気がしましたので・・・。 awkが最も適している、ということであればもうちょっとがんばってみたいと思いますが。
>>809 ソートはsortでいいじゃん。
キーとするフィールド位置の指定だとか、アルファベット順じゃなく数の大小でのソートだとか、
そういうオプションもあるので、後はsortのmanみてみるとよいです。
区切りが809の通りならsort +1 -nr でいいんじゃないかな。
812 :
809 :2007/02/03(土) 18:17:50
>>810 >>811 sort!!!!!
そ、そんな普段から自分でもよく使ってるやつで可能だったんですね!
さっそく
>>811 さんのようにやってみたらうまくいきました!
ありがとうございました。
whileやfor構文で繰り返されて出力される結果を >>out.txt を使ってどんどんファイルに書き加えていくのはわかりました。 では、ファイルに出力するのではなく、 (変数として?)メモリ上に出力していく方法はありますか? 例えば、 1回目の繰り返し文によって、変数$ssの値が5になりました。 変数$yyの中身は 5 となりました。 2回目の繰り返し文によって、変数$ssの値が2になったので、 変数$yyの中身は 5 2 となりました。 3回目の繰り返し文によって、変数$ssの値が7になったので 変数$yyの中身は 5 2 7 となりました。 こんな$ssに対して$yyのように出力が可能な方法はありますか?
while ...; do # ... yy="$yy $sss" # ... done echo "$yy" 単純にこうやるとyyの中身の1行目に空の行が出来ちゃうから、 yyが空かどうかチェックしたほうがいいか。
set - while ...; do set "$@" "$yy" done for a in "$@";do echo "$a" done
set -- while ...; do set "$@" "$yy" done for a in "$@";do echo "$a" done
>>814 なるほど。言われてみると簡単ですね・・・。
実際に自分でやってみたら、確かにできました。
最初の空白行は
yyが殻かどうかチェックするより
最後にsedとかで削除した方が簡単なのでそうしようと思います。
sed '/^$/d'
これをパイプしようと思います。
ありがとうございました。
>>815 よく意味がわからないのですが、
とりあえず814さんの方法でできましたので
お気持ちだけいただいておきます。
ありがとうございました。
815の方法は、setで $1, $2, ... に追加していって最後に それら全体である$@をループで回すことで取り出してる。
>>818 なるほど、意味がわかりました!
ありがとうございます。
$echo test.txt 太郎 84 25 花子 83 21 裕子 98 24 尚美 91 23 冬美 84 21 このように名前 点数 出席日数があったとき、 第一ソートは点数で、第二ソートは出席日数でソートし、 裕子 98 24 尚美 91 23 太郎 84 25 冬美 84 21 花子 83 21 こういうふうに出力したいのですが、 $echo test.txt | sort +2 -nr | sort +1 -nr こうして二段階のsortでいいのかな?と思ったけど、 むしろ必ず 冬美 84 21 太郎 84 25 と、逆になってしまいます。そこで、 $echo test.txt | sort +2 -n | sort +1 -nr -rオプションを外してやってみても同じ結果でした・・・orz なにか別のコツなどがあるのでしょうか?
終了
822 :
820 :2007/02/03(土) 20:08:12
echoじゃなくcatじゃないの? というか、cat使うと「catイラナイ」と言われるけどさ。
ここでは、「ぬるぽ」「ガッ」と同じくらい定番だもんなw
ネコイラズとな
826 :
820 :2007/02/03(土) 20:19:07
>>823 あ・・・、マジでごめソ・・・orz
cat text.txt
が正解。
というか初心者がパイプを覚えるには最も分かりやすい例だと思うけどね。
cat hoge.txt | sort
初心者にそういう使い方教えると、
>>820 のようなダメ人間ができあがる。
んまー、sortコマンドって難しいべ。
>>827 べつにそういう使いかた教えたせいじゃないだろう
830 :
820 :2007/02/03(土) 21:14:27
awkを使って 変数$hogeaと変数$hogebを連結しようと思います。 $hogeaの中身は 1 3 5 4 8 7 3 $hogebの中身は 1023 1032 1001 1002 1003 1009 1018 これをこんなふうにしたいのですが、 1 1023 3 1032 5 1001 4 1002 8 1003 7 1009 3 1018 ちょっと勉強して感じではよくわかりませんでした。 もうちょっと勉強してみます。
paste
833 :
831 :2007/02/04(日) 04:33:44
>>832 できました!!!
変数が20個くらいあったのですが、
echo "$hogehoge1" | paste file1.txt - >file2.txt
echo "$hogehoge2" | paste file2.txt - >file3.txt
・・・・・
echo "$hogehoge20" | paste file20.txt - >out.txt
とやることでなんとかなりました。
これが47x12x47=26,508回繰り返さないと行けない処理で、
ハードディスクは痛めつけるますがこれ一回だけやればいいので
これでがまんすることにします。
もっとメモリ内のみで済む方法ってないんでしょうね・・・。
echoを使うのはネタなのか、そうなのか!?
スマソ、ほんとにそういう中身なのね。
シェルスクリプト以外の方法でやればいいのに。
837 :
831 :2007/02/04(日) 19:45:16
>>836 例えばどういう方法がありますか?
わたしがやりたいのは、
気象庁のWebサイトから各都道府県庁所在地の
1961年以降の毎日のデータを2007年1月まで
一気に取得し、
例えば2007年1月の熊本(47814)のデータを
あとでとりだしやすいように加工した後に
「20070147814」
というファイル名で保存していく、ということです。
今朝から一括ダウンロードを始めましたがまだまだ終わりそうにありません。
24時間くらいかかりそうです・・・orz
こういう一回だけやれば済む使い捨てスクリプトをかくのに
シェルスクリプト以外になにかいい方法がありますか?
838 :
831 :2007/02/04(日) 19:59:03
>>837 PerlやRubyは考慮しないのかな、ということではないかと。
シェルスクリプトにはパズル的なおもしろさはあるけど、
若干の無理矢理感はあるし、外部コマンド使いまくりでモタモタするし。
840 :
831 :2007/02/04(日) 20:36:39
>>839 なるほど。
モタモタして時間がかかるのは確かだしね。
つか、俺的にはPerlもRubyもシェルスクリプトの1コマンド、という認識。
Rubyはよく知らんけど
Perlはシェルスクリプトと比べて意味がわかりづらいので
なかなか重い腰が上がらないんだよね。
あと、こういうデータを元にして動的なWebコンテンツをつくるには
やっぱphpでつか?
>>840 なんでもええよ。
シェルスクリプトでもいいし。
ある程度アクセス数が多くなるなら、シェルスクリプトではきついけどね。
>>840 そんなあなたにはRubyお薦め。
Perl挫折した俺が言うんだからまちがいない。
俺の知合いにはコマンドラインのちょっとしたスクリプトにもphpを使う奴がいるし、 その一方でウェブサービスをC++で書いたCGIで実現している奴もいる。 言語自体の得意分野や不得意分野があるのはその通りかも知れんが、 慣れた言語で適当にやるのも重要であるのだと思うぜ。所詮スクリプト。 そんな俺はPHPをおすすめしておこうかな
bash最強、次点tcsh
>>840 動的なWebコンテンツというなら、テキスト処理に長けていることが条件かな。
PHPでもPerlでもRubyでも、あるいは他のものでもいいと思う。
慣れているものを選べばいいのでは。
どれも初めてトライというなら、適当に情報を拾って見比べてみて、
自分に合いそうだと思ったものにすればいんじゃね?
シェルスクリプトは、テキスト処理能力に関しては
長けた言語と比べるとかなり見劣りする。
ちょっと凝ったものになると素のシェルスクリプトではとても苦しい。
>>837 ぐらいの処理なら、シェルスクリプト(+awkやsed)でもどうにかなるだろうけど。
cat hoge.txt | sort って何でcat要らんの??
cat -sとか cat -nとかするなら意味があるけど、ふつうは sort < hoge.txt で済むから。
848 :
831 :2007/02/05(月) 16:59:15
>>841 そうですか。ありがとう。
>>843 phpも挑戦したことはあるけど
なんかやっぱPerlほどではないけど小難しい感じがしました・・。
>>842 Rubyですか。
使ったことないけど今確認したら
ちゃんとMacOSXにもプリインストールされてるみたいなので、
Perlに挫折した俺としてもRubyに挑戦してみようかな。
日本人が作ったみたいだしね。
>>847 sort hoge.txt
の方が1文字少ない
>>850 sort hoge.txt だと、もしhoge.txtが存在しないか、またはpermission deniedの場合
にも、一旦sortコマンドが起動された後でエラーになるため、ちょっと無駄になる。
sort < hoge.txtだと、hoge.txtが読めない場合はシェルのレベルでエラーになり、
sortコマンド自体起動されないので無駄がない。
というより、質問がsortだったから引数に書けたってだけの話だな。 trみたいなファイルを引数に取らないのもあるわけで。 cat hoge.txt | tr a-z A-Z → tr a-z A-Z < hoge.txt
なるほどね
cat hoge.txt | tr a-z A-Z 確かに、こっちの方がcat以外でも同じ書き方になるから、ぱっと見わかりやすいか。
そんなあなたに < hoge.txt tr a-z A-Z
tr < hoge.txt a-z A-Z なんてのも可だったり。
858 :
831 :2007/02/07(水) 03:53:44
普通にcat hoge.txt | tr a-z A-Zに一票。 理由 ・初心者がパイプの意味を理解するのに適している ・ < を使う方法と大差ない ・後ろから < で入力とか気持ち悪い
>>858 理由の一つ目は、リダイレクトなら
「初心者がリダイレクトの意味を理解するのに適している」
と言い換えられるな。
理由の二つ目は、全然「catの方がいい」理由にはなってないな。
あんたにとって「大差ない」かもしれないが、少なくとも
タイプ量が多いし、無駄なプロセスも増える。
理由の三つ目は、もはや意味不明だな。何だそりゃ。
シェルのシンタクスが非常に美的であるとは俺も言わないが、
リダイレクトはシェルの基本だろ。
初心者にそういう使い方教えると、
>>858 のようなダメ人間ができあがる。
まあ、両方わかるようにしておけばいいじゃない
>>850 sort<hoge.txt
で文字数いっしょだ。
自演じゃないし
>>859 は間違いなくダメ人間だ。
まあ、両方できるようにしておけばいいじゃない
次の方どうぞ〜
パイプで処理結果をつなげていくっていうのがわかりやすいってことだろ cat hoge して中身を見て,その結果を | で別のコマンドに流し込んで... という部分を省略できるようになると冗長と感じるわけで オレはコマンドライン編集を使いながら書いていく方が多いから いまだに cat hoge | から始まるよ % cat hoge ...出力... % cat hoge | awk -F: '{print $1, $8}' ...出力... % ... そりゃ後から見ながら最適化すれば < hoge とか コマンドの引数に hoge 指定とかになるんだが
>>868 初心者ですが、catの左側にある % というのは何のコマンドですか?
うちでは % を付けるとエラーになるのですが・・
中身見るのにcat使う習慣はないなぁ。 英語のテキストならless、日本語ならlv、構文のあるテキストファイルならvim、バイナリならbvi。 よってcatは本当に結合したい時にしか使わんが、人それぞれか。
一般ユーザのシェルのプロンプト。$とおなじ。 Bourneシェルのデフォルトが$、Cシェル系は%なので両方が見られる。
マジレスはご遠慮ください。
マジレス上等 ゴマエー
>>859 がダメ人間(かどうかは知らん)という命題と、
>>858 がダメ人間(これは確実)
という命題はは排他ではない。
ははは 可愛い奴だなぁ
876 :
831 :2007/02/07(水) 15:31:42
>>868 そうそう、まさにそのとおり。
俺もそんなやり方でやっている。
viとかpicoとかでは
>>868 のような処理はできんだろ。
意味分かる?w
$ < hoge cat ...出力... $ < hoge cat ← ここで Ctrl-Wを押す $ < hoge ← catが消える $ < hoge awk -F: '{print $1, $8}' ...出力... ↑こうすれば無問題。無駄なcatやパイプは要らない。
無駄っつってもそんなにむちゃくちゃリソース食うわけでもないしな。 なんでそんなにこだわるのかわからん。
コマンドを作り上げていく過程での話なら、好きにすればいいじゃん。
cat hogeから始める必要は全然無い。 $ cat hoge しまった長い... ^C $ head hoge 考える... $ tail hoge 考える... $ sed -e '..' hoge |head 更に考える... $ sed -e '..' -e '..' hoge |head 更に考える... $ sed -e '..' -e '..' -e '..' hoge |head やっぱ、catを使いたがるのは、ダメ人間だな。
どうしよう、
>>859 のダメ度がどんどん進行しちゃう
<span></span>の中のhtmlタグを消したいのですが、いい手はないでしょうか? sed -n か awk を使えばできると思うのですが難しいです。 <span> 数行 </span> 数行 <span> 数行 </span>
885 :
831 :2007/02/07(水) 18:50:30
あたえられる文書が整形式のXMLの形になっているなら、 xmlstarlet とかのツールを補助に使えばいいと思うよ。 XSLT でも Xpath でも好きにコマンドラインから使える。
>>883 <span> と </span> のが完全に1行ずつなら簡単だね
889 :
831 :2007/02/08(木) 09:49:41
>>883 おれなら
cat -nとかでhtml書類を出力し
それをパイプしてgrepなどで一番最初に遭遇する
<span>と</span>をみつけ、
cut -d¥: -f1を使ってその行頭の数値(=行番号)をよみとり、
その結果をまた
それをパイプしてgrepなどで一番最初に遭遇する
<span>と</span>をみつけ、
cut -d¥: -f1を使ってその行頭の数値(=行番号)をよみとり、
という繰り返しでやるかな。
890 :
831 :2007/02/08(木) 10:05:40
まちがいた・・・orz
>>883 おれなら
cat -nとかでhtml書類を出力し
それをパイプしてgrepなどで一番最初に遭遇する
<span>と</span>をみつけ、
cut -d¥: -f1を使ってその行頭の数値(=行番号)をよみとり、
cat -nする前のhtmlに対してその数値の間をsedのdオプションで削除し、
その結果をまた
cat -nとかで出力し、
それをパイプしてgrepなどで一番最初に遭遇する
<span>と</span>をみつけ、
cut -d¥: -f1を使ってその行頭の数値(=行番号)をよみとり、
cat -nする前のhtmlに対してその数値の間をsedのdオプションで削除し、
という繰り返しでやるかな。
まぁ大抵の用途では「CDATAセクションに</span>がありました」 なんてケースは考えるだけ無駄だったりするよな。
そう? RSSとか扱ってると、結構あるけど
その辺の要求仕様は本来なら質問者が書くべきだと思うんだが たいていこういう質問投げるやつって投げっぱなしだよね。
RSSはXMLのくせにwell-formedなんてくそくらえって感じの世界が……
895 :
883 :2007/02/08(木) 14:59:16
自己解決しました
896 :
名無しさん@お腹いっぱい。 :2007/02/08(木) 16:26:18
ihsのログのローテーションについてのシェルで、次の2つのif文をfor文にまとめて書く書き方 知っているかた教えてください。 if [ -e /work/IBMIHS/logs/access_log ]; then mv /work/IBMIHS/logs/access_log /logs/auditlog/access_log.$(date "+%Y%m%d") >> ${LOG_FILE} echo "IHSログローテーション(アクセスログ)は成功しました。" else echo "IHSログローテーションは失敗しました。" exit 1 fi if [ -e /work/IBMIHS/logs/error_log ]; then mv /work/IBMIHS/logs/error_log /logs/auditlog/error_log.$(date "+%Y%m%d") >> ${LOG_FILE} echo "IHSログローテーション(エラーログ)は成功しました。" else echo "IHSログローテーションは失敗しました。" exit 1 fi
何が困っている(問題となっている)のか読み取れないんだけど・・・ ↑じゃダメな理由あるの?
for log in access_log error_log; do if [ -e /work/IBMIHS/logs/$log ]; then else fi done
シェルってゆうな for f in access_log error_log; do .... ってことをしたいのか?
IHSというかapacheのログってmvではローテーションできないんじゃなかったっけ? ま、それはおいといて、単純に繰り返し部分をまとめるだけなら、 SRCDIR="/work/IBMIHS/logs" DESTDIR="/logs/auditlog" for FN in "access_log error_log" do if [ -e "${SRCDIR}/${FN}" ] then mv "${SRCDIR}/${FN}" "${DESTDIR}/${FN}.$(date "+%Y%m%d")" >> ${LOG_FILE} echo "IHSログローテーション(${FN})は成功しました。" else echo "IHSログローテーションは失敗しました。" exit 1 fi done とか。
↑ for FN in "access_log" "error_log"
シェルスクリプトとちょっとずれるかもしれないのですが、 sudo -u hoge echo "hoge" > test.txt とすると test.txt の所有権は hoge ではなく、 sudo の実行者になります。 test.txt を hogeの所有権のファイルとして作成したいのですが、 どこに間違いがあるかご教授お願いします。
リダイレクトは sudo の実行前にシェルが解釈する。 sudo -u hoge sh -c 'echo "hoge" > test.txt'
シェルがコマンドラインを受理した際、 1. > test.txt 2. sudo -u hoge echo "hoge" の順で処理されるからね。 sudo -u hoge sh -c 'echo "hoge" > test.txt'
905 :
902 :2007/02/08(木) 20:09:21
>>903 レスありがとうございます、
上の内容をためしたところ、存在しない、といったエラーが出てしまいました。
お助けを〜〜
sh: test.txt: No such file or directory
906 :
902 :2007/02/09(金) 01:44:34
すいません、何か激しくボケていたようです。 再度試してみたらいけました。 ありがとうございました。 教えていただいた内容も納得です! ちょっと関連した内容になるのですが、 "hoge"の部分に改行などを含んだ変数を入れたいのですが、 うまくいきません。 どうやら改行ごとに、シェルが実行されてしまっている?ようです。 複数行にわたった変数を使用したい場合、 どのように記述すればよいでしょうか? 何度もすいません orz
改行を\でエスケープすれば効くかも。
シェルによっては、echo "hogeの直後に改行すると、"を認識してそのまま 継続行を入力させてくれるかも。
>>906 何もする必要ない。"hoge" の途中に改行があっても改行はそのまま保存される。
もし、そうならないなら、sudoを実行しているコマンドラインのシェルが、
普通のB-sh系のシェルじゃないんだろう。
(あるいは、sudo先のユーザーのログインシェルが B-sh系じゃないとか)
sh bash zsh ksh 等の B-sh系を使うこと。
910 :
902 :2007/02/09(金) 15:59:08
そうですか・・・・ レスありがとうございます。 ある変数の内容をファイルに書き込みたい、 という場合、echo とリダイレクトを使う以外にありますでしょうか?
↓これで委員じゃないか? echo "$変数" | sudo -u hoge sh -c 'cat > test.txt' sudo先のshでechoすると、クォートが2重になってややこしいから、 sudo前にechoしておいてパイプでつなぐ。
912 :
902 :2007/02/09(金) 16:30:53
>>911 orz ありがとうございます、うまくいきました。
クオートが入れ子になってて鬱入ってました。
発想の転換ですね、さすがみなさん視点がすごいです!!
本当にありがとうございました!!!
「ls -l」形式のファイル一覧が入っているテキストファイル(引数) を1行ずつ読み込み、ファイル名に「.bak」が含まれるファイルを 消去するシェルスクリプトを作成したいのですが、頭の「#!/bin/sh」 を書いた時点で力尽きました。 「while read」を使う、というところまでは理解出来たのですが、 文法等がさっぱりで…どなたかご教授願えないでしょうか?
>>913 read 使うと逆に難しそう。
grep .bak したのを sed か awk かなんかで加工して rm、がいいと思う。
> 「ls -l」形式のファイル一覧が入っているテキストファイル(引数)
この前提は変えられない?
ls -l 形式は扱いづらそうだから
find とか使った方がいいと思うんだが。
>>913 超簡単。1行で書ける。
while read line; do case $line in *.bak);; *) echo "$line";; esac; done < file
>>914 おまえには難しかったようだね。
「ls -l出力が書かれたファイルの中から、ファイル名 *.bakの行だけ消去する」のか、 「ls -l出力が書かれたファイルの中から、ファイル名 *.bakのファイルを消去する」 のか?
>>917 わかりにくい質問でどうも済みませんでした。
前者の意味です。
>>915 でできました。Thanksです。
rm したいんじゃなかったのか。 なら grep -v '\.bak$' でいいじゃん。 シンボリックリンクに対応してないけど。
920 :
913 :2007/02/11(日) 18:02:01
申し訳ありません。説明不足でした。 「ls -l出力が書かれたファイルの中から、ファイル名 *.bakのファイルを消去する」 が目的です。 ファイルリストをgrepして*.bakを含む行だけ取り出した後、awkを使用してls -lの リストからファイル名を抜き出して…とか色々と考えていたのですが、それらを シェルスクリプトで作成するだけの知識とか度胸とかが足りなくて困っております。 >915 回答ありがとうございます。「esacって何?」とか調べていたら返事が遅れて しまいました。
これ宿題だよなって言ったら
けっきょくどっちなんだ・・・
>>920 だったら、↓で行ける。(ls -l であって、ls -lR ではないんだから)
while read perm link usr grp size mon day year file other
do
case $file in
*.bak) rm "$file";;
esac
done < ls-l-file.txt
hoge.bakなんつーディレクトリがある可能性があるならtestも入れる。
まずは cat file |sed -e
926 :
913 :2007/02/11(日) 19:56:38
>923 回答ありがとうございます。色々いじくり回して実験してみます。
file の更新時間が今の何日前かを表示したいのですが、良い案はないでしょうか? アバウトに日付情報だけで判断できれば十分なので find file -printf "%Ad" でやろうと思ったのですが 月をまたぐとどうにもこうにもいきません。
>>927 OSによってはdateとかを駆使してもできるとは思うが、perlが適材適所
929 :
名無しさん@お腹いっぱい。 :2007/02/11(日) 23:41:54
%コマンド XXX ./AAA/ とやって、 ファイルXXX をディレクトリAAA にコピー(cp) して なおかつ、AAA に移動(cd) する というコマンドを作りたいんだけど、どうすればいい?
aliasかfunctionを使う
>>929 .bashrc あたりにこんな感じの function を書くのがお手軽かな
hoge(){
cp "$1" "$2"
builtin cd "$2"
}
引数のチェックとかの拡張はお好みで。
>>929 は%だからcsh系じゃないのか?と勝手に予想
どっちかというとBourneシェル系であるzshのデフォルトも%だったりして。
っていうか tcsh ならデフォルトは > なので。
tcshをargv[0]がcshで起動するとプロンプトは%
939 :
929 :2007/02/12(月) 22:02:42
返事が遅くなりました tcsh です
>>929 cshスクリプトを書いておいて、
それをsourceするaliasを設定するとか。
もっとスマートな方法、教えてエロい人。
蟹飯先生謹製のawkを落としてみたが、UTF-8で日本語が通る。 シンボリックリンクをgawkから変更しようかしら。 最近のgawkはインターネットアクセスが出来るらしいけど使いかたが分からない。
>>941 日本語が「通る」の意味がよくわからないが、
.がちゃんと一文字に適合したり
文字クラスとして[あ-ん]のようなものが書けたり
\u3120のようにユニコードリテラルを記述できたりするの?
>>942 そのへんは検証してもらえないかなと思いまして。w
とりあえず.は駄目でした。w
[あ-ん]はたぶん大丈夫そうな気が。
4行目の機能ってgawkにあるんですか?
>>943 いや別にgawkは関係ない。
せっかくUnicodeに対応しているなら、出来たほうが便利なのは
確実だが。
"Tibetan"とか"Greek"とか"CJKCompatibility"みたいに、
Unicodeのブロック/カテゴリ名が使えるとさらによい。
逆にその辺が出来ないなら、今時のUnicode対応としては
大したこと無いレベルじゃまいか?
まー今更awkにそんなに多くを求めてもしゃーない気はするが。
.が一文字に適合しないのなら、文字クラス指定も駄目っぽそうだな。 単に8bitクリーンなだけじゃないの?
どうやらそのようですね。 ...(.が3回)で一文字に適合しました。w
dir="aaa bbb" for f in $dir;do echo "$f" done とすると aaa bbb と表示されますが、この dir に空白を含む文字列を含ませるにはどうすればいいのでしょうか? イメージとしては dir='aaa bbb "ccc ddd"' とすると aaa bbb ccc ddd と表示できたらいいなと
>>947 そういう場合は位置パラメータを使う。
set aaa bbb 'ccc ddd'
for f in "$@"; do
echo "$f"
done
これで、
aaa
bbb
ccc ddd
と表示される。
「できないはず」と答えてしまった
>>948 が不憫。
951 :
929 :2007/02/13(火) 21:04:24
>>940 alias 使えばいいというのはわかるんですが、
そのcsh スクリプトがかけないんです
>>951 cshの話は厳禁。よそ行け。
b-shでの答えはすでに出てる。
for aa in aaa bbb ccc\ ddd; do echo $aa; done;
いつもの人キタ━(゚∀゚)━!!
>>951 $HOME/tmp/cpcd.shとかを作って中身を
#!/bin/tcsh
cp "$1" "$2"
cd "$2"
として、
chmod +x $HOME/tmp/cpcd.sh
alias cpcd "source $HOME/tmp/cpcd.sh"
単体で起動しても意味ないしsourceするんだから sh-bangも+xもいらないんじゃないか?
958 :
名無しさん@お腹いっぱい。 :2007/02/14(水) 01:24:40
ファイル名を"abc.txt"から日付+d.txtにリネームしたいのですがうまくいきません。 対処法を伝授して下さい mv abc.txt %Y%m%dd.txt
>>943 >4行目の機能ってgawkにあるんですか?
ない。
gawkは内部的にwchar_tを使っているだけで、スクリプトの記述は
そのときの locale設定が使われ、表にはUnicode(やwchar_t)はでてこない。
一応 [あ-お]はできるけどね。
>>958 mv abc.txt `date +%%Y%m%d`d.txt
%一つ余計だ。察して。
962 :
958 :2007/02/14(水) 01:52:02
>>960 ありがとうございます。うまくいきました
jawk
964 :
947 :2007/02/14(水) 03:20:49
965 :
名無しさん@お腹いっぱい。 :2007/02/14(水) 08:07:50
>>965 man 7 signal参照。
1:SIGHUP 2:SIGINT 3:SIGQUIT 15:SIGTERM
>>966 $ man 7 signal
No entry for signal in section 7 of the manual
ここはLinux板じゃない。
cron?
みす
>>966-967 man -a signalと言っておけばよかったね。
BSD(つーかMacだが)だとセクション3のライブラリ関数のとこに
一緒に載ってるようだな。
bash起動してtrap -lはどうか。
ls で ディレクトリのみ表示させるのは可能でしょうか?
973 :
名無しさん@お腹いっぱい。 :2007/02/14(水) 23:01:02
>>972 ls -FA | grep /
ちょっと意味が違うか?
974 :
名無しさん@お腹いっぱい。 :2007/02/14(水) 23:13:07
>>972 俺は
ls -l | grep 4096
でなんとかなっている
975 :
名無しさん@お腹いっぱい。 :2007/02/14(水) 23:15:18
>>974 ls -l | grep ^d
どちらかといえばこれか。
findを使うのは反則ですか?そうですか。
977 :
名無しさん@お腹いっぱい。 :2007/02/14(水) 23:26:49
ls の質問に便乗です。 大文字も小文字も区別なく表示させたいのですが、可能ですか? ls *.dat に何か工夫して、aaa.dat とbbb.DAT などを表示させたいです。
978 :
名無しさん@お腹いっぱい。 :2007/02/14(水) 23:36:16
>>974 4096って!
Bite じゃなくて bit 単位ですか?
家だと、 grep 512 で、例外を除き期待どおりの結果になるが・・
979 :
名無しさん@お腹いっぱい。 :2007/02/14(水) 23:44:26
ls | grep -i "\.dat$"
findを使うのは反則ですか?そうですか。
982 :
名無しさん@お腹いっぱい。 :2007/02/14(水) 23:50:41
>>980 それだと、質問子の例示した拡張子にしか一致しないよ。
>>大文字も小文字も区別なく表示させたいのですが、可能ですか?
というテーゼには合致しない。
983 :
977 :2007/02/14(水) 23:51:14
>>979 980
ありがとうございます
そっか、grep を使うという技があったか!
984 :
972 :2007/02/14(水) 23:56:08
できれば、 -l オプションを使わずにおながいします、 余計な出力が多いので・・・。orz
>>984 find . -depth 1 -type d
ってどのぐらいの範囲でつかえるんだろう?
tcshのjmanどこかにある?
991 :
972 :2007/02/15(木) 00:35:14
サンクスです、みなさん、
>>973 でいっきま〜〜す!!
>>990 ここは
シェルが参照するエイリアスがいくつ
って文章で終わってるね。ちょんぎれているのではないであろうかと愚考するものでありますが…
おそらく エイリアス置換 の章だな しょぼいブラウザをつかっているのかな? そこはページ全体の1/5ぐらいの場所
ieやoperaみたいなしょぼいブラウザしかないんだけどな
>990をxpのie6026…で見るとちょんぎれていて、しかも今日は切れるところがちがう… りぬサイトのせいなのかブラウザのせいなのかわからんけど。 りぬ使いは無問題か?
998
| | |∧∧ (-_-) 1000 (∩∩)――― / /
1001 :
1001 :
Over 1000 Thread このスレッドは1000を超えました。 もう書けないので、新しいスレッドを立ててくださいです。。。