トップページunix
1001コメント305KB

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

レス数が900を超えています。1000を超えると表示できなくなるよ。
0001名無しさん@お腹いっぱい。2009/01/29(木) 06:54:48
シェルスクリプトの総合スレです。
スクリプトのお勉強・自慢・腕試しなどにどうぞ。
まずは注意点、リンク、地鎮祭など(>>1-6くらい)をご覧ください。


□お約束
・特記なき場合は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 でトレースしましょう。

前スレ落ちたみたいなのでリンク省略。
0824名無しさん@お腹いっぱい。2009/05/22(金) 17:38:26
word1="This is a pen"
array=( word1 )

echo ${array[0]}

これを実行すると、Thisって表示される。

array[0]にThis is a penを格納したいんだけど、どうすればいいですか?
0825名無しさん@お腹いっぱい。2009/05/22(金) 17:43:48
>>824
array=( "$word1" )
0826名無しさん@お腹いっぱい。2009/05/22(金) 17:47:22
罰腫胃損乙
0827名無しさん@お腹いっぱい。2009/05/22(金) 18:00:47
>>825
できました!

ありがとうございました。
0828名無しさん@お腹いっぱい。2009/05/25(月) 20:19:14
00 01 02 03 04
05 06 07 08 09

というような内容のファイルを

0 1 2 3 4
5 6 7 8 9

という内容に変換するにはどうやったらいい?
0829名無しさん@お腹いっぱい。2009/05/25(月) 20:22:32
>>828
tr -d 0
0830名無しさん@お腹いっぱい。2009/05/25(月) 20:25:13
おれでも答えられそうな低級レベルの質問きたー
$ cat hoge.txt
00 01 02 03 04
05 06 07 08 09
$ sed -e 's/0\([^0]\)/\1/g' hoge.txt
0 1 2 3 4
5 6 7 8 9
0831名無しさん@お腹いっぱい。2009/05/25(月) 20:26:09
>>829
最初の0が残らないぞ。
0832名無しさん@お腹いっぱい。2009/05/25(月) 20:43:52
>>830
それだと、102 とかが 12 になってしまう。
0833名無しさん@お腹いっぱい。2009/05/25(月) 20:49:29
0203 とか 0052 とかの対応も含めて
ゼロサプレスをもう少しちゃんとやるとすると、こうか?

sed 's/¥<0*¥([^0]¥)/¥1/g'
0834名無しさん@お腹いっぱい。2009/05/25(月) 20:50:46
>>833
それ、今度は 00 が 00 のままになる。
0835名無しさん@お腹いっぱい。2009/05/25(月) 20:58:19
>>830 も、単独の
00
だけの行があると
00
のままになるよ。

ハイ、やり直し。
0836名無しさん@お腹いっぱい。2009/05/25(月) 21:02:20
00だけ別対応だな。

sed 's/¥<0*¥([^0]¥)/¥1/g;s/¥<00*¥>/0/g'
0837名無しさん@お腹いっぱい。2009/05/25(月) 21:05:22
>>836
対応できてませんけどw
0838名無しさん@お腹いっぱい。2009/05/25(月) 21:13:12
>>830
元ファイル:
04 03 02 01 00

結果:
4 3 2 1 00
0839名無しさん@お腹いっぱい。2009/05/25(月) 21:17:40
フルボッコw
0840名無しさん@お腹いっぱい。2009/05/25(月) 21:22:45
>>828
それを実行してるFreeBSDのバージョンは?
0841名無しさん@お腹いっぱい。2009/05/25(月) 21:57:51
>>840
質問した本人は言い辛いと思うので(ていうかもう見てないか)言っておくが、
書いても君には答えられない。
そもそも書く意味がほとんど無いから書いてない。
0842名無しさん@お腹いっぱい。2009/05/26(火) 01:14:33
3日ぶりの質問に群がるレスは煽りと否定ばかり
間違ってはいたけど建設的なのは一人だけ、まぁ全てが自演かもしれんけど
こんなんでどうだろう?

sed -e 's/0*\([0-9]*[0-9]\)/\1/g' hoge.txt
0843名無しさん@お腹いっぱい。2009/05/26(火) 02:38:05
多分>>830>>833 = >>836だろ
0844名無しさん@お腹いっぱい。2009/05/26(火) 06:10:05
シェルスクリプトというよりsedスレ化してるな。
0845名無しさん@お腹いっぱい。2009/05/26(火) 07:38:19
>>842
もとの質問の「仕様」が不明確だから何とも言えないけど、

A00B みたいなのが A0B に変換されてしまうのはいいんだよな??
0846名無しさん@お腹いっぱい。2009/05/26(火) 12:26:35
sed 's/^/ /;s/ 0*\([0-9]\)/ \1/g;s/^ //'
0847名無しさん@お腹いっぱい。2009/05/26(火) 13:06:05
いまどきのsedなら\bあるんじゃね?

sed 's/\b0*\([0-9]\)/\1/g'
0848名無しさん@お腹いっぱい。2009/05/26(火) 14:14:49
いまどきの sed とぼかさずに、はっきり GNU sed と言ったら?
0849名無しさん@お腹いっぱい。2009/05/26(火) 17:51:35
sedだと改行が難しいんですよねー

ところで、文章が書き込まれているテキストファイルを1行に1文字づつに変換するには
どのコマンドを使用するべきだと思います?
0850名無しさん@お腹いっぱい。2009/05/26(火) 18:00:32
>>849

fold -1
0851名無しさん@お腹いっぱい。2009/05/26(火) 18:25:19
>>850

ファイルに出力したくなかったので助かりました、ありがとうございます
0852名無しさん@お腹いっぱい。2009/05/26(火) 22:09:36
質問です。 bash です。

ls コマンドが次のように定義されています。
ls ()
{
/bin/ls ${1+"$@"}
}

わざわざ ${1+"$@"} にしている理由は何でしょうか?
/bin/ls "$@" にした時との差異がわかりません。
0853名無しさん@お腹いっぱい。2009/05/26(火) 22:38:27
古いshでは引数が与えられていない時の
command "$@"はcommand ""と同じだった。それを避けるための記法。
0854名無しさん@お腹いっぱい。2009/05/26(火) 22:38:35
bashで質問なのですがこういうタブ区切りのファイルがあります。
AAAA(タブ)BBBB(タブ)CCCC
DDDD(タブ)EEEE(タブ)FFFF

このファイルを1行ずつ読み込んでタブ区切りで分割し
配列に取り込みたいのですがどうやればいいんでしょうか?

自分が考えたのが次のようなやり方だったんですが
どうもうまく行きません。
while read LINE;do
DATA1=`echo $LINE | cut -f 1`
DATA2=`echo $LINE | cut -f 2`
done
データにはスペースが入ることもあるのでどうしてもタブで分割させたいんですが、
いいやり方ってないでしょうか?
0855名無しさん@お腹いっぱい。2009/05/26(火) 22:51:26
>>854
echo "$LINE"
というオチか

ダブルクォートが無いと、echoした時、せっかくのタブがスペースになってしまう。
08568522009/05/26(火) 23:07:25
>>853
ありがとうございます。
納得しました。
08578542009/05/26(火) 23:35:03
>>855
そんな簡単な理由だったとは・・・orz
ありがとうございます!明日早速試してみます
0858名無しさん@お腹いっぱい。2009/05/27(水) 02:02:24
ファイルの3行目から10行目を表示というのをかっこよく書くとどうなりますか?
0859名無しさん@お腹いっぱい。2009/05/27(水) 05:49:52
head foo | tail -n 8
かっこよくないなぁ
0860名無しさん@お腹いっぱい。2009/05/27(水) 06:44:54
>>859
では、10行未満のときにうまくいかないことに気がついた。
head foo | tail -n +3
でも、かっこわるいなぁ
0861名無しさん@お腹いっぱい。2009/05/27(水) 06:48:34
>>858
sed -n 3,10p
0862名無しさん@お腹いっぱい。2009/05/28(木) 02:16:45
そろそろスレ違い。

http://pc12.2ch.net/test/read.cgi/unix/1085730992/
sed
0863名無しさん@お腹いっぱい。2009/05/28(木) 03:16:01
そろそろ?
0864名無しさん@お腹いっぱい。2009/05/29(金) 17:19:16
tar: 空の書庫作成はご容赦願います

日本語のエラーメッセージ見て久々に吹いたw
こんな事になったのはいつからだ?

少し前は、どうしても空の書庫を作ろうとしませんとかだったような気がするが
0865名無しさん@お腹いっぱい。2009/05/29(金) 17:31:42
LC_MESSAGES=C しとけ
0866名無しさん@お腹いっぱい。2009/05/29(金) 17:34:23
おれは rm -f /usr/share/locale/ja/LC_MESSAGES/tar.mo 派。
0867名無しさん@お腹いっぱい。2009/05/30(土) 04:43:29
ja_JPとかで使って便利と思った事が無い。
0868名無しさん@お腹いっぱい。2009/05/30(土) 11:09:28
俺の場合、デフォルトは LC_CTYPE=ja_JP.UTF-8 にして、LANG が ja_JP.UTF-8 に
なってたほうがいいアプリには個別対応してる。
0869名無しさん@お腹いっぱい。2009/05/30(土) 11:10:42
.xinitrc で ja_JP.UTF-8 にしてる
0870名無しさん@お腹いっぱい。2009/05/31(日) 00:49:43
>>845
もとの質問の「仕様」が不明確?どこが?

例として10個もデータ載せてて0-9とスペース(タブ?)しか使って無いんだから
1001 とかの考慮は必要だろうけど、A00B なんて何勝手に仕様追加してるの?

もしそういうのもあるなら質問者も10個のデータ内、1つ位はそんなデータを載せるだろうよ

汎用性を考えるのは重要だけど元々無い仕様を勝手に追加して、
それに対応する方法を自分で書くならまだしも、人が書いた事を否定するだけって、何の意味があるの?
0871名無しさん@お腹いっぱい。2009/05/31(日) 09:08:48
一桁目だけ取り出す/余計な0を削除する。
実際のデータが例示されたものだけならどちらでも動くが、仕様は二通り考えられる。

今回の質問はそれほど不明確では無かったが、不明確な質問しといて後から
条件追加するアフォが多すぎるので防衛反応だろう。
0872名無しさん@お腹いっぱい。2009/06/01(月) 12:15:24
aliasでパターンマッチのようなことが出来るシェルってありますか
例えば特定の環境変数を指定した引数の値にセットして
makeを呼び出せるようなことが出来るとありがたい

bash風なシェルだとすると、次のようなイメージ
 alias mak pattern='SOME_ENV_VARIABLE=$(pattern) make'

あるいは、代替案があればご教示頂けると幸いです
0873名無しさん@お腹いっぱい。2009/06/01(月) 12:54:54
bashなら関数定義すりゃいいんじゃねーの?
0874名無しさん@お腹いっぱい。2009/06/01(月) 12:56:06
何言ってるかわからん
0875名無しさん@お腹いっぱい。2009/06/01(月) 13:04:19
function mak () {
local x="$1";
shift;
HOGE="$x" make "$@"
}
0876名無しさん@お腹いっぱい。2009/06/01(月) 13:20:29
>>875
ありがとうございます。快適になりました。
0877名無しさん@お腹いっぱい。2009/06/02(火) 02:01:37
バックグラウンドで実行したコマンドの終了ステータスを取得する方法はありませんか?
例えば、以下の様に実行した command の exit status を実行元のシェルで取得したいのです。

(sleep 3; command >/dev/null 2>&1) &
0878名無しさん@お腹いっぱい。2009/06/02(火) 02:07:33
>>877
>>1
> manや参考リンクを見ましょう。
0879名無しさん@お腹いっぱい。2009/06/02(火) 06:38:35
>>878
できないならできないって答えてやれよ
0880名無しさん@お腹いっぱい。2009/06/02(火) 07:14:37
wait %1
0881名無しさん@お腹いっぱい。2009/06/02(火) 07:23:01
>>880
シェル依存。

バックグラウンドコマンドがすでに終了していると、
wait %1 ではステータスが取れないシェルがある。
0882名無しさん@お腹いっぱい。2009/06/02(火) 08:25:01
何も答えずに回答者の揚げ足とるだけよりマシかと
0883名無しさん@お腹いっぱい。2009/06/02(火) 08:29:38
>>882
いや、一般論としては「できない」が正解。

「できない」とすでに答えてる。
0884名無しさん@お腹いっぱい。2009/06/02(火) 10:01:27
環境書かないなら一般論で答えるしかないな。
0885名無しさん@お腹いっぱい。2009/06/03(水) 02:21:44
バックグラウンドコマンドの終了ステータスをファイルに保存して、参照すればいいんでないの?
0886名無しさん@お腹いっぱい。2009/06/03(水) 08:20:18
実行してるシェルスクリプトが、自身のステータスコードって吐けるの?
0887名無しさん@お腹いっぱい。2009/06/03(水) 09:11:32
この場合は欲しいのはcommandのステータスなんだから

(sleep 3; command >/dev/null 2>&1; echo $? > status) &

で保存できるだろ。
0888名無しさん@お腹いっぱい。2009/06/03(水) 10:27:42
次に実行したコマンドの終了ステイタスで上書きされるから意味が無い。
0889名無しさん@お腹いっぱい。2009/06/03(水) 11:03:05
>>888
そんなのを回避する方法は、お前以外の人間はいくらでも思いつく。
0890名無しさん@お腹いっぱい。2009/06/03(水) 12:08:48
>>887
>>877は、実行してしまったシェルスクリプトを後からどう
にかしたいらしいので、>>887みたいに、実行前にタイムマ
シンで戻ってシェルスクリプトを編集するのは不可じゃない
の?
>>887みたいに$?を使っていいなら、>>877はそもそも質問し
ていないと思うけど。
0891名無しさん@お腹いっぱい。2009/06/03(水) 13:44:26
>>890
質問を普通に読むことができれば、そういう考えには至らない。
0892名無しさん@お腹いっぱい。2009/06/03(水) 13:57:42
>>877はどこ行った?
0893名無しさん@お腹いっぱい。2009/06/03(水) 14:05:09
>>890
なんだ単なるネタか。余りにつまらないんでレスしちまったぜ。
これほど、つまらないネタを見るのは始めてだ。
0894名無しさん@お腹いっぱい。2009/06/03(水) 14:35:20
>>890
もしそういう問題ならシステムコールトレースでも仕掛けておけば
いいんじゃねーの?w
0895名無しさん@お腹いっぱい。2009/06/03(水) 15:24:06
>>887 さんの方法で解決しました。
echoの直前にセミコロンが抜けていますね。
ほかの方の回答は興味がないので無視させていただきました。
0896名無しさん@お腹いっぱい。2009/06/03(水) 15:41:55
では次の質問どうぞ。
0897名無しさん@お腹いっぱい。2009/06/03(水) 18:47:09
抜けてないw
0898名無しさん@お腹いっぱい。2009/06/03(水) 20:24:59
>>897
>直前 >直前 >直前
0899名無しさん@お腹いっぱい。2009/06/03(水) 22:11:34
正規表現でアルファベット6文字というのはどう書けばいいでしょう?
0900名無しさん@お腹いっぱい。2009/06/03(水) 22:17:08
>>899
>>1
>正規表現の話題はスレ違い(正規表現スレへ)
0901名無しさん@お腹いっぱい。2009/06/03(水) 22:21:06
>>900
うす!
0902名無しさん@お腹いっぱい。2009/06/04(木) 01:24:43
>>898
なにそれ?
0903名無しさん@お腹いっぱい。2009/06/06(土) 09:22:29
[を含むテキスト表示で困っています。
solari8 Cシェル環境において以下のシェルスクリプトでテキストに含まれる[]が表示できなくて困っています。
echo `cat fileA`
fileAの中身は下記です。
1234[aa]
このまま表示したいのですが、実行すると「echo:一致しません」と表示されます。
fileAの中身を"1234[aa]"でも1234\[aa\]にしても変わりません。
echo文は変えられないので何とかfileAの中身を工夫して1234[aa]と表示できる方法をどなたかご教示いただけないでしょうか?
0904名無しさん@お腹いっぱい。2009/06/06(土) 10:47:36
> fileAの中身を工夫して1234[aa]と表示できる方法
そんな方法は無い。不可能。絶対に無理。
0905名無しさん@お腹いっぱい。2009/06/06(土) 11:55:02
csh% echo "`cat fileA`"
はどうなの?
0906名無しさん@お腹いっぱい。2009/06/06(土) 12:52:52
>>905
>echo文は変えられないので
0907名無しさん@お腹いっぱい。2009/06/06(土) 13:49:29
>>903
シェルを変えろ。話はそれからだ。
0908名無しさん@お腹いっぱい。2009/06/06(土) 14:02:49
echoのソースを八苦するしか無いなw
0909名無しさん@お腹いっぱい。2009/06/06(土) 14:04:46
>>903
alias echo 'cat'
0910名無しさん@お腹いっぱい。2009/06/06(土) 14:21:02
cshの話題だから敢えて無視してたけど、
マジレスするとechoより前に set noglob すればOK
ただし、そのスクリプト自体変更できないと言うなら不可能。
0911名無しさん@お腹いっぱい。2009/06/06(土) 16:03:34
903です。
皆様ありがとうございます。
スクリプト自体を変更できないのです。^^;
残念ながらあきらめるしかないのですね。
お手数ですが、不可能な理由をご教示願えないでしょうか?
0912名無しさん@お腹いっぱい。2009/06/06(土) 16:04:05
出来ないように作られているから。
0913名無しさん@お腹いっぱい。2009/06/06(土) 18:53:00
#!/bin/csh とか -f を付け忘れてるスクリプトなら、.cshrc でなんとかなるかも
0914名無しさん@お腹いっぱい。2009/06/06(土) 23:31:54
そこまでcshでがんばる理由も無いと思うけどね。乙。
0915名無しさん@お腹いっぱい。2009/06/08(月) 22:21:18
abcdefg を
a
b
c
d
e
f
g
と表示する方法ありますか?
0916名無しさん@お腹いっぱい。2009/06/08(月) 22:27:37
>>915
>>850
0917名無しさん@お腹いっぱい。2009/06/10(水) 02:11:49
パスを変えてecho -> /bin/cat を優先させるという
0918名無しさん@お腹いっぱい。2009/06/10(水) 14:51:51
内部コマンドじゃないの?
0919名無しさん@お腹いっぱい。2009/06/10(水) 15:08:27
>>909 = >>917 は根本的に勘違いしてる。
たとえechoが内部コマンドじゃなかったとして、
echoをcatにすり替えることができたとしても、

>>903
> echo `cat fileA`
は、

cat `cat fileA`

になるだけ。これでは何の解決にもなっていない。
0920名無しさん@お腹いっぱい。2009/06/11(木) 00:03:40
何が目的で
cat fileA
じゃなくて
echo `cat fileA`
としてるのか問い詰めたい
0921名無しさん@お腹いっぱい。2009/06/11(木) 00:10:30
cat fileAと
echo `cat fileA`
は明らかに異なるが。どうして同一だと考えられるのだろう。
問い詰めたい。問い詰めたい。問い詰めたい。問い詰めたい。
0922名無しさん@お腹いっぱい。2009/06/11(木) 00:58:46
>>903
これってうちのtcsh 6.15.00だと再現しないんだけど純正csh限定なの?
0923名無しさん@お腹いっぱい。2009/06/11(木) 09:57:44
debianのパッケージで入れたcshでも再現しないな。パッケージのバージョンは
20070713-2となっているが元がどういうのかはよくわからない。

どういう仕組みでそうなるんだろうか。solarisのcshに独自の何かがある?
レス数が900を超えています。1000を超えると表示できなくなるよ。