トップページunix
988コメント297KB

シェルスクリプト総合 その24©5ch.net

■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。 転載ダメ©2ch.net2014/11/11(火) 00:54:03.43
シェルスクリプトの総合スレです。
□お約束
・特記なき場合はBourne Shell(/bin/sh)がデフォルトです。
 bash/zsh/ksh/ashなどに依存する場合は明示しましょう。
 Linuxユーザは/bin/shの正体がbashまたはdashなので特に注意。
 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でそれらしい単語による簡単な検索もできます。
・シェルで使えるワイルドカード等は正規表現ではありません。
 正規表現の話題はスレ違い(正規表現スレへ)
・シェルスクリプトのことをシェルってゆーな
□初心者へのアドバイス:
・適した道具を判断するのも頭の重要な使い方。シェルスクリプトよりも
 awkまたはperlの方が適した処理にはそちらを使いましょう。
・知らないコマンドが出てきたらmanを引きましょう。
・思い通りに動かないときは、まずは sh -x でトレースしましょう。
□回答者への注意事項:
・シェルスクリプトでの処理方法を質問しているのに、よくわからずに
 「そういうのはperl使いましょう」と回答するのはやめましょう。
 安易にperlに逃げずにシェルスクリプトで処理するのが頭のいいやり方。
前スレ
シェルスクリプト総合 その23
http://peace.2ch.net/test/read.cgi/unix/1404204950/
0193名無しさん@お腹いっぱい。2015/01/01(木) 18:29:20.31
興味があったのでちょっと検索してみた。
ガイドラインというのはわからないが、こんな感じで使われてるね〜みたいのなら、

http://catb.org/~esr/writings/taoup/html/ch10s05.html

> The -a to -z of Command-Line Options
>
> Over time, frequently-used options in well-known Unix programs have established a loose sort of semantic standard
> for what various flags might be expected to mean. The following is a list of options and meanings that should prove
> usefully unsurprising to an experienced Unix user:

http://www.gnu.org/prep/standards/html_node/Option-Table.html

> 4.9 Table of Long Options
>
> Here is a table of long options used by GNU programs. It is surely incomplete, but we aim to list all the options that
> a new program might want to be compatible with. If you use names not already in the table, please send
> bug-standards@gnu.org a list of them, with their meanings, so we can update the table.
0194名無しさん@お腹いっぱい。2015/01/01(木) 20:15:18.38
>>191-193
サンキュー

URL先の情報にぴったりのオプション見つからないから
-h を少し書いて後々忘れた時に備えて、
デフォルトでクリップボードで検索、
引数あるときはそれで検索にする
0195名無しさん@お腹いっぱい。2015/01/01(木) 22:28:20.83
両方用意すればいいんじゃない?
自分の名前がgglかgglcかで動作が変わるのも面白そう。
0196名無しさん@お腹いっぱい。2015/01/01(木) 22:31:09.64
名前同じで動作変わるとmanの括弧書きの数字が増えてややこしいみたいな?
0197名無しさん@お腹いっぱい。2015/01/03(土) 21:18:53.70
そういやgetopt(3)ってPOSIXで規定されてるんだね。いまどきの
*BSD, Linuxならlibcで持ってるものなんだな。

とあるソフトがGNUのgetopt.cを同梱しているので消してやりたいと思って
いたんだけど、configureでgetoptの存在チェックしてlibcの方を優先して
使わせるようにするのがいいのかな。
0198名無しさん@お腹いっぱい。2015/01/08(木) 11:56:42.54
「とあるソフト」がGPLなら、一部を削除するのはライセンス違反。
0199名無しさん@お腹いっぱい。2015/01/08(木) 12:01:18.92
>>198
なんで?
0200名無しさん@お腹いっぱい。2015/01/08(木) 12:15:36.60
GPL V3
4. Conveying Verbatim Copies.
5. Conveying Modified Source Versions.
0201名無しさん@お腹いっぱい。2015/01/08(木) 13:17:19.27
>>200
詳しく
0202名無しさん@お腹いっぱい。2015/01/08(木) 18:53:35.81
質問です
22, 32, 33, 45,
12, 47, 78, 44, 32,
...
数字がカンマで区切って700個書いてあるファイルがあります。
一行に数字が何個あるか規則性はありません。
このファイルを読み込んで数字を100個ずつ出力して7枚のファイルを
作りたいと思っています。シェルスクリプトでうまくできますでしょうか。
出力されたファイルには数字が一列で入っているほうがいいです。
お願いします。
0203名無しさん@お腹いっぱい。2015/01/08(木) 19:41:16.46
GNU awk 限定

awk -v RS='' -v FPAT='( *[0-9]+, *\n?){1,100}' \
'{
for(i=1;i<=NF;i++){
gsub(" *\n"," ",$i);
gsub(", *$","",$i);
print $i > i ".txt";
}
}' a.txt

上手く行けば 1.txt ... 7.txt というファイルができるはず
0204名無しさん@お腹いっぱい。2015/01/08(木) 20:20:07.70
gawk じゃなくてふつーの awk で。

awk -v RS=, '{print $0+0 > int(NR/100)+1 ".txt" }'
0205名無しさん@お腹いっぱい。2015/01/08(木) 20:36:37.66
int((NR-1)/100)+1 じゃないとダメだった。
02062032015/01/08(木) 20:51:41.18
あ、カンマはいらないのね
02072032015/01/08(木) 20:56:03.24
なおかつ1列を1行と読み間違えていた(´・ω・`)ショボーン
0208名無しさん@お腹いっぱい。2015/01/08(木) 21:09:50.76
ファイル分割が有るし、awkでやる方が良いだろうけど、sedで
見易さの為-r付けてます

#!/bin/sh
sed -re '
 :loop;
 $! {
  N;
  b loop;
 }

 s/,[ \n]+/, /g;
 s/([0-9]+, ){100}/&\n/g;
' | {
 i=1
 while read line
 do
  echo "$line" > "$(( i++ )).txt"
 done
}
0209名無しさん@お腹いっぱい。2015/01/08(木) 21:43:46.83
awkもsedも出ちまったか

tr -d '\r\n' < file
0210名無しさん@お腹いっぱい。2015/01/08(木) 21:52:48.42
set -- `sed 's/,/ /g' input.txt`
i=1
while [ $i -le 7 ]; do
(j=1; while [ $j -le 100 ]; do echo "$1"; shift; done) > $i.txt
02112092015/01/08(木) 21:57:31.95
ミス

tr -d '\r\n' < file | tr ',' '\n' | split -l 100
0212名無しさん@お腹いっぱい。2015/01/08(木) 21:58:20.67
考えてる途中で送っちゃった。やり直し

set -- `sed 's/,/ /g' input.txt`
i=1
while [ $i -le 7 ]; do
(j=1; while [ $j -le 100 ]; do echo "$1"; shift; j=$((j + 1)); done) > $i.txt
shift 100
i=$((i + 1))
done
02132092015/01/08(木) 22:01:45.08
>>212
お前は俺か
0214名無しさん@お腹いっぱい。2015/01/08(木) 23:07:34.58
/ *, */を改行に変換してhead
0215名無しさん@お腹いっぱい。2015/01/09(金) 00:45:24.74
#!/bin/sh
file=`cat "$1"`
for i in `seq 1 7`; do
for j in `seq 1 100`; do
echo -n ${file%%,*}, >>$i.txt
file=${file#*,}
done
done
0216名無しさん@お腹いっぱい。2015/01/09(金) 01:53:20.06
GNU grep and GNU parallel

$ grep -Po '[0-9]+' data.txt | parallel --pipe -L 100 -n 1 -k 'cat - > {#}.txt'
0217名無しさん@お腹いっぱい。2015/01/09(金) 01:59:25.49
211と216を足して

$ grep -o '[0-9]\+' data.txt | split -l 100
02182022015/01/11(日) 18:59:23.53
>>203-217
ありがとうございます。本当に助かりました。
勉強不足を痛感。向上心を刺激されました。
0219名無しさん@お腹いっぱい。2015/01/14(水) 13:42:56.50
$SEARCH に入れても awkが動いてくれません
{}が引っかかってしまったのだろうか? どうすればよいのだろうか?

while true
do read SEARCH
awk 'BEGIN{RF="---"}/${SEARCH}/' $save_to
done
0220名無しさん@お腹いっぱい。2015/01/14(水) 13:55:03.85
シングルクォートで囲まれてるから置換されないのよ
0221名無しさん@お腹いっぱい。2015/01/14(水) 14:41:45.54
>>220
多少書き換えてみました
しかし、まだ動きません

clp.sh
do read SEARCH
export SEARCH
awk -f ~/sbin/h_Searher.awk $save_to
done

~/sbin/h_Searher.awk
BEGIN{RF="---"}/$SEARCH/
0222名無しさん@お腹いっぱい。2015/01/14(水) 17:08:45.99
perlで書いてしまった
たった1行のためにつまずくとは悔しい

do
 perl ~/Perl_instance/clp.pl
done


~/Perl_instance/clp.pl
open FH, '<', '$save_toと同じファイル';
my @LOG = <FH>;
close FH;

my $sentence = join ' ', @LOG;
my @field = split /---/, $sentence;

# my $search = "Ano";
chomp(my $search = <STDIN>);
for my $lines (@field) {
  if ( $lines =~ m/${search}/ ) {
    print "---\n";
    print "$lines\n";
  }
}
0223名無しさん@お腹いっぱい。2015/01/15(木) 10:05:06.27
>>219
awk 'BEGIN{RF="---"}/'${SEARCH}'/' $save_to
0224名無しさん@お腹いっぱい。2015/01/15(木) 12:37:55.02
>>223
thanks!
0225名無しさん@お腹いっぱい。2015/01/15(木) 13:19:56.10
そして、$SEARCHにインジェクションされましたとさ。
0226名無しさん@お腹いっぱい。2015/01/15(木) 18:30:18.23
GNU awk ならこんなのも

awk -v SEARCH="$SEARCH" 'BEGIN{RF="---"}/SEARCH/' $save_to
0227名無しさん@お腹いっぱい。2015/01/20(火) 01:40:59.45
こんな雑誌があることを初めて知った。
なんと月刊で20号以上出ているということにも驚いた。

シェルスクリプトマガジン vol.21
http://www.amazon.co.jp/dp/4904807154/
https://www.usp-lab.com/pub.magazine.html
0228名無しさん@お腹いっぱい。2015/01/20(火) 05:22:18.17
その雑誌の半分はシェルスクリプト関係ない内容だから相当ネタがないんだろなって思った
0229名無しさん@お腹いっぱい。2015/01/21(水) 01:45:14.76
ツールドフランスの実況が森の景色の解説になってるようなもんか
0230名無しさん@お腹いっぱい。2015/01/22(木) 16:29:19.37
コマンドラインから手入力するとちゃんと動くスクリプトが、cronからだと動かない。
数日悩んだ結果。。。原因はLANGだった
0231名無しさん@お腹いっぱい。2015/01/22(木) 16:32:53.58
ルンゲの罠
0232名無しさん@お腹いっぱい。2015/01/22(木) 16:48:29.41
>>230
まれによくある。

スクリプトの先頭付近でLANGを設定しちゃうことも多いんだけど、Unix的でクールな
ポータビリティのある手法を紹介してくれる偉い人が出てくるのを正座して待ちたい。
0233名無しさん@お腹いっぱい。2015/01/22(木) 17:14:56.12
LANG=C
0234名無しさん@お腹いっぱい。2015/01/23(金) 06:42:51.72
偉い人が
 共通したものは crontab 先頭で、タスク毎のは env NAME=VALUE COMMAND
と答えるか、もうまるっきり答えないと予想した
0235名無しさん@お腹いっぱい。2015/01/23(金) 10:00:16.40
共通したものは crontab 先頭で、タスク毎のは env NAME=VALUE COMMAND
0236名無しさん@お腹いっぱい。2015/01/23(金) 16:52:05.70
偉い人のコピペ北ー!
自演っぽくて、コメントしづらい輪
0237名無しさん@お腹いっぱい。2015/01/23(金) 17:30:03.53
この話はここで終わりって暗に言ってるんだろう
0238名無しさん@お腹いっぱい。2015/01/24(土) 10:11:24.87
LANG=C sl
的な書き方ってどこまで有効なのかな?
bashだけ?
0239名無しさん@お腹いっぱい。2015/01/24(土) 10:23:49.81
>>238
bourne shell でも使える
0240名無しさん@お腹いっぱい。2015/01/24(土) 15:26:45.88
配列の命名規則ってある?
0241名無しさん@お腹いっぱい。2015/01/24(土) 15:41:53.70
ない
02422402015/01/25(日) 04:39:03.74
みんなはどうしてる?
しっくりくる表記法がないんだけど
0243名無しさん@お腹いっぱい。2015/01/25(日) 05:18:01.83
しっくりこない表記がワカラナイ
0244名無しさん@お腹いっぱい。2015/01/25(日) 11:18:23.60
配列は邪教
使わないので規則などない
0245名無しさん@お腹いっぱい。2015/01/25(日) 11:45:02.72
>>244
同意
0246名無しさん@お腹いっぱい。2015/01/25(日) 12:36:31.55
配列って変数名に連番を入れたりして使うことかと思ってたw
0247名無しさん@お腹いっぱい。2015/01/25(日) 13:47:36.00
>>244,245
じゃあ代わりにどうすればよいのだ?
まさかコピペ?
0248名無しさん@お腹いっぱい。2015/01/25(日) 17:38:43.45
ポインタとか言い出すと見た
0249名無しさん@お腹いっぱい。2015/01/25(日) 19:40:14.84
あほらし

> じゃあ代わりにどうすればよいのだ?
> ポインタとか言い出すと見た
いかにも、めんどくさそう
0250名無しさん@お腹いっぱい。2015/01/25(日) 19:46:57.10
会話するネタがないんだなぁ……
0251名無しさん@お腹いっぱい。2015/01/25(日) 21:21:36.60
じゃあおれからネタ
xargsコマンドが好き。無理だと思ってた処理がワンライナーになる
いっそ、powershellみたいにjsonパイプラインみたいなのがあればいいのにって思う
0252名無しさん@お腹いっぱい。2015/01/25(日) 22:41:49.00
俺がよく使うのはfind ... | xargs grep だったかな
他どんな場面で使うっけ
0253名無しさん@お腹いっぱい。2015/01/25(日) 23:37:38.84
\ls -1t *.* |head -3|xargs head
0254名無しさん@お腹いっぱい。2015/01/26(月) 12:06:00.33
>>235

*.*の3行が、headへの標準入力じゃなくて、引数として与えられるのか。
おもしろいなあ。
0255名無しさん@お腹いっぱい。2015/01/26(月) 20:35:10.75
xargs で何か面白い事は無いかと、あれこれ考えた結果
ループになる
xargs loop で検索したら結構見つかるので
珍しくは無いんだろうが、まあ、一応

<<EOF xargs -I i sh -c 'seq 3 | xargs -I j echo i j'
foo bar
baz qux quux
corge
grault
EOF
0256名無しさん@お腹いっぱい。2015/01/27(火) 02:26:05.37
xargs は並列処理でもよく使うかな
例えば find ... | xargs -P 12 -n 16 gzip とすると12プロセスがファイルの圧縮を行う
0257名無しさん@お腹いっぱい。2015/01/27(火) 03:09:32.08
\nをファイル名に仕込まれて爆死する
0258名無しさん@お腹いっぱい。2015/01/27(火) 06:47:01.92
find ... -print0 | xargs ... -0 ... ってしとけばええやん…
0259名無しさん@お腹いっぱい。2015/01/27(火) 07:02:05.92
\0をファイル名に仕込まれて(ry
0260名無しさん@お腹いっぱい。2015/01/27(火) 07:38:50.39
仕込めるんだっけ?
0261名無しさん@お腹いっぱい。2015/01/27(火) 08:17:49.81
find ‥ -print0 を知らん奴もいるんだな w
0262名無しさん@お腹いっぱい。2015/01/27(火) 08:20:05.07
>>260
API だと思い付かない
ディスクを直接バイナリ編集すれば可能かも
0263名無しさん@お腹いっぱい。2015/01/27(火) 08:25:13.28
>>261
実装によってはないのよ
0264名無しさん@お腹いっぱい。2015/01/27(火) 08:28:26.16
solarisにはまだない
0265名無しさん@お腹いっぱい。2015/01/27(火) 12:18:24.66
>>263
移植すりゃいいじゃん
0266名無しさん@お腹いっぱい。2015/01/27(火) 12:56:34.51
大抵は
-exec {} +
で用が足りる
0267名無しさん@お腹いっぱい。2015/01/27(火) 13:01:19.27
>>262
カーネル内でもファイル名は0終端で扱ってるから無理だね
実際のサイズと異なる事でカーネルクラッシュなどまずいことが発生する可能性は
あるけど、それは普通にカーネル内バグ
0268名無しさん@お腹いっぱい。2015/01/27(火) 13:29:38.19
>>265
そういう話じゃないよ
0269名無しさん@お腹いっぱい。2015/01/27(火) 13:41:29.10
>>268
半分冗談だよ、いちいち気にしてたら禿げるぞ
0270名無しさん@お腹いっぱい。2015/01/27(火) 13:43:51.02
冗談に見えないし、
冗談だとしても面白くないよ
0271名無しさん@お腹いっぱい。2015/01/27(火) 15:15:56.23
大抵は
-exec \{\} +
とエスケープなりクォートで囲むなりするのを忘れる
0272名無しさん@お腹いっぱい。2015/01/27(火) 16:27:07.47
{}をquoteしなきゃならないカタワ専用シェルって何?
0273名無しさん@お腹いっぱい。2015/01/27(火) 21:10:27.07
-execはなんか怖いんだよなぁ
理由はないんだけど
0274DAEMON2015/01/27(火) 21:45:21.58
>>272
 シ
タッ・・(Φ Φ+)・・・ 恐らく Perl です
0275DAEMON2015/01/27(火) 22:02:58.78
>>274
 シ
タッ・・(Φ Φ+)・・・ 例えば、基礎公文で…

while (test) {
       open test-file.txt(filehandle) ,
          ">test-file.pl"
       print test-file.txt
    close test-file.txt
}

斯様な様にですか…
0276名無しさん@お腹いっぱい。2015/01/28(水) 00:14:24.97
>>271
で、{}をクォートする必要があるシェルって何?
0277名無しさん@お腹いっぱい。2015/01/30(金) 19:56:12.76
wait入れるsleepだが、引数が整数だけだろと思ってたら、整数じ
ゃなくてもいいというので、0.1入れてやってみたら、ほんとに動
作してるっぽい。manには何も書いておらん。つかえねーman
0278名無しさん@お腹いっぱい。2015/01/30(金) 20:00:01.61
うちのsleepはGNUだけど man sleep すると info 見ろって書いてあって、info 見たら:
Historical implementations of `sleep' have required that NUMBER be
an integer, and only accepted a single argument without a suffix.
However, GNU `sleep' accepts arbitrary floating point numbers (using a
period before any fractional digits).
0279名無しさん@お腹いっぱい。2015/01/30(金) 21:57:35.82
>>278

おお、サンクス
0280名無しさん@お腹いっぱい。2015/01/31(土) 12:09:54.06
>>273
客先環境での操作なんかだとおおいにある
xargsなら、-pとか-tがあるので安心
0281名無しさん@お腹いっぱい。2015/01/31(土) 13:19:36.31
>>280
同意が得られて異端じゃないと安心出来た
尚就職してから今まで客先環境でしか働いたことがない模様
0282名無しさん@お腹いっぱい。2015/01/31(土) 17:47:20.57
こうじゃなくて
v=${v:-default}

こうでしょ
: ${w:=default}

っていうの有りますか?皆さんの、そういうの教えて下さい
0283名無しさん@お腹いっぱい。2015/02/01(日) 00:46:16.74
こうじゃなくて
echo -e 'hoge\nfuga'

こうでしょ
printf 'hoge\nfuga\n'
0284名無しさん@お腹いっぱい。2015/02/01(日) 00:47:04.51
俺はecho派
0285名無しさん@お腹いっぱい。2015/02/01(日) 07:05:52.05
公文い公文
0286名無しさん@お腹いっぱい。2015/02/01(日) 13:49:52.79
echo は -e が必要だったり不要だったりモノによってバラバラなんで printf だなぁ。
OSX の /bin/sh は bash だけど、同じ bash のはずなのに
bash -c "echo -e 'hoge\nfuga'" と sh -c "echo -e 'hoge\nfuga'" で
結果が違うとかめんどくさすぎる。
0287名無しさん@お腹いっぱい。2015/02/01(日) 18:28:40.97
似た様なのだけど、

こうじゃなくて
function f () {
echo hoge hoge
}

こうでしょ
f () {
echo hoge hoge
}
0288名無しさん@お腹いっぱい。2015/02/01(日) 19:10:32.63
個人的には上なんだけど
最近やってるのがjavascriptだからかな
0289名無しさん@お腹いっぱい。2015/02/02(月) 10:43:19.51
変数は大文字か小文字か。
個人的には環境変数と区別するために小文字なんだけど、
社内の他の人が書いたのを見ると大文字ばっかりなんだよな。
0290名無しさん@お腹いっぱい。2015/02/02(月) 12:18:06.01
いつexportしても問題が出ないような命名規則なら問題無しw
0291名無しさん@お腹いっぱい。2015/02/02(月) 21:56:58.79
質問です。
linux mint 17.1 でコマンドの練習してるのですが、
% ls -l
だと色々ずらーっと出るんですけど、本に書いてあるとおり、
ソートコマンドを練習しようとして
% ls -l | sort +4
と打ち込んでファイルサイズで降順ソートしたかったのですが
sort: cannot read: +4: そのようなファイルやディレクトリはありません
と出てしまいます。
bashですが、シェルの種類によってはこのオプション使えないんでしょうか。
-r等は正常に動作します。
0292名無しさん@お腹いっぱい。2015/02/02(月) 22:04:13.81
sort -k4
sort -k4r
0293名無しさん@お腹いっぱい。2015/02/02(月) 22:34:00.27
で、できました!有り難うございます!
■ このスレッドは過去ログ倉庫に格納されています