1read 100read
2012年1月1期UNIX22: シェルスクリプト総合 その19 (112) TOP カテ一覧 スレ一覧 2ch元 削除依頼
・ 次のスレ
23: Solaris を入れてみます (160)
24: ☆ 古いPCを復活させよう (193)
25: OpenLDAP (300)
26: [test] 書きこみテスト 専用スレッド 11 [テスト] (183)

シェルスクリプト総合 その19


1 :11/12/10 〜 最終レス :12/01/09
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashなので特に注意。
 FreeBSDユーザは/bin/shの正体がashなので注意。
 v7 shに一番近くて、現役のshは、OpenSolaris由来のheirloom sh。
  http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/cmd/sh/
  http://heirloom.sourceforge.net/sh.html
・csh/tcshのシェルスクリプトは推奨されません。
 (理由は「csh-whynot」でググれ)
・UNIXにはシェルスクリプトに便利な小さなコマンドがいろいろあります。
 manや参考リンクを見ましょう。
 aproposないしはman -kでそれらしい単語による簡単な検索もできます。
・シェルスクリプトのことをシェルってゆーな
・シェルで使えるワイルドカード等は正規表現ではありません。
 正規表現の話題はスレ違い(正規表現スレへ)
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 RubyやPerlの方が適した仕事には素直にそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
前スレ
シェルスクリプト総合 その18
http://hibari.2ch.net/test/read.cgi/unix/1308195527/
次スレは >>970 で。

2 :
シェラーの皆さんこんにちは。
今日も元気にワンタイマーしてますか?

3 :
>>2
マジ質問ですいません。ワンタイマーって何ですか?

4 :
ワンライナーかな、とも思ったがシェルでワンライナーはそれほど重視されないしな…

5 :
相手すんなよ。

6 :

1000 :名無しさん@お腹いっぱい。 :sage :2011/12/11(日) 16:41:38.19
-z って変数が空か入ってるかぢゃ無いのかよ

7 :
>>6
変数が未設定か設定済みかをテストしたい時は、

test -z "${var+X}"

を使う。varに空文字列がセットされていても「設定済み」と判定する。

8 :
なるほどぉ。ためになるなぁ。
でもさ、スクリプトの場合あらかじめunsetで初期化しない?
unsetを初期化と呼ぶのかどうかさえ知らんのだけど……。

9 :
冷やすとリングはワンタイマーだよね?

10 :
here string は PowerShell用語だったという記憶。

11 :
bashのmanにも記載はあるが、何処のどいつが言い出したのかは分からんね
辿っていけば時期は分かるだろうが、PowerShellに関しては全く知らん

12 :
bashのhere string...
へー << じゃなくて <<< を使うんだな。
$ cat <<<XXX
XXX

13 :
つまりドザか

14 :
Powershellより昔の用語じゃないか?
ヒアストリングっていまいち使いどころがわからんけど。

15 :
ブロックコメントアウトには常用するよ
#!bash
:<<'#COMMENT'
echo $PATH
#COMMENT

16 :
それはhere stringじゃなくてhere documentじゃねーの?

17 :
ごめん、ヒアストか。たしかに使いどころがないというか、これくらいしか用例知らない。
awk <<< "$*" '{
for (i = 1; i <= NF; i++) {
print $i
}
}'

18 :
>>15
それはシェル内部で添付ファイル作られるから動作が無駄だな

19 :
grep -q 'pattern' <<< 'string'
とか使えると思うけど

20 :
>>18
その添付ファイル名を知る方法ってない?
終了時に自動で美しく消されるなら使い捨てのawkやsedを埋め込むのに使いたい。
mktempとか面倒だし本題からずれて見難いしさ。

21 :
>>20

exec 3<< EOF
hoge
EOF

cat /dev/fd/3

とか?

22 :
「無駄だな」マンw

23 :
シェルスクリプトライターなら、ソースで語れよ
無駄無駄だけじゃ、何も進まないぜ(キリッ

24 :
>>15 については、コメントアウトのつもりでも
実際には内部でtmpファイルが作られるという動作が実行され、
コメントになっていない、ということを >>18 が言ってるんだろ?
単に書き方が無駄だということじゃなくて、
根本的にコメントになっていないということ。

25 :
csh, commdnd.comでさえgotoがあるのにね。
cshの非実行部は構文解析されるんだっけ?

26 :
eucのサーバにおいて、sjisのファイルをcatすると文字化けするのですが、
対処方法としてはどうすればいいでしょうか?

27 :
nkf -e

28 :
>>27
iconv使えよ・・・

29 :
iconvはエラーで中途終了しちゃうからnkfの方が推奨。
(まあ、-sもあるとは言え)

30 :
>>29
つiconv -c オプション

31 :
半角文字とか記号とかが混じったデータだと、iconvじゃ変換できないってことがあった
日本語ならnkfの方がまだ分があるって気がする

32 :
sjisじゃなくてcp932でもそうなるならiconvのバグ臭いが

33 :
>>30
-c オプションでも解決はしないので nkfお勧め

34 :
-cのないiconvもあるよな…cygwinだっけか…(死亡フラグ

35 :
そもそもcygwinじゃデフォルトで入らないしnkfのパッケージもないから
入れてたpythonでフィルタ書いて使ってる

36 :
初歩的な質問なのですが、>>26の「eucのサーバ」ってどういう意味ですか?
サーバーの設定で文字コードって指定できるんですか?

37 :
サーバーのロケール設定が euc ってことじゃね?

38 :
別に i18n で euc を指定していようと、Terminal で sjis を指定してれば
文字化けだけは防げると思うよ。
文字化けだけは。

39 :
>>35
make一発でコンパイルできるやん
# Makefileにinstall targetがないけどw

40 :
iconvは自動判別してくれないよね?

41 :
>>38 が正解
間違っています >>39

42 :
>>41
えっ!?

43 :
ちょっとスクリプトを初めてちゃんと書いてみたので評価して欲しい。特にループ部分は他のやり方があると思う。
内容は天気表示スクリプトで使いかたは第1引数に、
http://weather.yahoo.co.jp/weather/jp/13/4410/13101.html
などのYahooのかなり限定されたURLを打ち込んで使う。
[Bash] weather_yahoo - Pastebin.com
http://pastebin.com/BxfbhQFd
curlじゃなくてaria2cは好みで使ってみた。
一部文字もユニコードで絵文字部分を使っているのでフォントや文字コードによっては文字化けが発生多発する思います。
最初のHTMLからの行の抜き出しはハードコーディングしないほうがいいと思うけど、構造自体変わったら元も子もないし、面倒でやめてしまった。

44 :
後で使うなら別だけど、
いちいち変数に入れずに、そのままアウトプットしちゃえばいいんじゃないの?

45 :
>>43
> #! /bin/bash
出直しな。

46 :
そういえばむかし圧縮形式ごとのオプションが面倒で全部kaitoってスクリプトにしてカレントにディレクトリつくって解凍するようにしたらいいんじゃないかと思ったけど、結局オプションを覚えてしまった

47 :
>>43
#! /bin/sh
wget -O - --quiet "$1" \
    | sed -n '149,163p' \
    | sed -r '0~2d
s/.*>([^<]+)<.*/\1/
s/晴れ/ /
s/曇り/ /
s/弱雨/ /
s/湿雪|乾雪|みぞれ/ /' \
    | tr '\n' ' ' \
    | awk '{ if ($7 == $8) $8 = "〃"
if ($7 == $8) $8 = "〃"
if ($6 == $7) $7 = "〃"
if ($5 == $6) $6 = "〃"
if ($4 == $5) $5 = "〃"
if ($3 == $4) $4 = "〃"
if ($2 == $3) $3 = "〃"
if ($1 == $2) $2 = "〃"
printf "|--+--+--+--+--+--+--+--|\n\
|00|03|06|09|12|15|18|21|\n\
|--+--+--+--+--+--+--+--|\n\
|%s|%s|%s|%s|%s|%s|%s|%s|\n\
|--+--+--+--+--+--+--+--|\n", $1, $2, $3, $4, $5, $6, $7, $8}'

48 :
>>46
7zがそんな感じになってるね。

49 :
そしてlibarchive化された FreeBSD の tar もそんな感じになんでもツールに

50 :
最近のlinuxのtarもzやjやJなしで解凍してくれるよな。
まあ圧縮するときにどうせ付けないといけないから結局覚えてしまうんだけど。

51 :
>>47
前時刻と同じかどうかのチェックと出力はまとめて
|awk '{for (i=1;i<9;i++){printf "|%s",$i==tmp?"〃":$i;tmp=$i};print "|"}'
としたい気分、スレ違い失礼

52 :
あれこれ覚えられない俺的には、tarが自動で何でも伸長して展開してくれる方がありがたい

53 :
http://www.nicovideo.jp/watch/sm16529183

54 :
引数のうち、-で始まるものを除いた個数を数えるにはどうすればいいでしょうか?
a.sh -a -b c d e
=> 3

55 :
>>54
#! /bin/sh
manko=0
for chinko in $@
do
if [ `echo $chinko | grep -v ^-` ] ; then
manko=`expr $manko + 1`
fi
done
echo $manko

56 :
>>55
"$@" の中に特殊記号とかスペースとか入ってたら駄目。

forとかでループしたりせずに一発でできる方法を想定してます。

57 :
n=0
for a in "$@";do
case "$a" in
-*)
;;
*)
n=`expr $n + 1`
;;
esac
done
echo $n

58 :
> forとかでループしたりせずに一発でできる方法を想定してます。
ねーよ。

59 :
何でfor文周りたらいかんのかその理由を詳しく。
sedで一文でできたとしても下のレイヤではいくらでもfor文回ってるだろうに。

60 :
>>56
そういうのはUNIX系OSとは非常に相性が悪いので、至れり尽くせりのMFCとかを使うほうが捗るよ

61 :
>>57さんのを使わせてもらいます。ありがとうございます。
ちなみに>>56は別人なので。

62 :
むう。ID表示しない板ってのはややこしいな。

63 :
ていうかとかRとかとかとか、やらないか

64 :
>>56 を上司に提出したら殴られました。
なんで…

65 :
それは暴力事件かパワハラだから警察に通報したらいいと思うぞ。

66 :
なぜgetoptsを誰も利用せんの?

67 :
>>66
俺は単純なものとか、拡張する予定が無いときはつかわないなぁ
それに複雑な処理をするならば、RubyなりPerl使った方が簡単とかさ

68 :
>>67
>>66>>54 の場合について言ってるんだろ?

69 :
>>66
こんな便利なものが!
getoptsを利用すれば、そもそも -で始まるものを除いた個数を数える必要もない
ことがわかりました。これで行きます。
まさに、forとかでループしたりせずに一発でできる方法ですね。

70 :
>69

71 :
Rもも使わなくていいって事ですね。
でもちょっと寂しいです。

72 :
>>68
おおッ。気付いてませんでした

73 :
getopts使ってもループは要ると思うが…

74 :
あるプロセスを起動して、その標準出力から100行分の入力をもらったら、
そのプロセスを自動的にすようなスクリプトは書けますでしょうか?
または、あるプロセスを100秒だけ起動して、その後自動的に強制的にすこと
は可能でしょうか。

75 :
>>74
>あるプロセスを起動して、その標準出力から100行分の入力をもらったら、
>そのプロセスを自動的にすようなスクリプトは書けますでしょうか?
あるプロセス | head -n 100
でいいんでねえの?
>または、あるプロセスを100秒だけ起動して、その後自動的に強制的にすこと
>は可能でしょうか。
あるプロセス &
sleep 100
kill -9 あるプロセスのプロセスID
でいいんでねえの?

76 :
>>75
$! 使えよ

77 :
>>75
上の方法はあるプロセスが101行目を出力しようとするまで生きてないか?

78 :
困るの?

79 :
もともとの仕様は満たしてないな。
困るかどうかは>>74に聞かないとわからん。

80 :
$!って、拡張機能だったかと

81 :
ボケるならもうちょっと面白いの頼む

82 :
どうせ学校の宿題だろ
そんなもん、動きゃいいんだよ

83 :
ボケてないよ。

84 :
ボケがウケなかったからって開き直らなくていいよ

85 :
>>75
ありがとうございます。
最初の問題については、たとえ延々と最初のプロセスが出力をたれ流していても、
パイプがなくなれば自動的にされるんですね。
後者の問題の場合、事前にプロセスIDが分からないのが問題なのですが、
シェルで、起動した命令のプロセスIDを取得する方法があるのでしょうか?

86 :
>>85
だから $! だって >>76 が回答してるだろ

87 :
>>76>>86 も、なぜこんな簡単なサンプルスクリプトさえ提示していただけないのでしょうか。
あるプロセス &
hoge=$!; sleep 100; kill -9 $hoge

88 :
>>87
変数が無駄だな
sleep 100; kill -9 $!
だけで桶。
あと、>>76 の回答でわからない人間にはサンプルを示しても無駄。

89 :
その $! に入ってるプロセスIDは、Sleep のものだとわかった上で言ってるのでしょうか…

90 :
>>89
わかってないのはオマエ sleepのプロセスIDは $! に入らない。

91 :
確かに、>>89 みたいなこと言ってる奴にサンプル示しても無駄だな。
正解者に間違った指摘する >>89 とかは書き込み自粛してくれ

92 :
「バッググランドで実行された」 直前のプロセスID…だろw
>>88 で桶。

93 :
自粛はしない。
すっげぇ数の訂正レスがついて嬉しい。ありがとう。

94 :
>>87-93
自作自演(・A・)イクナイ!!

95 :
ばーれたか

96 :
普段シェルbashとか使用しませんが
ファイルにある特定の文字でファイルを分割したいと考えています
何とか調べて
例えばkiritoriと言う文字の箇所からsample.txtを2つに分割するのに
grep -n kiritori sample.txtで行番号がわかりますので
split -ln sampl.txtによりxaa,xabの二つのファイルに分割することがわかりました
ここでお尋ねしたいのですが
grepとsplitをまとめて処理するためにはnをsplitに引き渡す方法がわかりません
どうかよろしくお願いいたします
又他の方法が有りましたらお教えください

97 :
sed '1,/kiritori/{ w xaa
d
}' sample.txt > xbb

98 :
>>97
早速のレス有難う御座いました。
おかげでファイルを分割できるようになりました
cutで行番号のみ抜き出したり
sedは文字変換のみの認識しかなかったりで
にわかもんはあなたのスクリプト見ただけで
すごいなと言う感想のみです
たまには勉強します
有難う御座いました

99 :
bashのことで質問させてください。
dateでYYYYMMを取得してきます。(例:201201)
1月から9月の場合には0を消去して、YYYYMで表示させたいのです。(例:20121)
自分でも一応下のようにして出来たのですが、もっと簡単に作る方法はないでしょうか?
lm=`date "+%Y%m"`
ll=`echo ${lm}|cut -c 1-4`
mm=`echo ${lm}|cut -c 5-6`
if [ ${mm} -lt 10 ];then
mm=`echo ${mm}|sed s/0//`
fi
lm=${ll}${mm}
echo ${lm}

100read 1read
1read 100read
TOP カテ一覧 スレ一覧 2ch元 削除依頼
・ 次のスレ
23: Solaris を入れてみます (160)
24: ☆ 古いPCを復活させよう (193)
25: OpenLDAP (300)
26: [test] 書きこみテスト 専用スレッド 11 [テスト] (183)