シェルスクリプト総合@LINUX Part3 at LINUX
[2ch|▼Menu]
1:login:Penguin
07/07/10 23:17:13 qGthZdME
UNIX板のスレを見ている方も多数おられるかと思いますが、
まあそれはそれとして、BASHウゼーとか言われる心配なく
平和にLINUX的スクリプト談義しましょうよ。

初めての自作スクリプト、自信ないから見てください。な初心者から
トリッキーな技を駆使した作品を披露したい、蘊蓄を語りたい上級者まで
いろいろな人に参加して頂けると嬉しいです。

perlやらPythonやらの話が混ざっても良いんでない?

【sed】シェルスクリプト総合@LINUX Part2【awk】
スレリンク(linux板)
スレリンク(linux板)

>>2-5あたりに色々と。


2:login:Penguin
07/07/10 23:18:45 qGthZdME
関連スレ
おまいら! sed  の使い方教えて下さいm(_ _)m@linux板
スレリンク(linux板)
【Shell】どのシェル使ってる?【Script】@LINUX板
スレリンク(linux板)
シェルスクリプト総合 その8
スレリンク(unix板)
sed@UNIX板
スレリンク(unix板)
2ちゃん画像落としまくりスクリプト@UNIX板
スレリンク(unix板)
連番のH画像/動画を一気にダウンロードする2
スレリンク(unix板)

ログを読みたい人はこちら
URLリンク(makimo.to)

3:login:Penguin
07/07/10 23:20:21 qGthZdME
参考リンク
bashで始めるシェルスクリプト基礎の基礎 @IT
URLリンク(www.atmarkit.co.jp)
シェルスクリプト(Bash)入門 CYBERAM Documents Project
URLリンク(cyberam.dip.jp)

IBM developerWorks
実例でわかるsed
URLリンク(www-06.ibm.com)
URLリンク(www-06.ibm.com)
URLリンク(www-06.ibm.com)
実例でわかるawk
URLリンク(www-06.ibm.com)
URLリンク(www-06.ibm.com)
URLリンク(www-06.ibm.com)
コマンドラインからのグラフィックス操作
URLリンク(www-06.ibm.com)
洗練されたPerl: MP3とPerlで遊ぶ
URLリンク(www-06.ibm.com)
URLリンク(www-06.ibm.com)

4:login:Penguin
07/07/14 09:56:17 42ZxWwqP
EUCで入力された文字列をShiftJISに置き換える方法ってありませんか?


5:login:Penguin
07/07/14 11:17:49 29sQfd47
>>4
nkf とか iconv とか。

6:login:Penguin
07/07/14 22:31:28 Lb+uQxni
シェルスクリプトの引数にワイルドカードを渡すと、
該当するファイルがファイルシステム上にある場合はそのファイルが変わりに
引数として渡されるみたいですが、ワイルドカード自体を取得したいのです。
何か方法はないでしょうか?
ちなみにダブルクォーテーションをつければ展開されないのは知っていますが、面倒で。。

(例)
$ test.sh *.txt
$ echo $1
とするとカレントにあるXXX.txtを表示するのではなく
「*.txt」を表示したいのです。

7:login:Penguin
07/07/14 22:53:16 29sQfd47
>>6
呼ばれるスクリプトの側でなんとかしたいってことなら
無理だよ。

8:login:Penguin
07/07/14 23:13:50 Lb+uQxni
>>7
そんな気はしていましたが、そうですか。。
残念です。

9:login:Penguin
07/07/14 23:26:42 29sQfd47
呼ぶシェル側でなんとかするなら
$ set -o noglob
$ test.sh *.txt
とか。

10:login:Penguin
07/07/15 05:00:56 OzInTFfn
>>6
test.sh '*.txt'
(シングルコーテーションならてんかいされないはず)

11:login:Penguin
07/07/15 11:22:44 oGW94xFn
>2
おまけの関連スレ

シェルスクリプト相談室
スレリンク(tech板)
awkについて語るスレ $2
スレリンク(tech板)

12:login:Penguin
07/07/15 12:37:56 llPpP8sT
>>8
よく仕様がわからんが、スクリプトの多段階呼び出しで展開されたくないんだったら、
$ test.sh @.txt
みたいに、擬似ワイルドカード指定指定しておいて
使ううときに、
fs=`eco $1 | sed 's/@/*/'`
echo $fs


13:login:Penguin
07/07/15 22:24:45 ZpXAubZ6
>>6
complete とかで、補完のルールを作れるんじゃないか?

bashで補完スレ [UNIX板]
スレリンク(unix板)


14:login:Penguin
07/07/16 12:28:16 MK2VLXxK
すみませんちょっとヘルぽ

/homeの中にある複数のファイル・ディレクトリーをrm -rf したいのですが
/home/hogeとlost+found だけは消したくないので

何とかそれ以外を消す方法をご教示頂きたいのですが
おしえてたもれ

15:login:Penguin
07/07/16 13:05:49 fC+1yCpQ
>14
shell script関係ないが、lsでリストとって、リストから削除したくないファイル・ディレクトリを削除し、
その後 rm -rf `cat 〜` なんかするのが間違いなくて確実だとおもー。

16:login:Penguin
07/07/16 13:13:37 hTbLQxc+
>>14
bashだったら、GLOBIGNORE="hoge:lost+found" に賭けてみたまえ

17:login:Penguin
07/07/16 13:32:26 xW/HZyHj
/home/hogeとlost+foundに書き込み禁止属性をつけてから一気に rm -rf
その後戻せばいいのでわ

18:login:Penguin
07/07/16 21:41:14 J/qZmNrt
>>14?!(xxx|yyy)

19:login:Penguin
07/07/17 03:37:44 I2w4SVYd
awk の出力をコマンドとして実行したいでつ。
どうやればいいでつか?

20:login:Penguin
07/07/17 10:02:57 ZxaQD0ZF
awk ... | sh


21:login:Penguin
07/07/18 08:18:48 Dw+iZryL
>>5
遅くなりましたが、ありがとうございます。
試してみたいと思います。

22:login:Penguin
07/07/18 16:34:40 cvC9pUm6
>>20
ありがとう。
できまちた。

23:login:Penguin
07/07/19 07:38:39 gg1Is+TJ
>>16 >>17 >>18 
dクス

とりあえず、試験機でゴリゴリしてみます

24:login:Penguin
07/07/19 07:41:44 gg1Is+TJ
あ、>>15 もdクスです
その方法でやってみたいと思います

25:login:Penguin
07/07/20 01:54:45 bZea7ZdA
スクリプトに実行時間制限を設けたいんですが、いい方法はないですか?
厳密さは求めていません。暴走防止程度です。
(因みにLinux初心者のプログラマです、あまり複雑な概念は未だ理解できていないと思います。

今は大体こんな感じでやろうとしています、
(sleep 10; kill $$)&
時間制限を設けたいコマンド

これだと、時間内に終了しなかったとき、スクリプトのみ終了し、実際に終了させたいコマンドは生き残ります。
時間内に終了したときにkillさせないために最後に kill `jobs -p` すると「(sleep 10; kill $$)&」は終了しますが、sleepだけが残ります(自然消滅はする
だからといって kill 0 とするとこのスクリプトの呼び出し元まで死んでしまいます。

プロセスを kill するときに、その子も殺せればいいんですが如何でしょうか。

26:login:Penguin
07/07/20 02:25:54 zucTG+iZ
>>25
ps --ppid とか pstree -p とかで
子の pid を調べれば
kill できると思う。

27:login:Penguin
07/07/20 07:34:06 0zbWXhyq
ulimit -tはだめ?
CPU使った時間になっちゃうけど。


28:login:Penguin
07/07/20 13:11:40 VbE5NJtk
killのman見ればprocess groupを殺す方法書いてあるだろうに。

29:login:Penguin
07/07/22 01:17:56 MkzMxIYh
>>26
pstree -p からpidだけ取り出す方法が分かりません。
ps --ppid の再起で殺すようにしてみましたが思い通り動いてくれません。
間違えている可能性は大いにありますが。

>>27
CPU時間でも構いません。寧ろその方が良いかもしれません。
ありがとうございます。調べてみます。

>>28
でしょうね。

30:login:Penguin
07/07/24 02:36:44 TdZoIfh3
>>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
07/08/04 23:01:23 prsNz29A
awkの区切り文字に'|'を指定するにはどうすればいいですか
awk -F'|'
ではパイプとみなされてしまいます

32:login:Penguin
07/08/04 23:37:42 dhi36EzE
やってみた。
% echo 'a|b|c' | gawk -F'|' '{print $2}'
b

33:login:Penguin
07/08/05 03:46:06 a+1tcmkL
>>31

-F'[|]' とか


34:login:Penguin
07/08/05 23:10:51 ftJrAaPL

非rootのアカウントからシェルを実行して
規定のHDDをマウントしたいと思っています。
問題は非rootなのでmountの実行権が無い点です。

sudo は設定方法がよく分からないので、
もちょっと簡単なやり方ないかと探しているのですが
何かよい方法ないもんでしょうか?

スクリプトの中でrootでログインして、そのまま
実行してほしい。(passwd入力はOK)

ちなみにSuSE 10.2を使ってます。


35:login:Penguin
07/08/05 23:39:27 YQ3bjemY
>>34
sudo の設定くらいわかれ。
そんなに難しくないよ。

36:login:Penguin
07/08/06 01:50:25 xhWrZGpQ
sudo -u USER /dev/hd ...

いかん、だるい。

37:login:Penguin
07/08/06 02:18:34 AKmvozj+
>>34
/etc/fstabの規定のHDDのエントリ内に user というオプションを書いておけば、
そこは一般ユーザでもmount/unmountできるようになる。
もちろんこの場合、mountコマンド自体のxビットは、一般ユーザが実行できるように
設定する必要がある。

38:login:Penguin
07/08/06 22:17:00 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
などをしたい。



39:login:Penguin
07/08/06 22:32:01 kQOiX48t
$ cat b.txt | while read keyword; do grep -i "$keyword" a.log; done

bshしか知らね。

40:login:Penguin
07/08/06 22:50:29 q2/C5Z+3
grep -f b.txt a.log

41:login:Penguin
07/08/09 03:57:05 q+NJZ5PJ
スクリプトの中から、
スクリプト自身のパスを知るにはどうすればいいですか?

42:login:Penguin
07/08/09 06:28:33 EHaDR+6/
echo $0

43:login:Penguin
07/08/09 08:01:28 NwjhxE+f
>>42
URLリンク(www.nurs.or.jp)

44:login:Penguin
07/08/09 11:34:05 EHaDR+6/
>>43
俺? $0で十分だと思うけど?

45:login:Penguin
07/08/09 21:51:00 8UsjPRp6
うわ。あさたくの文章、久しぶりに見た。

46:login:Penguin
07/08/10 18:42:50 hRezB52r
こんなの作った。

#!/bin/sh

for i in "$@"
do
a="$(echo $i | nkf -w)"
mv $i $a
done

convmv は元の文字コードを指定しなきゃならないのが面倒なので。
良かったらどぞ。

47:46
07/08/10 18:44:30 hRezB52r
書き忘れたので一応。
./myconvmv.sh *
とかで使える。

48:38
07/08/11 02:02:30 h4twNLWe
>>39
>>40
できました。神様ありがとう。


49:login:Penguin
07/08/15 18:16:19 oxw3opBU
・ファイルを指定フォルダ内へコピー
・同名ファイルが存在する場合は、
既に存在するファイル名を「ファイル名.1」へ変更し、
既にファイル名.1が存在しているのであれば、それをさらにファイル名.2へ変更し、、、(繰り返し)

というコピーシェルスクリプトがほしいんですが、
簡単な記述方法などがあったらおながいします。


50:login:Penguin
07/08/15 18:22:48 vI6OWTR9
>>49
自分ではどこまでできたの?

51:49
07/08/15 18:30:05 oxw3opBU
シェルスクリプト自体ほとんど作成経験がないので、
mv とかのオプションでそんな機能ないかな〜と
調べている程度の状態です。
--------------------------------------------------
・同名ファイルが存在する場合は、
既に存在するファイル名を「ファイル名.1」へ変更し、
既にファイル名.1が存在しているのであれば、それをさらにファイル名.2へ変更し、、、(繰り返し)
--------------------------------------------------
この部分を数行で教えていただけるとありがたいでつ。
ループ処理が必要になるのはなんとなく予想がつくのですが、、、

52:login:Penguin
07/08/15 18:34:51 vI6OWTR9
>>51
ファイルが何番まであるかを先にチェックして
番号大きい方から順に mv してくのが楽かな。
[ とか expr 使え。

53:login:Penguin
07/08/15 23:30:14 BP+0zqca
番号をrotateすることに大した意味がないことに気付き、--backupオプションとかで安易に済ます。
そんな自堕落な道を私は選びました。

54:login:Penguin
07/08/16 07:16:56 D/eLf54Q
ディレクトリにあるすべての*.cファイルを
全部*.cppにするにはどういう風に書いたらよいのでしょうか?
mv *.c *.cpp
としてみましたがだめでした
どなたかお知恵を...

55:login:Penguin
07/08/16 07:57:42 Uoi1O64b
rename コマンドで出来そうな気がする。

56:login:Penguin
07/08/16 10:10:37 MWEjh3WB
まあそうだけど。シェルスクリプトスレであることだし
for f in *.c; do mv "$f" "${f}pp"; done

57:login:Penguin
07/08/16 13:33:29 D/eLf54Q
>>56
Thx,できますた!

58:login:Penguin
07/08/23 16:17:17 n9QZBMiJ
flashの動画をダウンロードできる
シェルスクリプトある?

59:login:Penguin
07/08/23 16:36:59 lPn22JjI
kurekure厨

60:login:Penguin
07/08/23 16:53:47 C+I5hIDu
>>58
普通にwgetでダウンロードすればいいだけでは?
youtubeから簡単に落としたいとかであればyoutube-dlとかが便利。

61:login:Penguin
07/08/24 19:56:13 k2Yrnokn
すごく基本的なことなんだろうけど、
いくつかのディレクトリの中にあるファイルのそれぞれの名前を変数に入れたいんだけど、

files=ls dir* | sort

for i in files
do

done

みたいなことは出来ませんか?
要するに標準出力する内容を変数に入れたいだけなんだけど。

62:login:Penguin
07/08/24 20:25:50 iKvrTLai
>>61
「コマンド置換」でぐぐってみ

63:login:Penguin
07/08/24 20:43:22 k2Yrnokn
>>62
理解できました。どうもありがとりんこです。

64:login:Penguin
07/08/26 16:36:55 sDCP6Pah
ファイル一覧だと長大になって溢れるので

 ls ... | sort | while read i; do echo $i; done

とかも定番。

65:login:Penguin
07/08/27 08:44:07 mTK43/6/
for i in dir*
do

done

sortを挟むのは良くわからんが、単純にこんなんで済む話じゃね?

66:login:Penguin
07/08/27 18:32:24 Vup2OsE3
>>64
それだとlsの時点ですでに溢れる

67:login:Penguin
07/08/27 20:04:00 5Y4ThyNx
find DIR -exec (ここで好きなことやれ) \;


68:login:Penguin
07/08/28 00:17:04 Gt/lw90m
/home/200708/1200・・・1300・・・1400/と100刻み1800までディレクトリーがあるとして
A.PDFとかファイルが格納されてて

0KB〜150MBなら 「ne-yo」
500〜600MBなら 「OK」 とfile.txtを出力したいのでつが・・・・・
if,thenの繰り返ししかないでしょうかね?

69:login:Penguin
07/08/28 00:58:46 is4Tjxw4
なんのバイト数? そのディレクトリ内ファイルの総和?

70:login:Penguin
07/08/28 08:13:17 k11zEdxe
こんな感じ?

 $ du -s * | awk '{ print $2," ", ($1 > 10000 ? "ne-yo" : "OK") }'

条件文のところは自分で書き換えてくれ。

71:login:Penguin
07/08/28 09:07:28 LHhLJxDo
なるほどdu か。。。。と、>68とはちがう漏れ様が感心しますたーw

72:login:Penguin
07/08/28 14:07:23 LHPFC9xp
du 以外だと例えば何が?

73:login:Penguin
07/08/28 16:21:13 N3nQTqrG
すいません、初心者の質問です。

# 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でも構いません)で教えていただけるとありがたいです。


74:login:Penguin
07/08/28 16:31:19 kk6ZVe0N
>>73
つcsplit

75:login:Penguin
07/08/28 22:47:28 WiEkAmOg
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...の部分は付け足してクレイ

76:login:Penguin
07/08/28 23:05:57 WiEkAmOg
cat /tmp/test.txt | gawk '/^# time = 0\.20+E-01 *$/,/^ *$/ {print $0}'

あと仕様の意味が、#time=...から始まる一ブロックだけ出す(空行が出たらオシマイ)
という意味ならもっと単純になる

77:login:Penguin
07/08/28 23:48:14 Gt/lw90m
>>70 すげーまさにOK!ですた! 
awk の ? と : の使い方に感動

>>71-72  ls -lh とかでやろうとしたのは漏れ様も同じww



78:login:Penguin
07/08/29 12:08:46 NEtL1MxO
>>74
>>75
さっそくにありがとうございます。
試してみます。


79:login:Penguin
07/08/29 22:41:00 4pERO676
再帰的に2つのディレクトリをdiffしたいのですが存在するかしないか
と違うファイルだということだけわかればいいので
わかりやすく比較する方法はありませんか?
diffのマニュアルみてもそれらしいのはないようで

80:login:Penguin
07/08/29 22:50:35 UIgvqpQI
>>79
diff -rq dir1 dir2 ではだめなの?

81:login:Penguin
07/08/29 22:51:26 N3MeiS9e
>>79
URLリンク(www.gnu.org)
$ LANG=C diff -r dir1 dir2 | grep Only
とかである程度分かるかも。


82:login:Penguin
07/08/29 22:52:42 N3MeiS9e
む、-qで違いが分かるのか orz


83:login:Penguin
07/08/29 23:16:46 9GyP78LH
デジャヴなんだが俺だけか?

84:login:Penguin
07/08/30 01:02:14 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



85:login:Penguin
07/08/30 04:22:00 GmS5dPb3
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までループさせればいいと思う

86:login:Penguin
07/08/30 07:19:55 QpfKAJKg
そのバージョン表記の書式にもよるけど、

 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

あたりでどうかな。


87:login:Penguin
07/08/30 18:00:56 bHskgKzh
>>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 にある。
他のディストリは知らないけど
パッケージが用意されてるかもしれない。

88:login:Penguin
07/08/30 23:05:03 nhWZyH15
$ which rpmver
rpmver not found

うえーん。。。

89:login:Penguin
07/08/31 00:47:12 U99N+hxP
>>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ですが
07/09/01 15:15:18 uwRTp3HZ
>>76
おくればせながらありがとうございました。

91:73ですが
07/09/01 22:39:45 uwRTp3HZ
>>76
仕様はおっしゃるとおりです。
その際のスクリプトも教えてくだされば幸いです。
なお、他のスクリプトは現在のところ動作していません。わたしの知識不足なのだろうと思うのでもうすこし調べてみます。
#0は補ってはあるのですが...
ついでといってはなんですが、awkの本でおすすめの本などありましたら教えていただけませんか?

92:login:Penguin
07/09/02 04:19:30 WMH1r7G1
>>91
オライリーの sed & awk
てかawkの本なんて何冊もないって。


93:login:Penguin
07/09/02 08:46:56 ToB27R8d
本命 足立さんの訳してる awk 本
大穴 awk 256 本

94:login:Penguin
07/09/02 20:47:44 VmAuZafy
awk256倍はDOS時代からある骨董本で内容もふざけまくっているが、初心者が
「正規表現」「連想配列」という二つのキモを学習するにふさわしい内容。
読み終わったあとも、巻末の関数一覧がずっと使える。未だに刷を重ねてるけど
愛用者もおおいんじゃない?
大して御本家3人の書いたawk本は内容が高度な上に散発的で、調べたいことが
すぐに出てこなくて使いにくい

>>91
>>76のがその仕様のスクリプトなんだけど。うまく動かないのは、スペースとかが
ちゃんとコピペされてないからなんじゃないの?

95:73ですが
07/09/02 21:37:03 71yMDj2y
>>92-94
本の紹介ありがとうございました。
>>94
気づきませんでした。すいません。スペースの問題などを再確認してみます。
またなにかあったら伺うかもしれません。よろしくおねがいします。

96:login:Penguin
07/09/02 21:40:05 QLbcFUyG
DOS時代ってのはいつまでを言うんだ?

97:login:Penguin
07/09/02 21:55:05 ToB27R8d
awk 256 本の話の文脈としては、MS-DOS上のawk実装の時代かな

98:login:Penguin
07/09/02 22:03:47 VmAuZafy
>>97
そう。今の版じゃ改訂されてるのかもしれないが、俺の持ってるのだと
gawkをDOSに移植したjgawkとかいうのを下敷きにしていて、中には486を乗せたキューハチだと
スクリプトの速度が向上したとか、パイプの実行速度が遅いのはUNIXみたいな本物のパイプじゃないからとか、
そんな話題が満載

99:login:Penguin
07/09/02 22:04:37 QLbcFUyG
MS-DOS上のawk実装の時代ってのはいつを言うんだ?

100:>>84
07/09/04 00:34:58 3rxVdbk9
おくらばせながら、ありがとうございますm(_ _)m

101:login:Penguin
07/09/06 08:15:09 33eRwNa2
指定されたディレクトリ以下にあるディレクトリ一覧を返してくれるコマンドはありませんか?

/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 等の難しいコマンドはなるべく使わずに実現したいのですが、出来ませんかねぇ?
宜しくお願い致します。

102:login:Penguin
07/09/06 08:27:57 QTrKtnCG
>>101
ls -d /data/*/

103:login:Penguin
07/09/06 08:30:08 QTrKtnCG
/data/.x/ とかも考慮したいなら find で。

104:login:Penguin
07/09/06 08:31:55 33eRwNa2
>>102
あっちゃー・・・・そんな簡単なコマンドでこんな素晴らしい出力が得られるんですか!
LinuxのCUIって本当に高機能ですね・・・素晴らしいです。本当にありがとうございます。

ls -l /data/ | grep ^d | wc -l
ってやるより
ls -ld /data/*/ | grep ^d | wc -l
ってやる方が良いのでしょうか?どんなファイルやディレクトリがあっても確実に動作するような
書き方をしたいのですが・・・。

105:login:Penguin
07/09/06 08:32:01 QFjDOBHf
属性が見えて良ければ
ls -d /data/*|grep "^d"



106:login:Penguin
07/09/06 08:33:56 QFjDOBHf
-l忘れてた



107:login:Penguin
07/09/06 10:26:24 QTrKtnCG
>>104
> ls -ld /data/*/ | grep ^d | wc -l
なんで grep するんだ?

108:login:Penguin
07/09/06 11:58:40 rZQRUej8
ls -1d /data/*/ /data/.*/

/data/../ もヒットするのが難点だけどな。ってかあれだ。つ「man ls」

109:login:Penguin
07/09/06 16:47:27 40ywKZW4
>>101
求めてることが出来たのであればどんなコマンドでもいいけど
find の使い方も知っておいたほうがいいと思う。

> 不具合が発生するようなケースは想定されますか?
> ディレクトリだと ls -l した時に必ず最初が dから始まる
ディレクトリへのシンボリックリンクがあった場合の扱いをどうするか。

さらに言えばリンクの対象がどこにあるか
ln -s /data/A /data/B と ln -s /tmp/C /data/B の違いとか。

110:login:Penguin
07/09/06 16:55:32 QTrKtnCG
ls -Ap /data | grep /$
でよかったか。

>>109
> find の使い方も知っておいたほうがいいと思う。
同意。

111:login:Penguin
07/09/06 17:08:55 ZccH/OF/
なのに誰もfindを使った答を書かないのはなんでだw
101への課題?

112:login:Penguin
07/09/06 20:00:39 QTrKtnCG
>>111
それもあるし、単にめんどうだし。

113:login:Penguin
07/09/07 11:30:33 BZSReuYl
んじゃ、俺の回答に採点してくれ
find /data -type d -maxdepth 1

114:109
07/09/07 17:14:59 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.

115:login:Penguin
07/09/07 17:35:19 BZSReuYl
>>114
なるほど。非常に参考になった。
模範解答を頼む。

116:login:Penguin
07/09/07 17:39:52 aiZtBudz
>>115
もう一回自分で書いてみたら?

117:login:Penguin
07/09/07 19:24:55 Txvf/Wl4
find /data -mindepth 1 -maxdepth 1 -type d -exec ...

shopt -s nullglob
for i in /data/{,.{[!.],.?}}*/
do ...

こんなんでいかが

118:login:Penguin
07/09/07 19:45:52 ezpNZgi5
cat hoge | awk
に似ている。

119:login:Penguin
07/09/07 20:30:25 BZSReuYl
>>116
OK。これでどうだ?
find /home/* -maxdepth 0 -type d


120:login:Penguin
07/09/08 04:46:18 WlyFgm6n
>>117 でもう答え出てるじゃん。

>>119
/home/.xxx/ とかが出ない。
* 使うなら find 使う意味ない。

121:login:Penguin
07/09/08 14:42:47 vllGfkN4
>120
>* 使うなら find 使う意味ない。
上下別々の回答なんじゃないの?

122:login:Penguin
07/09/11 03:08:21 997sWGjJ
bashrc の書き方もこのスレでいいですか?

123:login:Penguin
07/09/12 11:40:47 EatE1MlG
#!/bin/sh -f
ls *.dat > list.txt

なぜか走らん。

124:login:Penguin
07/09/12 17:16:53 A49nKXNq
>>123
子プロセスとして(?)起動するシェルに -f が渡らないんだと思う。
/bin/sh -f hoge.sh とか
あらかじめ /bin/sh -f で起動したシェルで
./hoge.sh みたいにすると
-f が有効になる。

125:login:Penguin
07/09/12 17:21:21 EatE1MlG
>>124
エラーで *.dat: ファイルもディレクトリもありません とでる
ワイルドカードが原因かと思ったけど、hoge*でも同様のエラー

シェルにしたら走らず、コマンドラインで直接投げたら走る
なんでだろ

126:124
07/09/12 17:27:12 A49nKXNq
>>125
/bin/sh -f の -f がどんな意味かわかってる?

あと、シェルとシェルスクリプトはちゃんと区別したほうがいい。

127:login:Penguin
07/09/12 17:33:44 EatE1MlG
!/bin/cshで走ったわ
コンソールがcshだった

128:login:Penguin
07/09/12 20:01:20 9HkBr7tD
複数のpasswdファイル(passwd_A、passwd_B)を結合して、同じユーザ名があった場合
passwd_Aのものだけを残すというようなことをしたいのですがどうすればよいでしょうか?

129:login:Penguin
07/09/12 20:12:55 nfcPR4Gc
いったんファイルを結合する
一行ずつ上から順に読んでパスワードファイルに書き込む
書き込んだらそのユーザー名を別ファイルに書き出す
その別ファイルにユーザー名がないことを確認してから
パスワードファイルに書き込めばよい

130:login:Penguin
07/09/12 22:19:22 qqfxe9V8
while read t ;do
if [ "`grep ^${t%%:*}: passwd_A`" ];then
continue
else
echo $t >>passwd_A
fi
done <passwd_B


131:login:Penguin
07/09/12 22:53:21 SML918nz
んだば awk で。
awk -F: '{
    t[$1] = $0;
}
END {
    for (e in t)
        print t[e];
}' passwd_B passwd_A

132:login:Penguin
07/09/12 23:49:46 lhLTsTba
awk -F: '!($1 in t){print;t[$1]=1;}' passwd_A passwd_B

133:login:Penguin
07/09/13 21:53:28 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でできなくて悩んでおります
よろしくお願いいたします


134:login:Penguin
07/09/13 22:06:02 OVx1tSlg
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

135:login:Penguin
07/09/13 22:08:03 G9V8Phhb
\(\)でグルーピング、\{\}でマッチする回数の指定。
グルーピングしたパターンは後で\1,\2で参照出来る。
\を忘れるなよ。

136:login:Penguin
07/09/13 22:09:20 G9V8Phhb
あ、ごめん、>135はGNU sedの話

137:login:Penguin
07/09/13 22:25:32 8j1+julM
>>134
ありがとうございます
gwakというのも勉強してみようと思います





138:login:Penguin
07/09/13 22:52:13 8j1+julM
>>134
manを見てみたら いろんなところで使用できそうです
本当にありがとう

139:login:Penguin
07/09/13 23:24:02 saILvvtf
>>134
catは要らんだろ。

140:login:Penguin
07/09/14 00:50:00 uh85VpLs
正規表現も勉強した方がよろしいかと>>138

141:login:Penguin
07/09/14 12:28:52 hH9EcwDJ
ある 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なのはなぜですか?

142:login:Penguin
07/09/14 12:34:24 18sjQ9F0
>>141
kill って標準入力を受け付けないんじゃない。
ところで pkill XXX じゃだめなの?

143:login:Penguin
07/09/14 12:37:30 hH9EcwDJ
>>142
そうなのかなと思って
for p in $(ps aux | grep XXX | grep -v grep | awk '{print $2}'); do
    kill "$p"
done
ってのもやってみたんですが、だめだったんですよ。

144:login:Penguin
07/09/14 17:32:35 Ney/3ygS
スクリプトでタイマー作れませんか?
一定間隔ごとに単純にコマンド出すだけじゃなくて
処理ごとに条件分岐してタイマーを止めたりコマンドが成功
するまで繰り返したりしたいのですが

145:login:Penguin
07/09/14 20:21:33 KxObz0sB
>>144
sleep使って、て程度で良いなら作れるような気しかしないんだけど、具体的にどうしたいのか書いたのが良いと思うぞ。

146:login:Penguin
07/09/14 20:32:43 RM0kquC+
>>144
どこまで出来たの?

147:login:Penguin
07/09/14 23:57:41 XHXILi6a
>>143
だめってどうダメだったのかわからんと。

for p in $(ps aux | grep smbd | grep -v grep | awk '{print $2}'); do
"kill "$p"
done

これでやったらちゃんと動いたよ。スクリプトの問題じゃなくて
単に権限がなくてkillできなかっただけでは?

148:login:Penguin
07/09/15 16:55:13 /cIKvz/T
>>147
さっきやってみたら出来た。。。

間違って mplayer を40個くらい起動してしまって、そこでそのスクリプトを
叩いたつもりだったんだけど、焦ってなんか間違ってたのかもしれない。

とりあえず今度からは xargs のほうを使うようにするよ。

149:login:Penguin
07/09/15 17:28:32 YiwEKkpX
いやだからpkill使えって

150:login:Penguin
07/09/15 17:49:23 X+i1f7J3
command | command みたいな

cat hoge.txt | grep piyo

書き方があるじゃないですか? cat hoge.txt で出力される標準出力をパイプかませて
その出力内容に対して grep piyo をかける と言うような。
これと
xargs ってコマンドがあるじゃないですか?その違いがよく分からないのですが・・。
cat hoge.txt | xargs grep piyo

みたいな?

151:login:Penguin
07/09/15 18:13:14 YiwEKkpX
「cat hoge.txt | xargs grep piyo」=「grep piyo `cat hoge.txt`」



152:login:Penguin
07/09/15 18:42:58 X+i1f7J3
>>151
ほぉほぉ・・・・

cat hoge.txt | xargs grep piyo が
grep piyo `cat hoge.txt`
と同じならば
cat hoge.txt | grep piyo

grep piyo hoge.txt

ん?なんか混乱してきた・・・イマイチはっきりと分からない・・・

153:login:Penguin
07/09/15 19:03:27 8eNJORpc
argっていうぐらいだから引数に展開してくれるのだろ
その場合hoge.txtの中身はファイル名でないとだめ

154:login:Penguin
07/09/15 19:15:07 jJyNjt7I
もう分かってるかもしれないけど、xargsは標準入力をコマンドライン引数に変換するだけ。
echo 'file1 file2 hoge' | xargs rm
 ↓
rm file1 file2 hoge

155:login:Penguin
07/09/15 19:47:59 X+i1f7J3
むぅ・・・

echo `file1 file2 hoge` | xargs rm

rm file1 file2 hoge
となるならば
echo `file1 file2 hoge` | rm

どう展開されるんですか? すみません、ほんと頭弱くて。

156:login:Penguin
07/09/15 19:51:39 YiwEKkpX
引数と標準入出力の区別がまだついてなくて、全部「入力」として
ごちゃまぜの段階でしょ?まずそれを考えてみるんだ>155

157:login:Penguin
07/09/15 23:18:03 +DsxitZ3
>>154の echo 'file1 file2 hoge' | xargs rm
>>155の echo `file1 file2 hoge` | xargs rm

どこが違うか理解してからにしろ


158:login:Penguin
07/09/15 23:25:38 PpA5ThvC
こんな初歩の初歩みたいなことに、どうしてそんなに高飛車になれるんだ。

159:login:Penguin
07/09/16 01:01:56 S5o7UTSR
初歩の初歩は自力で身に付けてから来てくれよ。

160:login:Penguin
07/09/16 01:06:18 BSYCrrV+
タコタコ

161:login:Penguin
07/09/17 04:16:34 nqz563FT
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:login:Penguin
07/09/17 08:49:52 hnYIly1T
>>161
qkc最強伝説

163:login:Penguin
07/09/17 11:57:35 nqz563FT
>>162
URLリンク(hp.vector.co.jp)
これですよね?

しかしこれはconvmvとは全く別物のようです。

convmv => ファイル"名"の文字コードを変換する ←私はコレが必要
qkc   => テキストファイルの"中身"の文字コードを変換する ←これは違う・・・

なので使えないみたいです。

ちなみに >>161で書いたスクリプトを実際に動かしてみた所、LinuxサーバのCPU使用率が
100%になって固まっちゃいました。無限ループをしているかファイル名取得に失敗しているか
よく分かりませんがダメでしたOTL

164:login:Penguin
07/09/17 12:18:44 CDwJTqgj
よくわからんのだが、nkf -gで文字コードの判別してやりゃ良いんじゃねぇの?

165:login:Penguin
07/09/17 12:56:16 RA5G8Fdp
while ! convmv -f sjis -t utf-8 -r /data --notest ; do
convmv -f euc-jp -t utf-8 -r /data --notest
done
なんか、どうよ?
文字コード判定がいまいちなのか誤認してくれたりするので --notest とって、ざっと眺めてからやる事を推奨。


166:login:Penguin
07/09/17 13:00:08 85s13mgP
--notest 外して試してみればーじゃん。

167:login:Penguin
07/09/17 13:21:00 hplwR1nR
echo $RANDOM

で結果に乱数を返したいんですけど、
0〜9までの一桁の結果のみ返したい場合の指定方法とかってありますか?

168:login:Penguin
07/09/17 13:53:15 MlIRuyKv
$RANDOM % 10

169:login:Penguin
07/09/17 15:09:07 nqz563FT
>>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はずして試してみてますが、エラーで弾かれます。

170:login:Penguin
07/09/17 15:30:26 kUn2DAgf
>>169
いや、ファイル名のコードをnkfで調べりゃいいじゃん、てことだったんだけど。

171:login:Penguin
07/09/17 15:35:55 kUn2DAgf
念のため。
for T in `ls ~`
do
C=`echo "$T" | nkf -g`
echo $T,$C
done
ファイル名の文字コードを調べてると思うんだが。

172:login:Penguin
07/09/17 16:38:42 nqz563FT
>>170-171
違うと思うなぁ・・・。

>>171のスクリプト実行してみたけど
これは ls ~ で表示されるファイル名リスト全体、、、そうだなぁ、、例えば
a.txt
b.mp3
c.tar
d.gz
e.tar.gz

とか日本語も含むファイル名全てが列挙されると思うけど、それらのファイル名リスト
全体を1つのテキストファイルとみなして、テキストファイルの中身(つまりファイル名が列挙されてる)
に対して文字コード変換をかけた結果を echo で出力しているんじゃないですか?
だからnkf は ファイル"名"の文字コードを調べるんじゃなくて、あくまでもテキストファイルの中身
の文字コードを調べるんだと思いますが。それこそqkcみたいな動作?
convmvは全くそれとは性格が異なる物だと思いますが、、非常にこの辺ややこしい・・・。

173:login:Penguin
07/09/17 16:45:55 8vN1DPCo
なんでこんなに全然わかってないのに自信満々なのだろうか

174:login:Penguin
07/09/17 16:47:06 rlyHM/pf
>>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 の文字コード判定の
精度はあまりよくないが、やらないよりはマシだろう。


175:login:Penguin
07/09/17 16:52:30 HxbR0j5A
文字コードが違うファイル名が混在しているディレクトリって。
どうしてそうなったかが気になる

176:login:Penguin
07/09/17 16:55:54 4XOwAbVo
ローカルで作ってSambaで作ってWebDAVあたりで作ってとやってしまうと
起きるな?>混在。

後はデータ中の文字列を元にファイルを作ったりすると、うっかり
混在状態になったり。

177:login:Penguin
07/09/17 17:22:02 kUn2DAgf
>>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
半角カナ使ってなけりゃ、それなりの精度なんじゃねぇかと思うんだけど、どうだろ。

178:login:Penguin
07/09/17 17:29:26 kUn2DAgf
>半角カナ使ってなけりゃ、〜
↑勘違い。すま。


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5365日前に更新/275 KB
担当:undef