シェルスクリプト総合 その26at UNIX
シェルスクリプト総合 その26 - 暇つぶし2ch946:名無しさん@お腹いっぱい。
18/05/02 22:47:14.90 .net
>>920
それだと前からn個以降は実現可能だけど
範囲ができないんですよね。

947:名無しさん@お腹いっぱい。
18/05/02 22:51:49.30 .net
bashだとこんな感じですね
foo() { echo "${@:2:3}"; }
$ foo 1 2 3 4 5
2 3 4

948:名無しさん@お腹いっぱい。
18/05/03 00:40:42.42 .net
>>921
for文使えば?
selectargnum()
{
fromargnum=$1
toargnum=$2
shift ${fromargnum}
for arg in $(seq $((toargnum - fromargnum + 1))); do
printf '%s\n' "$2" && shift
done
}
selectargnum 3 5 "$@"
注意: シェル函数への第1,2引数は必ず非負整数で,引数の範囲内であるべし。

949:名無しさん@お腹いっぱい。
18/05/03 00:47:51.26 .net
#! /bin/sh -
selectargnum()
{
fromargnum=$1
toargnum=$2
shift ${fromargnum}
for arg in $(seq $((toargnum - fromargnum + 1))); do
printf '%s\n' "$2"
shift
done
}
selectargnum 2 4 "$@"
もうちょっと親切に書くわ。
シェル函数selectargnumの
::仕様::
selectargnum <開始位置> <終了位置> <(処理したい)引数>
開始位置・終了位置は省略不可で,常


950:識的な範囲であることを前提にしている。 ::使い方:: 上のコードを適当な名前のファイル(例えばselarg.sh)に保存して実行権限を賦与。 $ chmod +x ./selarg.sh あとはファイル中のselectargnum函数の第1,2引数を書き換えて使える。 上の例なら $ ./selarg.sh "第1引数" "第2引数" "第3引数" "第4引数" "第5引数" に対して 第2引数 第3引数 第4引数 という出力が得られる。



951:名無しさん@お腹いっぱい。
18/05/03 00:50:36.20 .net
seqを除いてPOSIX準拠。
もしもより厳密にPOSIXに従いたければ当該箇所を
seq $((toargnum - fromargnum + 1))
から
yes | head -n $((toargnum - fromargnum + 1))
としてもいいだろう。

952:名無しさん@お腹いっぱい。
18/05/03 03:17:05.15 .net
>>922のせいで勘違いさせたようですね
> 別の関数の引数に渡すのってどうやればいいだろうか?
重要なのはこれ
another_function() {
for i in "$@"; do
printf "%s\n" "$i"
done
}
foo() { another_function "${@:2:3}"; }
another_functionはそのまま使って、
fooの部分をPOSIX準拠にして
以下のような出力を得たいということです
$ foo a "b 1" "c 1" d e
b 1
c 1
d

953:名無しさん@お腹いっぱい。
18/05/03 03:18:03.35 .net
eval使うしか無いっすかね?

954:名無しさん@お腹いっぱい。
18/05/03 03:20:16.97 .net
このコードの応用でできますかね?
いまいちこのコードがなにやってるのかよくわからんのですが
URLリンク(unix.stackexchange.com)
for arg do
shift
[ "$arg" = "-inf" ] && continue
set -- "$@" "$arg"
done
printf '%s\n' "$@"

955:名無しさん@お腹いっぱい。
18/05/03 03:42:12.53 .net
>>926
おいおいヒドいな俺の>>923-925は無視かよ
引数をどうにかしたいコマンドをsomefuncとして
#! /bin/sh -
selectargnum()
{
fromargnum=$1
toargnum=$2
shift ${fromargnum}
for arg in $(yes | head -n $((toargnum - fromargnum + 1))); do
printf '%s\n' "$2"
shift
done
}
somefunc()
{
printf '%s\t%s\n%s\n' "$2" "$3" "$1"
}
somefunc $(selectargnum 2 4 "$@")
こういうので実現できると思うんだが?
なにかこれでは駄目な点があれば言ってくれ。
せっかくGW中とは言え頭使ったのにあまりにもあまりな仕打ちじゃマイカ

956:名無しさん@お腹いっぱい。
18/05/03 04:08:41.64 .net
>>929
somefuncは分かりづらいんでこう書き換えるけど
somefunc() {
printf '%s\n' "$@"
}
$ test.sh "a" "b" "c" "d" "e"
b
c
d
こうなるところ
$ test.sh "a 1" "b 1" "c 1" "d 1" "e 1"
b
1
c
1
d
1

957:名無しさん@お腹いっぱい。
18/05/03 04:23:08.37 .net
somefuncはこうしないとだめだな。
何番目の変数に入っているのか分かりづらい
somefunc() {
printf '1: %s\n' "$1"
printf '2: %s\n' "$2"
printf '3: %s\n' "$3"
}

958:名無しさん@お腹いっぱい。
18/05/03 04:23:43.87 .net
なんかすごいどうでもいいことしてる気にならん?

959:名無しさん@お腹いっぱい。
18/05/03 04:26:07.99 .net
しょうがないだろう。
引数には空白、シングルクォート、ダブルクォート、改行が
含まれる可能性があるんだよ

960:名無しさん@お腹いっぱい。
18/05/03 04:29:26.87 .net
一見うまくいったと思いきや
$ test.sh "a" "b" "c" "d" "e"
1: b
2: c
3: d
変数Aに改行が含まれている文字列を入れ
$ A="b
b
b
b
"
以下のように実行するとおかしくなる
$ test.sh "a" "b${A}b" "c" "d" "e"
1: bb
2: b
3: b
> なにかこれでは駄目な点があれば言ってくれ。
駄目な点を言った

961:名無しさん@お腹いっぱい。
18/05/03 04:32:29.46 .net
なお、俺が書いたコードだと以下のように正しく出力される
$ test.sh "a" "b${A}b" "c" "d" "e"
1: bb
b
b
b
b
2: c
3: d
>>928を参考にして以下のように書いた
selectargnum() {
func=$1 start=$2 length=$3
shift 3
i=0 last=$((start+length))
for arg in "$@"; do
: $((i+=1))
[ $i -gt $length ] && shift
[ $i -ge $last ] && continue
shift
set -- "$@" "$arg"
done
$func "$@"
}
somefunc() {
printf '1: %s\n' "$1"
printf '2: %s\n' "$2"
printf '3: %s\n' "$3"
}
selectargnum somefunc 2 3 "$@"

962:名無しさん@お腹いっぱい。
18/05/03 04:34:38.30 .net
ただ問題は、>>935のコードを書いた俺自身が
なんでこのコードで動くのかよく分かってない所だなw
誰か俺の書いたコードが何をやってるのか教えてくれw
>>928のコードはなにやら引数を一周させているみたいだ。
俺が書いたコードは、その一周を途中で中断させているようだな?

963:名無しさん@お腹いっぱい。
18/05/03 04:37:45.65 .net
eval使ったほうが簡潔かつ速い気がしてきたw
set -- の所、何度も引数をずらす処理をしているわけだしね。

964:名無しさん@お腹いっぱい。
18/05/03 04:38:19.15 .net
長い
読む気にならん

965:名無しさん@お腹いっぱい。
18/05/03 04:39:32.30 .net
長くて読まないのはわかるが、
なぜ読まないということをわざわざ宣言するんだろう?

966:名無しさん@お腹いっぱい。
18/05/03 04:42:04.26 .net
まあ長いのは、>>929のコードに合わせたからであって、
メインの処理はこれだけなんだけどね
i=0 start=2 length=3 last=$((start+length))
for arg in "$@"; do
 : $((i+=1))
 [ $i -gt $length ] && shift
 [ $i -ge $last ] && continue
 shift
 set -- "$@" "$arg"
done
printf '1: %s\n' "$1"
printf '2: %s\n' "$2"
printf '3: %s\n' "$3"

967:名無しさん@お腹いっぱい。
18/05/03 05:49:25.62 .net
>>935
ちょっとリファクタリング(ってほど大層じゃないが)
selectargnum() {
 func="$1"; start=$2; length=$3
 shift 3
 i=0; last=$((start + length))
 for arg in "$@"; do
  i=$((i + 1))
  test ${i} -gt ${length} && shift
  test ${i} -ge ${last} && continue
  shift
  set -- "$@" "${arg}"
 done
 "${func}" "${@}"
}

968:名無しさん@お腹いっぱい。
18/05/03 06:31:02.21 .net
>>941
文字増やしてるだけじゃねーかw

969:名無しさん@お腹いっぱい。
18/05/03 06:31:17.96 .net
不要な文字

970:名無しさん@お腹いっぱい。
18/05/03 06:50:55.78 .net
リファクタリングは文字数減らすことを言うのじゃないけど

971:名無しさん@お腹いっぱい。
18/05/03 07:41:52.01 .net
不必要な機能

972:名無しさん@お腹いっぱい。
18/05/03 09:41:05.71 .net
一旦SQLiteにでも格納すれば何でも出来るで

973:名無しさん@お腹いっぱい。
18/05/03 12:57:05.87 .net
なんか余計に読みづらくなっただけのような

974:名無しさん@お腹いっぱい。
18/05/03 13:11:25.55 .net
解こうとしてる問題が間違っていると言ったやろw

975:名無しさん@お腹いっぱい。
18/05/03 13:13:23.38 .net
bashだと簡単にできるようになったことのどこが
間違っているというのだろうか?

976:名無しさん@お腹いっぱい。
18/05/03 13:14:48.71 .net
>>944
> リファクタリングは文字数減らすことを言うのじゃないけど
リファクタリングは文字数を増やすことじゃないって話

977:名無しさん@お腹いっぱい。
18/05/03 13:16:44.77 .net
>>949
問題が間違っているとハッキリ書いとるやろwアホなん?

978:名無しさん@お腹いっぱい。
18/05/03 13:17:25.13 .net
なぜ問題が間違っているというのか?
結論を最初に持ってこないように

979:名無しさん@お腹いっぱい。
18/05/03 13:22:50.10 .net
>>952
あ、それが分からんのかw
引数の意味をパースすれば任意の位置指定でのスライスなど不要やからな
つまりgetoptで十分な問題を間違った角度から解こうとしとるっつー事やw
てかおまえ安価ぐらいできんのか

980:名無しさん@お腹いっぱい。
18/05/03 13:33:39.18 .net
どういう理屈で、引数の意味をパースすれば任意の位置指定での
スライスなど不要になるのでしょうか?

981:名無しさん@お腹いっぱい。
18/05/03 13:41:59.15 .net
>>954
まず安価しろ

982:名無しさん@お腹いっぱい。
18/05/03 13:43:07.07 .net
例えばfindコマンドのように
find . -type f -exec chmod 600 {} \;
-execが来たら、chmodコマンドを;までをオプションとして
渡して実行みたいなのはスライス相当のものがないとできませんね

983:名無しさん@お腹いっぱい。
18/05/03 13:44:07.01 .net
自分がやったことがないことだからって
問題が間違ってるということにはなりませんよ

984:名無しさん@お腹いっぱい。
18/05/03 13:44:46.06 .net
>>953
根本的に何がしたいのかに依るんじゃねーのそれは
引数を解釈したいならgetoptでやるべきだが、今回やりたいのは引数のスライスそのものじゃね?
bashなら一行でできるそれをbash依存せずにやるにはどうすればって話なんじゃないか
まぁなんか妙なのが湧いてて話が無駄に複雑になってる感が否めないが

985:名無しさん@お腹いっぱい。
18/05/03 13:47:13.94 .net
まあ言わないでもわかるでしょうが、
わざとスルーされないように言っておきますと、
-execは残りの引数を全て、指定したコマンドの引数として実行するものではなく
; までを引数とします。だから以下のように複数の-execもしていできます。
find . -type f -exec echo {} \; -exec echo {} \;

986:名無しさん@お腹いっぱい。
18/05/03 13:53:29.10 .net
>>958
位置が固定ならいきなりスライスでも構わんが
今回のやつは任意の位置を指定したいと言っとるやろ
つまりその任意の位置がどこか分かった時点で引数の解析は終わっとるから
必要な引数も選別できているはずなんや
つまりそこからさらに位置指定でスライスしたいというのは
引数解析のアプローチが間違っとるいう訳やな

987:名無しさん@お腹いっぱい。
18/05/03 14:10:06.58 .net
>>960
そして、その選別した引数(複数)を別の関数に渡すんだろ?
配列があれば、配列に選別していった引数を入れていけばいいだろうが
bash依存しないなら、配列は使えないよな。
お前ならどうするんだ?

988:名無しさん@お腹いっぱい。
18/05/03 14:10:06.74 .net
>>960
任意の位置をどう指定するのかが要望ないからそこは>>922みたいな位置の直書きを想定してた
多分位置の指定まで引数に組み込むような汎用性高いものは要求されてないだろう
つまりいきなりスライスでいいと思ってる

989:名無しさん@お腹いっぱい。
18/05/03 14:17:44.04 .net
>>961-962
関数に渡すならその引数に割り当てた変数に保存しとくだけやな
可変個ならevalするやろしw
どっちにしろもっと多くの状況がわからんと最適解は得られんわw

990:名無しさん@お腹いっぱい。
18/05/03 14:21:33.10 .net
>>963
> 関数に渡すならその引数に割り当てた変数に保存しとくだけやな
>>917を読み返してみましょうか?
> 引数 $1 $2 $3 ・・・ のうち、特定の範囲n~mを
> 別の関数の引数に渡すのってどうやればいいだろうか?
> n~mは条件で変わるものとする

その引数に割り当てた変数とはなんですか?

結局↓これですか?
> 934 自分:名無しさん@お腹いっぱい。[sage] 投稿日:2018/05/03(木) 04:37:45.65
> eval使ったほうが簡潔かつ速い気がしてきたw

991:名無しさん@お腹いっぱい。
18/05/03 14:22:57.28 .net
>>964
せやでw
こいつは問題を複雑に考えすぎとるだけやw

992:名無しさん@お腹いっぱい。
18/05/03 14:23:53.17 .net
あれほど問題が間違っていると偉そうなこと言ったくせに
問題は間違ってないってことでいいんだろうな

993:名無しさん@お腹いっぱい。
18/05/03 14:24:26.11 .net
>>965
そっちじゃない。
いきなり問題が間違っているといちゃもんを付けたことに
謝れって言ってる

994:名無しさん@お腹いっぱい。
18/05/03 14:25:12.82 .net
>>966
正確には問題自体を複雑に考えすぎとるやなw
こいつの問題設定自体が間違っとるんやw

995:名無しさん@お腹いっぱい。
18/05/03 14:25:16.94 .net
>>963
> どっちにしろもっと多くの状況がわからんと最適解は得られんわw
最初の質問の>>917に全て書かれてるじゃん
他に何の状況が知りたいのさ?

996:名無しさん@お腹いっぱい。
18/05/03 14:26:18.22 .net
>>968
なんで問題設定に話をすり替えてるの?
問題は>>917。問題が間違ってるといちゃもんを付けたのは>>918

997:名無しさん@お腹いっぱい。
18/05/03 14:26:43.00 .net
>>967
なんやおまえ質問した本人なんかw
ならもっと情報をさらけだしてみw
おにいちゃん達が手取り足取り教えてあげるやろからw

998:名無しさん@お腹いっぱい。
18/05/03 14:28:32.21 .net
>>971
なんだお前が問題が間違ってるといちゃもんつけたやつか?
問題は間違っていませんでした、ごめんなさいって謝れば?

999:名無しさん@お腹いっぱい。
18/05/03 14:29:43.06 .net
>>972
せやでw
てか教えて欲しいくせに何いきなりキレとんねんw
キチガイかおまえはw

1000:名無しさん@お腹いっぱい。
18/05/03 14:32:04.43 .net
はぁ?教えてもらうも何も>>935で自力で解いたし
>>937でeval使ったほうが良いかもって、
それは最初からわかってるよアピール(笑)もしたし
お前はなにか役に立ったのか?
俺に問題が間違ってるといちゃもんを付けた挙げ句
結局、俺の足元にも及んでないじゃんw

1001:名無しさん@お腹いっぱい。
18/05/03 14:34:28.22 .net
>>974
だからな?
もう少し柔軟なアタマと経験を持っとればそんな問題自体にぶちあたらんと言っとるのやでおいちゃんはw
人に教えてもらいたかったらもう少し素直になった方がええでおまえw

1002:名無しさん@お腹いっぱい。
18/05/03 14:38:23.58 .net
>>975
お前に経験がないから問題にぶち当たってないんだろうw
それで、お前質問に答えずに逃げてるよな?
>>960
そして、その選別した引数(複数)を別の関数に渡すんだろ?
配列があれば、配列に選別していった引数を入れていけばいいだろうが
bash依存しないなら、配列は使えないよな。
お前ならどうするんだ?

1003:名無しさん@お腹いっぱい。
18/05/03 14:40:51.17 .net
>>976
いくらお子ちゃまでもナチュラルに話がループするバカにつきあう気はないで生憎w

1004:名無しさん@お腹いっぱい。
18/05/03 14:40:58.71 .net
偉そうに>>960で引数の選別をする方法で
できるような言い方をしているということは、
"このやり方の続き" でやる方法も当然思いついてるはず
質問に答えようか。
まさかここまでいって、この方法じゃ実現不可能だった
なんていうはずがないよなw

1005:名無しさん@お腹いっぱい。
18/05/03 15:39:01.57 .net
やたらめったに長ったらしいコード書いたアホが元凶

1006:名無しさん@お腹いっぱい。
18/05/03 15:57:16.13 .net
たしかに俺のコードは長すぎたし引数に改行が含まれると各行を引数だと見做してしまう
修正が困難な不具合があるからね(もし可能だという方がいるなら是非教えてほしい)。
実は俺自身もシェルスクリプトの経験はあまりないんだ。まだ仕事してねーし。
それが原因で場が乱れたとするなら申し訳ない。
ただ、言わせてもらうが、俺は寧ろ荒れた原因は「問題が間違ってる; 質問は正しい態度で」なんていう
主張をageながら口説いてる奴にあると思うがな。

1007:名無しさん@お腹いっぱい。
18/05/03 16:20:04.93 .net
どっちもはしゃぎ過ぎ
それに、安価だのageだの馬鹿みたい

1008:名無しさん@お腹いっぱい。
18/05/03 16:29:15.75 .net
>>980
いや、だから>>935で自力で解いたってw
eval使ったほうが良さそうだけど
(ここまで自力の結論というかeval版は質問前に作っていたがね)

1009:名無しさん@お腹いっぱい。
18/05/03 16:29:46.34 .net
>>981
> それに、安価だのageだの馬鹿みたい
まったくだw 俺も最初からその2つは無視してるw

1010:名無しさん@お腹いっぱい。
18/05/03 16:31:30.06 .net
IDが出ないスレでこれほど見難い言い争いはあんま見ないな。いや醜いかw

1011:名無しさん@お腹いっぱい。
18/05/03 16:41:10.54 .net
ここって建設的じゃないよな、ホント

1012:名無しさん@お腹いっぱい。
18/05/03 17:10:05.54 .net
自力で解いたっつてんだろ、何度も。偉ぶってんのはどっちなんだか。

1013:名無しさん@お腹いっぱい。
18/05/03 17:33:34.69 .net
醜すぎw

1014:名無しさん@お腹いっぱい。
18/05/03 17:54:41.55 .net
はい、次スレ
シェルスクリプト総合 その27
スレリンク(unix板)

1015:名無しさん@お腹いっぱい。
18/05/03 19:24:32.42 .net
この人は問題を解きたいんじゃなくて
問題を自分のルールで解かせたいだけなんだと思う

1016:名無しさん@お腹いっぱい。
18/05/03 19:33:59.23 .net
自分のルールってなんのことや?

1017:名無しさん@お腹いっぱい。
18/05/03 20:13:25.91 .net
そうじゃなくて呈示されたコードの完成度が低くて、かつ
自分で作ったコードが要件を満たしていたから「お前ら馬鹿ばっかだな」になるんでしょう?

1018:名無しさん@お腹いっぱい。
18/05/03 20:15:23.07 .net
ただのお子ちゃまやないかw
間違っとる言われてボクは間違ってないてすねとるだけやでw

1019:名無しさん@お腹いっぱい。
18/05/03 20:27:22.30 .net
>>991
要件じゃなくて、あれはバグだよ
正しく動いてないじゃないか

1020:名無しさん@お腹いっぱい。
18/05/03 20:28:19.18 .net
いまいち誰が誰だかなわからない追うのめんどくさすぎなのに、論評続けるねえ
質問内容に文句つけ続けのオッサン:一理あるが、一理でしかない。しつこいわっ
質問したヤツ:自力で解いたとかウザいわ。だったら最初から質問すんなwおっさんの一理を理解して素直に受け取れ

1021:名無しさん@お腹いっぱい。
18/05/03 20:37:05.47 .net
>自力で解いたとかウザいわ。だったら最初から質問すんなw
書いた途端に解が分かったとかザラにあるだろ
お騒がせしました、とか書けない人格はアレだけど

1022:名無しさん@お腹いっぱい。
18/05/03 20:38:34.10 .net
>>995
一行目は問題にしてない、全く。言う通りだし
二行目を問題にしてる、ほぼそれが全部

1023:名無しさん@お腹いっぱい。
18/05/03 20:58:18.53 .net
能力はありそうに見えるのにもったいないよね。ああいうので仕事を失しなうってのは。
俺の同僚にも居たわ。正直に言って、俺より優秀だった�


1024:フに人当たりが強すぎてやんわり退職させられて 先月会ったらトビやりながら独学でコーディングしてるらしい



1025:名無しさん@お腹いっぱい。
18/05/05 15:07:28.61 .net
すいません。すごく細かいことなんですが、
シェルの変数に関する展開で、
${somevar:-otherstring}
という、somevarに変数が格納されていなればotherstringを変数の値として採用するという仕組みがありますよね。
ここにコマンド展開が使えるということに最近気がつきました。
${somevar:-$(somecommand)}
これは、展開の順序としては
I. コマンド展開→変数の展開
 somecommandがresultを返し、${somevar:-result}になってresultが展開される
のか、
II. 変数の展開→コマンド展開
 ${somevar:-$(somecommand)}が$(somecommand)になってresultが返る
のか、
どちらか分かりますか?
ぶっちゃけ、この違いが影響するような状況に遭遇したことがないのですが、よりよいシェルスクリプトの理解の為にどうかよろしくおねがいします。

1026:名無しさん@お腹いっぱい。
18/05/05 15:36:58.33 .net
IIなんじゃねーの(鼻くそホジホジ)

1027:名無しさん@お腹いっぱい。
18/05/05 23:01:08.19 .net
somecommandを副作用のあるコマンド(touchとかrmとか)にしでsomevarがある状態とない状態でそれぞれどうなるか比べてみればいい。たぶんIIだと思うが。

1028:名無しさん@お腹いっぱい。
18/05/06 01:02:57.40 .net
>>1000
おぉう。そんな手があったとは。勉強になります。
おっしゃる通りIIでした。
somevarに変数が格納されている時、somecommandは実行されませんでした。

1029:名無しさん@お腹いっぱい。
18/05/06 10:46:14.65 .net
echo 999

1030:名無しさん@お腹いっぱい。
18/05/06 10:46:54.81 .net
exit 1000

1031:1001
Over 1000 Thread.net
このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 411日 22時間 39分 28秒

1032:過去ログ ★
[過去ログ]
■ このスレッドは過去ログ倉庫に格納されています


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch