シェルスクリプトに関する総合スレッドです。
全般
・荒しは無視しましょう。
・丁寧な姿勢を心掛けましょう。
・ネチケット(死語)を意識しましょう。
前スレ:
シェルスクリプト総合 その29
https://mevius.5ch.net/test/read.cgi/tech/1537540487/
探検
シェルスクリプト総合 その30
■ このスレッドは過去ログ倉庫に格納されています
2019/07/01(月) 23:04:27.02ID:/rKj5XUf
305デフォルトの名無しさん
2019/07/18(木) 17:25:39.32ID:Nv4mVpEC bash の mapfile にある callback みたいなもん?
306デフォルトの名無しさん
2019/07/18(木) 19:06:15.61ID:ugDCzjFC 数値計算ならbcに直接渡すし
文字列を加工するラムダ式はbcで処理できないし
必要性を感じたことないんだよね
文字列を加工するラムダ式はbcで処理できないし
必要性を感じたことないんだよね
307デフォルトの名無しさん
2019/07/18(木) 19:08:03.03ID:BkvY1rKv308デフォルトの名無しさん
2019/07/18(木) 19:17:03.16ID:DPDlMznj >>307
へ?数値計算に限定するならもっとシンプルに書けるよ
これだけにできる
lambda '$1 + ($1 * $2)"' 100 0.08
数値計算に限定してないから呼び出し側にechoとかbcが埋め込まれてるんだけど?
へ?数値計算に限定するならもっとシンプルに書けるよ
これだけにできる
lambda '$1 + ($1 * $2)"' 100 0.08
数値計算に限定してないから呼び出し側にechoとかbcが埋め込まれてるんだけど?
309デフォルトの名無しさん
2019/07/18(木) 19:21:15.11ID:DPDlMznj310デフォルトの名無しさん
2019/07/18(木) 19:28:37.52ID:DPDlMznj ラムダで用いる計算式は通常短くなるから、
$1, $2 であっても分かりづらくなることはないだろうが
もともとの人は変数をどうすべきかって言ってたから書くと
lambda 'calc "$1 + ($1 * $2)"' 100 0.08
は
lambda v1 v2 -- 'calc "$v1 + ($v1 * $v2)"' 100 0.08
ってやろうと思えばやれる。変数に入れてからevalすればいいだけだから
それが>>294で書いたこと。--で区切るのが面倒だと思えばこういう書き方もありだろう
lambda v1:v2 'calc "$v1 + ($v1 * $v2)"' 100 0.08
第一引数が:で区切られた変数名、第二引数が計算式、残りが引数と簡単に見分けられる
$1, $2 であっても分かりづらくなることはないだろうが
もともとの人は変数をどうすべきかって言ってたから書くと
lambda 'calc "$1 + ($1 * $2)"' 100 0.08
は
lambda v1 v2 -- 'calc "$v1 + ($v1 * $v2)"' 100 0.08
ってやろうと思えばやれる。変数に入れてからevalすればいいだけだから
それが>>294で書いたこと。--で区切るのが面倒だと思えばこういう書き方もありだろう
lambda v1:v2 'calc "$v1 + ($v1 * $v2)"' 100 0.08
第一引数が:で区切られた変数名、第二引数が計算式、残りが引数と簡単に見分けられる
311デフォルトの名無しさん
2019/07/18(木) 19:41:15.10ID:DPDlMznj 数値限定で引数全てに計算式を適用して返す例(笑)
map() {
formula="$1"
shift
while [ $# -gt 0 ]; do
eval "echo \$(($formula))"
shift
done
}
map '$1 * $1' 1 2 3
map() {
formula="$1"
shift
while [ $# -gt 0 ]; do
eval "echo \$(($formula))"
shift
done
}
map '$1 * $1' 1 2 3
312デフォルトの名無しさん
2019/07/18(木) 19:53:59.13ID:ugDCzjFC 書き方が煩雑になるだけでメリットないんじゃね
やりたいこと素直に書けばいいじゃんって思ってしまう
やりたいこと素直に書けばいいじゃんって思ってしまう
313デフォルトの名無しさん
2019/07/18(木) 19:54:42.45ID:DPDlMznj まあ、それはラムダ計算そのものが言われていることだからw
シェルスクリプトの話ではないね。
シェルスクリプトの話ではないね。
314デフォルトの名無しさん
2019/07/18(木) 20:03:10.85ID:ugDCzjFC ラムダ式って簡潔に書けるのがメリットでしょ
コード量増えるのなら本末転倒だよね
コード量増えるのなら本末転倒だよね
315デフォルトの名無しさん
2019/07/18(木) 20:09:12.09ID:DPDlMznj 簡潔に書けてるよw
map '$1 * $1' 1 2 3
ただ違うのはシェルスクリプトにはそれようのライブラリがないだけ
ここで例示したようなmapみたいなライブラリ集ができたら
もっと便利になると思う
map '$1 * $1' 1 2 3
ただ違うのはシェルスクリプトにはそれようのライブラリがないだけ
ここで例示したようなmapみたいなライブラリ集ができたら
もっと便利になると思う
316デフォルトの名無しさん
2019/07/18(木) 20:15:16.65ID:DPDlMznj というか、普通の言語のラムダ式だと、こんな感じで変数が出てくるけど
lambda a, b : a + b
引数名が$1, $2と数字固定だから変数宣言が不要になるんだよな
lambda a, b : a + b がシェルスクリプトだと
lambda '$1 + $2' だけになっちゃう
i = (lambda a, b: a + b)(1, 2) はシェルスクリプトだと
i=$(lambda '$1 + $2' 1 2) こうなる
lambda a, b : a + b
引数名が$1, $2と数字固定だから変数宣言が不要になるんだよな
lambda a, b : a + b がシェルスクリプトだと
lambda '$1 + $2' だけになっちゃう
i = (lambda a, b: a + b)(1, 2) はシェルスクリプトだと
i=$(lambda '$1 + $2' 1 2) こうなる
317デフォルトの名無しさん
2019/07/18(木) 20:17:43.55ID:ugDCzjFC クロージャの概念がないシェルスクリプトは
ラムダ式の真価を発揮する場面は無いだろうね
ラムダ式の真価を発揮する場面は無いだろうね
318デフォルトの名無しさん
2019/07/18(木) 20:22:14.60ID:DPDlMznj 無いっていうのは出来ないんじゃなくて
用意されてないって意味だけどな
実はPOSIX標準でも一つだけクロージャーが使われてる。
それがtrap
trap 'echo trapped; exit 1' INT
みたいな書き方ができる
用意されてないって意味だけどな
実はPOSIX標準でも一つだけクロージャーが使われてる。
それがtrap
trap 'echo trapped; exit 1' INT
みたいな書き方ができる
319デフォルトの名無しさん
2019/07/18(木) 20:55:40.78ID:BkvY1rKv ていうか(ほぼ暴論だけど)シェルスクリプトだってオブジェクト思考っぽいことはできる訳だし
単に「向いている処理」「向いていない処理」があるってだけ。
シェルスクリプトでラムダ式は書けるけど、シェルスクリプトはラムダ式を扱うのには向いていない。
単に「向いている処理」「向いていない処理」があるってだけ。
シェルスクリプトでラムダ式は書けるけど、シェルスクリプトはラムダ式を扱うのには向いていない。
320デフォルトの名無しさん
2019/07/18(木) 21:16:40.14ID:DPDlMznj そんな難しく考えるなよw
trapの例もあるんだし、使うのが適切な場合に使えば良いいんだよ
trapの例もあるんだし、使うのが適切な場合に使えば良いいんだよ
321デフォルトの名無しさん
2019/07/18(木) 21:28:25.20ID:KBi6m+gV map は意外と使い道がないんだよな
lisp 以外では意外と実装されていない
lisp 以外では意外と実装されていない
322デフォルトの名無しさん
2019/07/18(木) 21:33:57.01ID:DPDlMznj 実装されてない言語のほうが珍しいだろw
323デフォルトの名無しさん
2019/07/18(木) 21:36:48.83ID:DPDlMznj mapがある言語
Python、Ruby、Perl、JavaScript、C#(LINQのSelect)
思いついたものだけ
Python、Ruby、Perl、JavaScript、C#(LINQのSelect)
思いついたものだけ
324デフォルトの名無しさん
2019/07/18(木) 21:42:27.79ID:ugDCzjFC trapってただのイベントハンドラだよ
引数渡したり戻り値受け取ったりできないじゃん
引数渡したり戻り値受け取ったりできないじゃん
325デフォルトの名無しさん
2019/07/18(木) 21:52:45.54ID:DPDlMznj trapはイベントハンドラじゃない。
シグナルに対してイベントハンドラを設定するもの
引き数渡したり戻り値受け取ったり出来ないのは
trapの制限であってイベントハンドラの制限じゃない
シグナルに対してイベントハンドラを設定するもの
引き数渡したり戻り値受け取ったり出来ないのは
trapの制限であってイベントハンドラの制限じゃない
326デフォルトの名無しさん
2019/07/18(木) 22:00:05.94ID:ugDCzjFC 言いたいのはクロージャの話してるのにtrap 持ってくるのは筋違いってことだ
327デフォルトの名無しさん
2019/07/18(木) 22:03:45.58ID:DPDlMznj 別に筋違いでもない。戻り値は(標準)出力と上で書いたが、
trapで出力したものは画面に表示される。
trapで出力したものは画面に表示される。
328デフォルトの名無しさん
2019/07/18(木) 23:59:39.80ID:SGv/emwF 「mapは意外と使い道がない!lisp以外では意外と実装されていない!!(キリッ」
329デフォルトの名無しさん
2019/07/19(金) 01:30:43.88ID:/UdqfCLD 正直>>321のmapの話は無知だなと思ったけど(めちゃめちゃ実装言語があるので)
そうやって煽ることしかできない君より100万倍有意義な発言だったよ。
そうやって煽ることしかできない君より100万倍有意義な発言だったよ。
330デフォルトの名無しさん
2019/07/19(金) 01:49:27.68ID:7Hdy7m6i >>323
Kotlin もよろしく
Kotlin もよろしく
331デフォルトの名無しさん
2019/07/19(金) 02:44:48.56ID:ApXEphk2 map 縛ると高階関数で書きにくい
332デフォルトの名無しさん
2019/07/19(金) 08:55:46.76ID:MqWaI42B333デフォルトの名無しさん
2019/07/19(金) 09:10:54.61ID:mIHotaYe 第13話 本物のラムダ計算(完)
334デフォルトの名無しさん
2019/07/19(金) 10:16:54.74ID:uab/wKdg Cだとqsort()とかがラムダになるのかな。
335デフォルトの名無しさん
2019/07/19(金) 10:47:40.54ID:pw5qcQRZ map が有効な例はどんな時?
336デフォルトの名無しさん
2019/07/19(金) 11:16:36.30ID:ApXEphk2 集合XからYに写像を持つ関数fがあれば
Y = f(X) と書ける
これを満たす x, yは
y = f(x) で表わせる
数学だとこんなかんじだが
プログラムなら
Y = map f X のような感じでいっきに変換できる
map 使わないで、古典的なループを書くと
for my $x (@X) {push @Y, &f(x)}
のような具合になるが、x, push など本来不要な変数や操作を中継するため
コードが肥大化する
Y = f(X) と書ける
これを満たす x, yは
y = f(x) で表わせる
数学だとこんなかんじだが
プログラムなら
Y = map f X のような感じでいっきに変換できる
map 使わないで、古典的なループを書くと
for my $x (@X) {push @Y, &f(x)}
のような具合になるが、x, push など本来不要な変数や操作を中継するため
コードが肥大化する
337デフォルトの名無しさん
2019/07/19(金) 11:33:07.63ID:/UdqfCLD338デフォルトの名無しさん
2019/07/19(金) 11:37:49.93ID:/UdqfCLD339デフォルトの名無しさん
2019/07/19(金) 11:47:33.02ID:/UdqfCLD340デフォルトの名無しさん
2019/07/19(金) 12:35:59.70ID:mIHotaYe >>339
perlのsortの場合、$a、$b固定になってる
https://perldoc.jp/func/sort
my @articles = sort {$a cmp $b} @files;
perlの場合、関数の引数は$_[0]、$_[1]で取れるのだが
そうすると、sortの外の$_[0]、$_[1]になってしまう。
文字列にしてevalしちゃえば同じことはできると思うがそれでも長くなっちゃうしな。
my @articles = sort '$_[0] cmp$_[1]' @files;
このために$a、$bをグローバル変数としているようだが、Perlはダイナミックスコープを
使えるからローカル変数にできるんじゃないかな? 互換性のためにそうなっているのかも
perlのsortの場合、$a、$b固定になってる
https://perldoc.jp/func/sort
my @articles = sort {$a cmp $b} @files;
perlの場合、関数の引数は$_[0]、$_[1]で取れるのだが
そうすると、sortの外の$_[0]、$_[1]になってしまう。
文字列にしてevalしちゃえば同じことはできると思うがそれでも長くなっちゃうしな。
my @articles = sort '$_[0] cmp$_[1]' @files;
このために$a、$bをグローバル変数としているようだが、Perlはダイナミックスコープを
使えるからローカル変数にできるんじゃないかな? 互換性のためにそうなっているのかも
341デフォルトの名無しさん
2019/07/19(金) 14:53:58.91ID:pw5qcQRZ342デフォルトの名無しさん
2019/07/19(金) 15:35:22.89ID:uab/wKdg >>341
有り難いと言うか、記述が短くなったり、余計な変数を使わなくてよくなったり、連結して書けて分かりやすくなったりという利点があるかな。
有り難いと言うか、記述が短くなったり、余計な変数を使わなくてよくなったり、連結して書けて分かりやすくなったりという利点があるかな。
343デフォルトの名無しさん
2019/07/19(金) 15:43:06.00ID:ApXEphk2 >>341
集合を扱うのに適した型がない言語、perl などを例にすると
後ろの方を見るのに時間がかかる大きなリスト素早く参照するハックとして
>271
のようにハッシュに打ちこむ手法がある
シェルスクリプトのワンライナーだと1行ずつ入ってくるけど
perl コード内なら簡潔に書けるし、たぶん map の部分が C で書かれてて
速度が出ることが覆い
このタイプの高速な手法としてはシュワルツ変換が有名
|sort -k 2,2
に相当するやつ
集合を扱うのに適した型がない言語、perl などを例にすると
後ろの方を見るのに時間がかかる大きなリスト素早く参照するハックとして
>271
のようにハッシュに打ちこむ手法がある
シェルスクリプトのワンライナーだと1行ずつ入ってくるけど
perl コード内なら簡潔に書けるし、たぶん map の部分が C で書かれてて
速度が出ることが覆い
このタイプの高速な手法としてはシュワルツ変換が有名
|sort -k 2,2
に相当するやつ
344デフォルトの名無しさん
2019/07/19(金) 16:04:19.10ID:S0JoFjeS345デフォルトの名無しさん
2019/07/19(金) 17:47:07.68ID:mIHotaYe346デフォルトの名無しさん
2019/07/19(金) 19:32:30.99ID:LTHpRmEj ていうかシェルスクリプトの関数って(少なくともPOSIXの範囲では)広域定義で
システムのコマンドと同じ名前空間(名前空間なんて一つしかないけど)で定義するしかない。
だからラムダ式に代表される無名関数は寧ろシェルスクリプトのような言語で重宝するかも知れない。
でも可読性や保守性を考えると一般的でない書き方なので多用は控えたほうがいいかな。
システムのコマンドと同じ名前空間(名前空間なんて一つしかないけど)で定義するしかない。
だからラムダ式に代表される無名関数は寧ろシェルスクリプトのような言語で重宝するかも知れない。
でも可読性や保守性を考えると一般的でない書き方なので多用は控えたほうがいいかな。
347デフォルトの名無しさん
2019/07/20(土) 02:10:15.33ID:RMeQOh+3 >>345
もちろんそのリンク先に書いてある。……下から 21 行目に。(空行を除く)
もちろんそのリンク先に書いてある。……下から 21 行目に。(空行を除く)
348デフォルトの名無しさん
2019/07/23(火) 15:21:00.97ID:vatz3/hX シェルスクリプトで引数が整数であることを判定する可搬で高速な方法ってなんだろう
思い付いたのは
isint() {
case "$1" in
[0-9][0-9]*) printf '%d\n' $1 ;;
*) return 22 ;;
esac
}
…ところで$1がないときは標準入力から値を取得するっていう操作ってどう実装するんだろう?
思い付いたのは
isint() {
case "$1" in
[0-9][0-9]*) printf '%d\n' $1 ;;
*) return 22 ;;
esac
}
…ところで$1がないときは標準入力から値を取得するっていう操作ってどう実装するんだろう?
349デフォルトの名無しさん
2019/07/23(火) 15:29:05.59ID:+7TCISw6 >>348
標準入力かどうかは
けっこうシェルスクリプトとperlは同じような書き方する部分があるから
こんな構文がありそうだ
https://pastebin.com/0wXLeenr
あとそれだと負の数が抜けてる。数字の前に マイナス記号がついている可能性がある
標準入力かどうかは
けっこうシェルスクリプトとperlは同じような書き方する部分があるから
こんな構文がありそうだ
https://pastebin.com/0wXLeenr
あとそれだと負の数が抜けてる。数字の前に マイナス記号がついている可能性がある
350デフォルトの名無しさん
2019/07/23(火) 15:31:44.56ID:ecacfG7E case $1 in # $1にダブルクォートはいらない
*[!0-9]* ) ;; # 数字以外が含まれている = 整数ではない
*) ;; # それ以外 = 整数である
esac
if [ $# -eq 0 ]; then
read -r data
else
data=$1
fi
とかいろいろ
*[!0-9]* ) ;; # 数字以外が含まれている = 整数ではない
*) ;; # それ以外 = 整数である
esac
if [ $# -eq 0 ]; then
read -r data
else
data=$1
fi
とかいろいろ
351デフォルトの名無しさん
2019/07/23(火) 15:32:56.13ID:ecacfG7E > 数字の前に マイナス記号がついている可能性がある
case ${1#-} in
こうすればよい
case ${1#-} in
こうすればよい
352デフォルトの名無しさん
2019/07/23(火) 15:36:47.54ID:ecacfG7E $1があるかどうかじゃなくて、echoなどで流し込まれているかどうかなら
if [ -t 0 ]; then
# 流し込まれてなどいない
else
# 流し込まれている
fi
if [ -t 0 ]; then
# 流し込まれてなどいない
else
# 流し込まれている
fi
353デフォルトの名無しさん
2019/07/23(火) 15:43:42.61ID:ecacfG7E 所でcaseって戻り値を返すって知ってる?
isint() {
case $1 in
*[!0-9]* ) false ;;
*) true ;;
esac
}
if isint 1; then
echo int
fi
とか、
if case $1 in *[!0-9]* ) false ;; *) true ;; esac; then
echo int
fi
とか
if ! case $1 in *[!0-9]* ) false; esac; then
echo int
fi
とか書けるよ
isint() {
case $1 in
*[!0-9]* ) false ;;
*) true ;;
esac
}
if isint 1; then
echo int
fi
とか、
if case $1 in *[!0-9]* ) false ;; *) true ;; esac; then
echo int
fi
とか
if ! case $1 in *[!0-9]* ) false; esac; then
echo int
fi
とか書けるよ
354デフォルトの名無しさん
2019/07/23(火) 15:47:46.96ID:ecacfG7E > if ! case $1 in *[!0-9]* ) false; esac; then
間違えたw !いらない
最短かな?
if case $1 in *[!0-9]*) false; esac; then
echo int
fi
ワンライナーw
isint() { case $1 in *[!0-9]*) false; esac; }
間違えたw !いらない
最短かな?
if case $1 in *[!0-9]*) false; esac; then
echo int
fi
ワンライナーw
isint() { case $1 in *[!0-9]*) false; esac; }
355デフォルトの名無しさん
2019/07/23(火) 15:50:04.40ID:ecacfG7E あ、空文字のときにintになるね。こうすればよい
isint() { case $1 in ''|*[!0-9]*) false; esac; }
isint() { case $1 in ''|*[!0-9]*) false; esac; }
356デフォルトの名無しさん
2019/07/23(火) 15:50:25.78ID:h7ECSrMt expr "$1" + 0 >/dev/null 2>&1
echo $?
というのもありかと思ったけど、MAXINT(2^32or2^64)以上になると
エラーになる(exit status 3)からダメか
echo $?
というのもありかと思ったけど、MAXINT(2^32or2^64)以上になると
エラーになる(exit status 3)からダメか
357348
2019/07/23(火) 16:11:28.72ID:vatz3/hX みなさんありがとうございます。
↓助言を参考にさしてもらってこういう形にしました。
isint() { set -- "$1"
case ${1#-} in
''|*[!0-9]*) return 22 ;;
*) true ;;
esac
}
「$1が設定されていなければ標準入力を$1に」というのはシェルスクリプトでは
実現が難しそうなので諦めます。
↓助言を参考にさしてもらってこういう形にしました。
isint() { set -- "$1"
case ${1#-} in
''|*[!0-9]*) return 22 ;;
*) true ;;
esac
}
「$1が設定されていなければ標準入力を$1に」というのはシェルスクリプトでは
実現が難しそうなので諦めます。
358デフォルトの名無しさん
2019/07/23(火) 16:12:19.43ID:ecacfG7E if case $1 in *[!0-9]*) false; esac; then
echo int
fi
こっちのほうが短いかw
case $1 in *[!0-9]*) :;; *)
echo int
esac
echo int
fi
こっちのほうが短いかw
case $1 in *[!0-9]*) :;; *)
echo int
esac
359348
2019/07/23(火) 16:15:37.53ID:vatz3/hX ……と思いましたが良い感じの構文を思い付きました。
isint() { set -- "${1:-"$(cat)"}"
case ${1#-} in
''|*[!0-9]*) return 22 ;;
*) true ;;
esac
}
これでどうでしょうかね。もし$1が設定されていなければcat(1)が実行されて
cat(1)には引数が渡っていない(この時は$1が設定されていない)ので
If no file operands are specified, the standard input shall be used.
(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cat.html)
に従って標準入力が読み込まれてset -- 〈標準入力の内容〉となって$1に標準入力が設定される。
isint() { set -- "${1:-"$(cat)"}"
case ${1#-} in
''|*[!0-9]*) return 22 ;;
*) true ;;
esac
}
これでどうでしょうかね。もし$1が設定されていなければcat(1)が実行されて
cat(1)には引数が渡っていない(この時は$1が設定されていない)ので
If no file operands are specified, the standard input shall be used.
(http://pubs.opengroup.org/onlinepubs/9699919799/utilities/cat.html)
に従って標準入力が読み込まれてset -- 〈標準入力の内容〉となって$1に標準入力が設定される。
360デフォルトの名無しさん
2019/07/23(火) 16:15:43.02ID:ecacfG7E trueはさっき俺が書いたけど、別にいらない
isint() { set -- "$1"
case ${1#-} in
''|*[!0-9]*) return 22
esac
}
> 「$1が設定されていなければ標準入力を$1に」というのはシェルスクリプトでは
こっちも書いたはずだが? cat "$1" or cat "/dev/stdin" の話でもしてたのか?
isint() { set -- "$1"
case ${1#-} in
''|*[!0-9]*) return 22
esac
}
> 「$1が設定されていなければ標準入力を$1に」というのはシェルスクリプトでは
こっちも書いたはずだが? cat "$1" or cat "/dev/stdin" の話でもしてたのか?
361デフォルトの名無しさん
2019/07/23(火) 16:16:28.44ID:ecacfG7E cat呼び出しは遅いから、read使ったんだが?
362デフォルトの名無しさん
2019/07/23(火) 17:17:45.59ID:vatz3/hX >>361
申し訳ないです。完全に見落してました。
申し訳ないです。完全に見落してました。
363デフォルトの名無しさん
2019/07/23(火) 23:34:58.45ID:JEktaXSk npmでシェルスクリプトだけのパッケージを配布してもOKですか?
364デフォルトの名無しさん
2019/07/24(水) 01:15:44.75ID:ArGZw8p9 npmスレに。
365デフォルトの名無しさん
2019/07/24(水) 21:22:10.25ID:ArGZw8p9 >>361
catとreadってたった一行読み込むのにそんな差ある?
catとreadってたった一行読み込むのにそんな差ある?
366デフォルトの名無しさん
2019/07/25(木) 02:49:23.09ID:WafvXnG3 1行だからcatが遅いんだろ
367デフォルトの名無しさん
2019/07/25(木) 02:51:27.80ID:muDuQw8n ついcatなって言った
368デフォルトの名無しさん
2019/07/25(木) 08:46:34.39ID:m8sWcejF こawkあいはしていない。
369デフォルトの名無しさん
2019/07/25(木) 14:59:51.08ID:VsjL1nxe sedで質問です。
置換前
(a0b1c2=99999) (a0b1c2=00000)
置換後
DATA1=99999 DATA2=00000
こんな感じに置換したいです。
カッコと接頭辞みたいなのを除去した上で、
行の1つめはDATA1に、2つめはDATA2に置換したいという意味です。
何卒ご教示ください。
置換前
(a0b1c2=99999) (a0b1c2=00000)
置換後
DATA1=99999 DATA2=00000
こんな感じに置換したいです。
カッコと接頭辞みたいなのを除去した上で、
行の1つめはDATA1に、2つめはDATA2に置換したいという意味です。
何卒ご教示ください。
370デフォルトの名無しさん
2019/07/25(木) 15:04:52.21ID:D8pzUtDE (
[a-zA-Z0-9]
=
[0-9]+
)
こんな形のデータか?
[a-zA-Z0-9]
=
[0-9]+
)
こんな形のデータか?
371デフォルトの名無しさん
2019/07/25(木) 15:09:40.46ID:D8pzUtDE 暫定これ
echo "(a0b1c2=99999) (a0b1c2=00000)" | sed -n 's/([a-zA-Z0-9]\+=\([0-9]\+\)) ([a-zA-Z0-9]\+=\([0-9]\+\))/DATA1=\1 DATA2=\2/gp'
DATA1=99999 DATA2=00000
echo "(a0b1c2=99999) (a0b1c2=00000)" | sed -n 's/([a-zA-Z0-9]\+=\([0-9]\+\)) ([a-zA-Z0-9]\+=\([0-9]\+\))/DATA1=\1 DATA2=\2/gp'
DATA1=99999 DATA2=00000
372デフォルトの名無しさん
2019/07/25(木) 15:11:16.41ID:VsjL1nxe >>370
すいません、話を簡単にするため>>369は端折ったんですが、
端折らない方がよさそうなので元データそのまま書きます。
わかる人にはわかるかもしれませんが、VMwareのAPIから取ってきた値です。
guest(01) %!s(int32=110) %!s(int32=3625)
これは左からゲスト名、各ゲストのCPU使用量(MHz)、メモリ使用量(MB)です。
これを
guest(01) CPU=110 Memory=3625
こんな感じにしたいなと思っています。
最初はsedの単純な置換とパイプで何とかしようとしたんですが、
ゲスト名にもカッコが使われてる(のが除去されちゃう)という部分が回避できませんでした。
すいません、話を簡単にするため>>369は端折ったんですが、
端折らない方がよさそうなので元データそのまま書きます。
わかる人にはわかるかもしれませんが、VMwareのAPIから取ってきた値です。
guest(01) %!s(int32=110) %!s(int32=3625)
これは左からゲスト名、各ゲストのCPU使用量(MHz)、メモリ使用量(MB)です。
これを
guest(01) CPU=110 Memory=3625
こんな感じにしたいなと思っています。
最初はsedの単純な置換とパイプで何とかしようとしたんですが、
ゲスト名にもカッコが使われてる(のが除去されちゃう)という部分が回避できませんでした。
373デフォルトの名無しさん
2019/07/25(木) 15:20:38.81ID:D8pzUtDE echo 'guest(01) %!s(int32=110) %!s(int32=3625)' | sed -n 's/\S\+([a-zA-Z0-9]\+=\([0-9]\+\)) \S\+([a-zA-Z0-9]\+=\([0-9]\+\))/DATA1=\1 DATA2=\2/gp'
guest(01) DATA1=110 DATA2=3625
これで間にあう?
guest(01) DATA1=110 DATA2=3625
これで間にあう?
374デフォルトの名無しさん
2019/07/25(木) 15:22:34.93ID:D8pzUtDE 失礼しました
最後のCPU, Memoryに書きかえて
echo 'guest(01) %!s(int32=110) %!s(int32=3625)' | sed -e 's/\S\+([a-zA-Z0-9]\+=\([0-9]\+\)) \S\+([a-zA-Z0-9]\+=\([0-9]\+\))/CPU=\1 Memory=\2/g'
guest(01) CPU=110 Memory=3625
最後のCPU, Memoryに書きかえて
echo 'guest(01) %!s(int32=110) %!s(int32=3625)' | sed -e 's/\S\+([a-zA-Z0-9]\+=\([0-9]\+\)) \S\+([a-zA-Z0-9]\+=\([0-9]\+\))/CPU=\1 Memory=\2/g'
guest(01) CPU=110 Memory=3625
375デフォルトの名無しさん
2019/07/25(木) 15:27:23.74ID:hsvk8oNq >>361
パイプにテキストファイルの中身を流し込んで逐次処理するとき、
cat "hoge.txt" | 〜 のほかに、
echo $(< "hoge.txt") | 〜 とか、
lessなどのページャー読み込みでもできるけど、
どうするかいつも悩むなぁ。
grepなどの、ファイル読み込みオプションのあるコマンドが先頭ならそれを使えばいいけど、
そうでない場合は、みんなどうしてる?
パイプにテキストファイルの中身を流し込んで逐次処理するとき、
cat "hoge.txt" | 〜 のほかに、
echo $(< "hoge.txt") | 〜 とか、
lessなどのページャー読み込みでもできるけど、
どうするかいつも悩むなぁ。
grepなどの、ファイル読み込みオプションのあるコマンドが先頭ならそれを使えばいいけど、
そうでない場合は、みんなどうしてる?
376デフォルトの名無しさん
2019/07/25(木) 15:44:25.16ID:qx5YGZv4 >>375
何故 < hoge.txt じゃ駄目なの?
何故 < hoge.txt じゃ駄目なの?
377デフォルトの名無しさん
2019/07/25(木) 15:57:19.67ID:VsjL1nxe378デフォルトの名無しさん
2019/07/25(木) 17:02:25.09ID:hsvk8oNq >>376
複数のパイプを繋げた逐次処理の場合に、
処理元のファイルが何であるかを明確にしたいので、
すべてのパイプの先頭に持っていきたいんだよ。
ファイル読み込み | 処理1 | 処理2 | 処理3…
複数のパイプを繋げた逐次処理の場合に、
処理元のファイルが何であるかを明確にしたいので、
すべてのパイプの先頭に持っていきたいんだよ。
ファイル読み込み | 処理1 | 処理2 | 処理3…
379デフォルトの名無しさん
2019/07/25(木) 17:18:56.17ID:vvE0ECJG 俺なら
< hoge.txt cmd1 | cmd2 | cmd3 ...
と書く
< hoge.txt cmd1 | cmd2 | cmd3 ...
と書く
380デフォルトの名無しさん
2019/07/25(木) 17:34:33.11ID:hsvk8oNq >>379
ほぉ、リダイレクトって、コマンドの前にもってこれるんだ。ありがとう。
これならとりあえず、ソースを明確にできるね。
しかもおそらく一番処理が速いかな。
catを使った方法のような、単に読み込むだけのコマンドの高速版みたいなのはないのかなぁ。
ほぉ、リダイレクトって、コマンドの前にもってこれるんだ。ありがとう。
これならとりあえず、ソースを明確にできるね。
しかもおそらく一番処理が速いかな。
catを使った方法のような、単に読み込むだけのコマンドの高速版みたいなのはないのかなぁ。
381デフォルトの名無しさん
2019/07/25(木) 18:20:54.41ID:D8pzUtDE >>377
正規表現は実行可能な回戦ノイズになりやすいから、
複雑なものは、可能なら perl を薦める
バックスラッシュの頻度も下がり、空白で単位ごとに分けられ読みやすい
echo 'guest(01) %!s(int32=110) %!s(int32=3625)' | perl -pe 's{ \S+ \( [a-zA-Z0-9]+ = ([0-9]+) \) \N{SPACE} \S+ \( [a-zA-Z0-9]+ = ([0-9]+) \) }{CPU=$1 Memory=$2}xg'
guest(01) CPU=110 Memory=3625
sedの正規表現にはいくつか注意すべきことがあると思う
match部の
( が 文字どおりの ( にマッチする
\( が あとで \1 \2 で使う為のキャプチャの括弧になる。
\+ が1つ以上の という個数指定になる
正規表現は実行可能な回戦ノイズになりやすいから、
複雑なものは、可能なら perl を薦める
バックスラッシュの頻度も下がり、空白で単位ごとに分けられ読みやすい
echo 'guest(01) %!s(int32=110) %!s(int32=3625)' | perl -pe 's{ \S+ \( [a-zA-Z0-9]+ = ([0-9]+) \) \N{SPACE} \S+ \( [a-zA-Z0-9]+ = ([0-9]+) \) }{CPU=$1 Memory=$2}xg'
guest(01) CPU=110 Memory=3625
sedの正規表現にはいくつか注意すべきことがあると思う
match部の
( が 文字どおりの ( にマッチする
\( が あとで \1 \2 で使う為のキャプチャの括弧になる。
\+ が1つ以上の という個数指定になる
382デフォルトの名無しさん
2019/07/25(木) 18:41:30.57ID:m8sWcejF ……Perlも十分読み難いと思うのは俺だけだろうか…
383デフォルトの名無しさん
2019/07/25(木) 18:52:29.83ID:I5POGkj3 perl が使えるような環境なら sed -E 使えるんじゃね?
384デフォルトの名無しさん
2019/07/25(木) 19:47:46.86ID:D8pzUtDE >>382
もっと分かりやすそうに書いてみた
今度はどうだ?
echo 'guest(01) %!s(int32=110) %!s(int32=3625)' | perl -pe ' $pattern = q{ \S+ \( [a-zA-Z0-9]+ = ([0-9]+) \) } ; s/$pattern \N{SPACE} $pattern/CPU=$1 Memory=$2/x'
guest(01) CPU=110 Memory=3625
もっと分かりやすそうに書いてみた
今度はどうだ?
echo 'guest(01) %!s(int32=110) %!s(int32=3625)' | perl -pe ' $pattern = q{ \S+ \( [a-zA-Z0-9]+ = ([0-9]+) \) } ; s/$pattern \N{SPACE} $pattern/CPU=$1 Memory=$2/x'
guest(01) CPU=110 Memory=3625
385デフォルトの名無しさん
2019/07/25(木) 21:09:49.52ID:AjtfUs9C386デフォルトの名無しさん
2019/07/25(木) 22:22:57.77ID:1GqrqsZl これぐらいのの複雑さになると、perl でちゃんと改行、インデントして
書いた方がいいような気がする
書いた方がいいような気がする
387デフォルトの名無しさん
2019/07/26(金) 00:44:50.95ID:16gdYth6 シェルスクリプトは関数型だとかアホなこと言ってるブログがあった
388デフォルトの名無しさん
2019/07/26(金) 10:46:37.80ID:54Ib42km Ruby では、
def get_value( str ) # = ) の間にある文字列を取得する
pos_1 = str.rindex "=" # 文字を末尾から探す
pos_2 = str.rindex ")"
str[ pos_1 + 1 ... pos_2 ]
end
str = 'guest(01) %!s(int32=110) %!s(int32=3625)'
ary = str.split # 空白で区切る
# ["guest(01)", "%!s(int32=110)", "%!s(int32=3625)"]
puts "#{ ary[ 0 ] } CPU=#{ get_value( ary[ 1 ] ) } Memory=#{ get_value( ary[ 2 ] ) }"
# guest(01) CPU=110 Memory=3625
1-liner では、
ただし、途中で改行したので、1行にしてください!
echo 'guest(01) %!s(int32=110) %!s(int32=3625)' | ruby -ne 'def get_value( str ) pos_1 = str.rindex "="; pos_2 = str.rindex ")"; str[ pos_1 + 1 ... pos_2 ] end;
ary = $_.split; puts "#{ ary[ 0 ] } CPU=#{ get_value( ary[ 1 ] ) } Memory=#{ get_value( ary[ 2 ] ) }"'
def get_value( str ) # = ) の間にある文字列を取得する
pos_1 = str.rindex "=" # 文字を末尾から探す
pos_2 = str.rindex ")"
str[ pos_1 + 1 ... pos_2 ]
end
str = 'guest(01) %!s(int32=110) %!s(int32=3625)'
ary = str.split # 空白で区切る
# ["guest(01)", "%!s(int32=110)", "%!s(int32=3625)"]
puts "#{ ary[ 0 ] } CPU=#{ get_value( ary[ 1 ] ) } Memory=#{ get_value( ary[ 2 ] ) }"
# guest(01) CPU=110 Memory=3625
1-liner では、
ただし、途中で改行したので、1行にしてください!
echo 'guest(01) %!s(int32=110) %!s(int32=3625)' | ruby -ne 'def get_value( str ) pos_1 = str.rindex "="; pos_2 = str.rindex ")"; str[ pos_1 + 1 ... pos_2 ] end;
ary = $_.split; puts "#{ ary[ 0 ] } CPU=#{ get_value( ary[ 1 ] ) } Memory=#{ get_value( ary[ 2 ] ) }"'
389デフォルトの名無しさん
2019/07/26(金) 12:22:34.47ID:AGnOcgvd >>388
死ね
死ね
390デフォルトの名無しさん
2019/07/27(土) 10:41:07.02ID:6v++aFZ1 上の方の数値判定だけどマイナス記号を考えない(つまり正整数だけを判定する)のなら
[ ! ${var%%[0-9]*} ]
これが最速で(記述も)最短じゃなかろうか。
[ ! ${var%%[0-9]*} ]
これが最速で(記述も)最短じゃなかろうか。
391デフォルトの名無しさん
2019/07/27(土) 11:54:57.07ID:z4Poa3yK 真っ直ぐに一直線ですか?
392デフォルトの名無しさん
2019/07/27(土) 13:52:23.75ID:QzyB/IP7 >>390
シェルのパターンマッチングでの '*' って any string の意味なので、
$ var='10abcdefg'
$ [ ! ${var%%[0-9]*} ] && echo integer
integer
となってしまう。bash の extglob を使うなら、
$ [ ! ${var%%?([-+])+([0-9])} ] && echo integer
などと書ける(空文字の場合に対応してないけど)。
シェルのパターンマッチングでの '*' って any string の意味なので、
$ var='10abcdefg'
$ [ ! ${var%%[0-9]*} ] && echo integer
integer
となってしまう。bash の extglob を使うなら、
$ [ ! ${var%%?([-+])+([0-9])} ] && echo integer
などと書ける(空文字の場合に対応してないけど)。
393デフォルトの名無しさん
2019/07/27(土) 15:15:37.83ID:6v++aFZ1394デフォルトの名無しさん
2019/07/27(土) 19:04:12.75ID:6v++aFZ1 突飛なことはせずcase分使うのが一番いいのかな。
正直、俺だったらそもそも「型」の概念が必要になるようなプログラムは
シェルスクリプトで書かないけど
正直、俺だったらそもそも「型」の概念が必要になるようなプログラムは
シェルスクリプトで書かないけど
395デフォルトの名無しさん
2019/07/28(日) 00:29:26.94ID:LPR+u+AV * は、シェルスクリプトでは、0文字以上の任意の文字列で、
正規表現では、直前の文字の0回以上の繰り返し
正規表現を使うのなら、egrep, grep -e でフィルターしないといけない
egrep '正規表現'
これもシェルで解釈されないように、シングルクォーテーションで囲む方がよい
正規表現では、直前の文字の0回以上の繰り返し
正規表現を使うのなら、egrep, grep -e でフィルターしないといけない
egrep '正規表現'
これもシェルで解釈されないように、シングルクォーテーションで囲む方がよい
396デフォルトの名無しさん
2019/07/28(日) 00:33:37.21ID:7n7RswoS perlは正規表現しか知らんが構文は結構読みにくいのね
pythonやruby辺りやった方がいいのかな
簡単なシェルスクリプトを書いたりsedやawkで弄ったりはしてるけど
pythonやruby辺りやった方がいいのかな
簡単なシェルスクリプトを書いたりsedやawkで弄ったりはしてるけど
397デフォルトの名無しさん
2019/07/28(日) 01:42:13.12ID:/N9EqgUo シェルスクリプトとしてはワンライナーが短く書け、
カオスも含めた無限のような表現力のあるperl を薦める
seq 30 | perl -0777 -ne 'print $_ =()= /1/g'
13
カオスも含めた無限のような表現力のあるperl を薦める
seq 30 | perl -0777 -ne 'print $_ =()= /1/g'
13
398デフォルトの名無しさん
2019/07/28(日) 02:18:58.47ID:UCGA8APU seq 30 | tr -dc '1' | wc -c
でいいんじゃね
でいいんじゃね
399デフォルトの名無しさん
2019/07/28(日) 02:37:29.23ID:/N9EqgUo 旨い
2文字以上じゃないことを利用する柔軟性見事
2文字以上じゃないことを利用する柔軟性見事
400デフォルトの名無しさん
2019/07/28(日) 03:11:34.56ID:vKAr7iFy401デフォルトの名無しさん
2019/07/28(日) 04:13:22.82ID:/N9EqgUo はい
402デフォルトの名無しさん
2019/07/28(日) 04:28:55.80ID:LPR+u+AV Ruby では、1 の個数を数える
seq 30 | ruby -e 'puts ARGF.read.count( "1" )'
#=> 13
seq 30 | ruby -e 'puts ARGF.read.count( "1" )'
#=> 13
403デフォルトの名無しさん
2019/07/28(日) 04:30:02.41ID:vKAr7iFy 何の意味があんの?
Perlだと複雑に書けるよってこと?
Perlだと複雑に書けるよってこと?
404デフォルトの名無しさん
2019/07/28(日) 04:37:14.85ID:UCGA8APU 1 を数えたいなら
$ seq 30 | grep -o 1 | wc -l
$ seq 30 | grep -o 1 | wc -l
■ このスレッドは過去ログ倉庫に格納されています
ニュース
- 京都のホテル大幅値下げ 訪日中国人客、年1000万人目前で急ブレーキ ★2 [蚤の市★]
- 高市首相の答弁書に「台湾有事答えない」と明記 存立危機発言当時 ★9 [蚤の市★]
- 中国・ロシア両軍の爆撃機が東京方面へ向かう「異例のルート」を共同飛行…核も搭載可能、連携して威嚇か ★4 [ぐれ★]
- 「今の女性はルッキズム」は本当なのか? 若い世代が結婚相手に求める"本当の条件" [少考さん★]
- 【サッカー】J1リーグの2025年平均観客動員数が4.4%増の21,246人 最多入場者数の2019年を超えて過去最高値 ★2 [尺アジ★]
- 【沖縄】宮古島で陸自防災訓練に抗議した団体、「恫喝された」と駐屯地トップ厳正捜査求め署名運動 「市民弾圧と戦争への道を…」 [少考さん★]
- 【実況】博衣こよりのえちえちドラクエ1&2リメイク🧪
- 鈴木大臣「お米券の使い勝手は悪くない。卵や味噌、醤油も買えます。」 [237216734]
- 正義のミカタ「中国は日本人の反高市勢力を裏で操ってる。あいつらはスパイ」 [931948549]
- 【ネトウヨは人権を嫌う】イラン、ノーベル平和賞の人権活動家を拘束 [419054184]
- 【悲報】鈴木農水大臣、ネトウヨからも叩かれ始めるwww [237216734]
- フィンランド人「吊り目ポーズの何が悪いの?ジャップも白人イジリで付け鼻したり黒人イジリで唇デカくしたりしてるよね?」 [175344491]
