シェルスクリプト総合 その28
■ このスレッドは過去ログ倉庫に格納されています
シェルスクリプトの総合スレです。
□お約束
・特記なき場合はBourne Shell(/bin/sh)もしくはPOSIX準拠の互換シェルがデフォルトです。
bash/zsh/ksh/ash/dash/yash/poshなどの専用機能に依存する場合は明示しましょう。
Linuxユーザは/bin/shの正体がbashまたはdashなので特に注意。
FreeBSDユーザは/bin/shの正体がashなので注意。
・POSIXについてのリンクは https://en.wikipedia.org/wiki/POSIX にまとめられています
最新の仕様はこちらへ http://pubs.opengroup.org/onlinepubs/9699919799/
(左上の「Shell & Utilities」 から参照することができます。)
・v7 shに一番近くて、現役(?)のshは、OpenSolaris由来のheirloom sh。
http://src.illumos.org/source/xref/illumos-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に逃げずにシェルスクリプトで処理するのが頭のいいやり方。
質問に対して問題が間違ってるといちゃもんをつけるのもやめましょう
シェルスクリプト総合 その27
https://mevius.5ch.net/test/read.cgi/unix/1525337663/ >>185
引数で単語と数字nを受け取ってn文字目の単語を返す関数を書けばいいだけ >>189
日本語ではなくてbashでお願いします!! >>188
結果だけ見たら
入力テキストをカンマで区切って
最初の数値を取得 ⇒ nとする
残りの文字列のn番目の文字をアッパーケースに変換して空白区切りで連結する
かな
俺ならテキストが小さいならBashで一気に読んで処理すればいいと思うしでかいならPythonとかで処理する > 俺ならテキストが小さいならBashで一気に読んで処理すればいいと思うしでかいならPythonとかで処理する
これはなんで? 小さいとかの境目はどれくらい? そんなこと聞いてくるようではセンスがないよ
センスがない奴にいくら説明しても無駄 pythonだと単語のn文字目を取り出すなんて朝飯前だしな
関数書く手間が一つ省ける 疑問になった点は「テキストが小さいなら」です。
その他の話は聞いてません。 > pythonだと単語のn文字目を取り出すなんて朝飯前だしな
単語の3文字目(オフセット2から1文字)を取り出す
echo "${str:2:1}"
Pythonだとどう朝飯前なんですか? 早く答えのスクリプトを書いてください!!
遅いですよ!! >>195
個人的には今どきなら1MB以下なら小さい1GB以上ならでかい
その間ならケースバイケース
PCの性能やメモリ容量とかと相談 >>185
> 一度ファイルを最後まで空読みすれば
これはどういうスクリプトなの? >>198
1MBってことは、1行256バイトとして4096行以下なら小さいってことですね。
10MBで約4万行、100MBで約40万行、1GBで400万行
昔のExcelの制限が1シート65000行だったことを考えると
エクセルで扱えるデータなら問題なさそうですね アスペかよw
アスペならちゃんと改行コードも数えるんだぞ? >>201
お前なんのためにレスしたの?
>>200が言ってることは正しいし、お前の主張は何も含まれていない。
ただ、レスしただけ 185です。説明不足ですみません。
やりたいことは1行目を読み取り、2行目以降はそのままwhileループで最後まで読みたいのです。
ただそのためだけにフラグを使うのもなんだかなぁと。 わざわざ空読みする理由が分かんねえ
今出来てる状態のスクリプト貼って何がうまく行かないのか説明してみ >>205
そこまでは上手く書けてる
その調子で頑張れ >>190
今日一番ワロタ
キミもbashで質問しなよ bash は重複しない4文字である。つまり2bitのデータと考えられる
日本語を1文字16bitのデータと考えると、
1文字をbashの4文字×8組=32個のデータで表現できる
つまりbashで質問すると32倍のデータが必要になる
1レスに2048バイト、1024文字を書き込めるから32文字の質問であれば
bashで質問することは可能 >>208
> 1文字をbashの4文字×8組=32個のデータで表現できる
この行から間違えてるだろ >>199
こいうんじゃね?
というのを期待してた?残念w >>211
while IFS=, read は思いつくけど
最後まで空読みってどんな処理なのか気になっただけ >>196
>>> str = "foobarbaz"
>>> print(str[3])
b
python3は重いかわりに色々便利なのが定義されてる タブで字下げされてるテキストファイルの中にある
_TAG("S.T.A.R.T") が含まれる行と
_TAG("E.N.D") が含まれる行との間にある行数を数えるにはどうすればいいでしょうか ...... | sed -n '/_TAG("S.T.A.R.T")/,/_TAG("E.N.D")/p' | wc -l
こんな感じ さんくす
sedやwcなどの外部コマンド?を使わない方法はありますか? >>216
そういうことするなら
perl5に行きなよ
普通はそれも最初から入ってて、文字処理に強い言語だから
---
そんな処理だと、その処理の前に
タグがネストしてたり、正しく対になっているのか調べれた方が安全
おみあげに類似したコードあげる
https://ideone.com/XCz8Ou
対が壊れてたら -1 を
壊れてないならネストの最大の深さを返す >>214
問題の意図が明確
その _TAG("S.T.A.R.T") とかは字下げされているのかどうなのか
_TAG("S.T.A.R.T") が含まれてると言うが、
一行 は _TAG("S.T.A.R.T") だけではないのか?
echo ' _TAG("S.T.A.R.T")' なんかも考慮する必要あるのか?
俺だったら一行まるまる、_TAG("S.T.A.R.T") だけにするがな
その方がパースしやすいので あと _TAG("S.T.A.R.T") は複数あるのか?という質問も追加
ネストされている場合は考慮するのか?とか まあいずれにしろテキストファイルは read で読み込めるんだから
こんな感じになるだろうが
while IFS= read -r line; do
case $line in
'_TAG("S.T.A.R.T")') なんとか ;;
'_TAG("E.N.D")') かんとか ;;
esac
if 条件; then
count=$((count + 1))
fi
done < テキストファイル >>218みたいにそういう場合だったら Perl にとかいうやつがいるけど
シェルスクリプトで同等のコードを書いても大差ないんだけどなw sedやwc使うなとかいう制約も謎だわ
言語やツールが何であれ結局裏で似たようなライブラリの関数呼び出すのに 理由がわからないなら普通に聞けばいいだけなのに。
自分が知らないだけなのに、なんでそんなことありえない、
あってたまるかみたいな書き込みをするんだろうねw 理由がわからないんじゃなくて、そんなことを言い出す人間が理解できないって話だよ
こだわりがあるならこんなところで人に聞くんじゃないよって話で 自分とは違う方針の質問は受け付けない
そんなレスはこてんぱんにしてやる。ですか? 自分の期待とは違う方針の回答は受け付けない
そんなスレはこてんぱんにしてやる。じゃないの? >>227
スレの流れ見たけど受け付けられてるじゃん
宿題を済ませたいのか知らないが
人に聞くくらいなら針路変更したらどう?
知り合いにコンピューターの勉強してた人居るけど
大学で課題をすべて友人からパクってたそうだ
今その人バイトで食いつないでる
ITの仕事できたら低くても年収400万は行ったろうにね >>229
知り合いの人は大学をやめて会社を起こして金持ちになったよ。
お前が何をいいたいのか知らんが >>228
さんくすとお礼を言った上に、条件をつけ忘れてたから
補足しただけでしょ
たったそれだけで、はぁ?理解できない。謎だわ。なんでそんな事するの?バカなの?
みたいに言うのはなんで? >>230
知り合いは宝くじ当たったよ
中卒、高卒、大卒の平均年収見てみ 問題を解決できないやつは
学歴がなんでも大成しないな 2chは口が悪いやつが多いけど
ここ見てると分かるように無償で相手してくれるやつがいるんだな
現実はどうだろう
そんなことないよ
社会に出れば分かるがフリーライダーは受け入れられない
街角でスケッチブックに助けてくださいって掲げるのか?
そんなの通報されて終わるよ
SNSなら答えてくれるって?
フォロワーも居ない人の相手なんて誰もしない
要するに2chしか質問する先がないんだ >>231
何で逆切れするの?
仕事は自分でしましょう >>231
>>227があなたの書き込みなら
あなたが煽っただけでしょう
そして>>227があなたではないなら
なぜそんな反応するのか分からない 課題か仕事か知らんが問題を片付けてくれたのになぜ素直になれないんだろうか
仕事だったら出来上がらないから検収されずに報酬もらえないぞ JavaHouseってのがあって明らかに仕事に関係するであろう質問してた輩に
運営者の人がそれ幾らなのって聞いてたな
聞いた本人は無料ですってなんか意味の分からんこと言ってたが 課題をこなせず大学をやめて成功したって丸投げ派遣会社でも設立したんか >>240
人の話がシェルスクリプトと何の関係があるのという話だ
人の話をし始めたやつにいえな >>243
全ての質問に対してそういう回答をしてるなら何も言わんよ >>230
まあ今どきの日本人はだいたいビル・ゲイツは知り合いだからなw >>244
でたでたw
なぞの平等理論w
あいつだけずるいとかいう妬みで周りが見えなくなってるんだろうなあ 自分なら質問者が
「今こうやってるけどもっと効率のいい方法ない?」
とか聞いてきたら答えてあげたくなる
一度答えてそーじゃねーよとか言われたら・・・w 一度答えてそーじゃねーよと言われたら?
↓これみて「そーじゃねーよ」言われたと思っちゃったの?
215 名前:名無しさん@お腹いっぱい。[sage] 投稿日:2020/04/11(土) 11:20:47.30
...... | sed -n '/_TAG("S.T.A.R.T")/,/_TAG("E.N.D")/p' | wc -l
こんな感じ
216 名前:名無しさん@お腹いっぱい。[sage] 投稿日:2020/04/12(日) 07:36:15.54
さんくす
sedやwcなどの外部コマンド?を使わない方法はありますか? 沸点が低いんだろうなぁ。
少しでもなにか言われたら、親を侮辱されたかのように感じるんだろうな なんとなく答える前に
sedやwcなどの外部コマンド?を使わない方法はありますか?
と書いても、同じようにキレていそうな気がするなw レスしただけでこの反応w 矛先をずらしているのもありがちだなぁw >>220-221
その _TAG("S.T.A.R.T") とかも字下げされてます
echo ' _TAG("S.T.A.R.T")' なんかも考慮する必要はありません
_TAG("S.T.A.R.T") は複数ありません
ネストもありません
>>222
可能ならman bashで出る内容だけで解決したいです。
_TAG("S.T.A.R.T")や_TAG("E.N.D")の前後にも行はあるので、わかりやすく
_TAG("S.T.A.R.T")なんとか
count=$((count + 1))
_TAG("E.N.D")かんとか
ならベストなのですが。 >>253
while文で1行ずつ読んでSTART見つけたところからカウントしていってENDが見つかったら終了すりゃいいだけじゃないの
自分でどこまで作ったの? >>254
もういいから早くスクリプト作れって言ってんだよ >>255
なら今からman bash読むわ
ちょっと量が多いから1週間待ってな
忘れるといかんからまたその頃に催促してくれ 自分で man 読んで自分で出来るようになる方が自分にとって有益だと思うんだが… awkでやればできるよ!・・・全部BEGIN
これ萎えるw フレッシュなニンニクジュースを飲めばコロナの菌が死滅する この板の住民なら生ニンニクで腸内細菌死滅して病院送りになるのは知ってそう 言うほどUNIXやシェルスクリプトってコロナ菌に関係あるか? [ と [[ の違いなんかも理解できてないままflgやcontinueを使って書いてみました。
_TAG("S.T.A.R.T")の後でもループの度にflgをチェックするのが無駄なので
_TAG("S.T.A.R.T")を探すループと_TAG("E.N.D")まで行数を数えるループを完全に分けてflgを無くしスッキリ出来たらいいのですが。
declare -i i=0
declare -i flg=0
for f in `cat $INPUT_FILE`
do
if [ $flg == 0 ]; then
if [[ "$f" =~ \t*'_TAG("S.T.A.R.T")' ]]; then
flg=1
else
continue
fi
else
if [[ "$f" =~ \t*'_TAG("E.N.D")' ]]; then
echo 行数は $i
exit 0
else
i=$i+1
fi
fi
done >>264
> ループを完全に分けてflgを無くしスッキリ出来たらいいのですが。
まず for f in `cat $INPUT_FILE`を使うのはやめよう
シェルスクリプトでテキストファイルを読むならwhile + read を使う
そしてread は read してから read すると次の行を read する(当たり前だw) 一応それらしいのを書いてみました。
exitがあるのと、whileループの前と中にreadがあるのがちょっと不満です。
後チェックができるように do; read; while という使い方ができればいいのですが。
declare -i i=0
while : ; do
read f <- 不要かも
while [[ !("$f" =~ \t*'_TAG("S.T.A.R.T")') ]]; do
read f
done
read f
while [[ !("$f" =~ \t*'_TAG("E.N.D")') ]]; do
i=$i+1
read f
done
echo 行数は $i
exit
done < $INPUT_FILE そもそも done < $INPUT_FILE とか書く必要ない
script.sh < $INPUT_FILE とやればいいんだよ
その方が柔軟性が高くなる
そうすりゃスクリプトは中身だけで良くなる。endはいらない。
そして while read do にも置き換えられるやろ?
read f <- 不要かも
while [[ !("$f" =~ \t*'_TAG("S.T.A.R.T")') ]]; do
read f
done
read f
while [[ !("$f" =~ \t*'_TAG("E.N.D")') ]]; do
i=$i+1
read f
done
echo 行数は $i 後出しっぽくてすみません。
$INPUT_FILE は_TAG("S.T.A.R.T")や_TAG("E.N.D")と同じく固定名なので汎用性は不要なんです。
それにこの部分はscriptの一部で本体には引数があるため毎回script.sh 引数 < $INPUT_FILE とやるのはちょっと...
といって、このためだけに分割するのも... じゃあ
{
なかみ
} < "$INPUT_FILE"
とかすればいい $ eval "<"
bash: 予期しないトークン `newline' 周辺に構文エラーがあります
これってどういうこと? そりゃ < をbashに渡すから
$ <
と同じ結果になる訳で おふたりありがとう
たしかに
$ <
と同じ結果になった
でもnewlineというのはどこにも記述してないのにどうして `newline' なんだろう?と >>275
パーサーが入力の「末尾」も改行文字と同じに扱っている
または入力末尾に改行文字を追加してからパースしている
といったところじゃないかな あー、そういうことか、なるほどわかりました
日本語の中に突然newlineが出てきて、しかもわざわざクォートされてるからてっきり予約語かと思い込んでいた
というか目に見えない予約語なんだろうけど
ありがとうございます >>164
win鯖管か個人用途のみで使うなら7系はいいものだと思うけど、数百MB食うpwshがunix界隈で受け入れられるとはとても思えない
まあ新興非b系シェルは駆逐されるかもしれんが
そもそもまだMacとlinux主要ディストロにしか公式対応してないので
IT職でなく、単にツールキットを享受できればいい人ならpwshでいいと思うよ
たとえ趣味や仕事でも(だけど時代遅れな)b系シェルの技能は汎用性あるから、あえて普段から使うのも勉強になるよ あと怒涛の互換性ブチ壊しバージョンアップ中だから、せっかく書いても一年で動かなくなる
まだソフトウェア開発には使えないのが現状 シェルスクリプトの特徴は「人間がそのまま読むことが出来る1行1データのテキストを扱う」という点なんだわ
シェルスクリプトは分かりづらいからPerlやPythonを使うとか言ってるやつがいるけど
1行1データのテキストを扱うならば、シェルスクリプトが一番うまく処理できる
正確に言えば、シェルスクリプトだけじゃなくてUNIX系のCLIコマンドがそれを前提としたインターフェースになってる
CLIコマンド=シェルスクリプトのAPIなんだよ
pwshがunix界隈で受け入れられないのは、APIが全く違っていて互換性がないから
API=CLIコマンドなので、プログラマの多くはAPIコマンドを知ってる
シェルスクリプトがいつまでたってもPerlやPythonに置き換わらないのも
それらの言語はCLIコマンドというAPIを使わないから
CLIコマンドを使うならば、シェルスクリプトより簡潔に書ける言語が存在しない シェルなんだから外部コマンドは呼べるし、テキストも扱えるしそんなに変わらんのでは
そんなに変らんということはすなわち、わざわざunix環境で使うモチベとしては弱いと思うが
ドザーが流行りのwsl使うのには便利なんじゃね 昔ながらのwinコマンドは大体外部コマンドだけど、pwshはほとんど組み込みコマンドなのがなあ
slsとか分けて提供してくれればbetter grep/findとして個人的には使いたいんだが >>283
Windowsのコマンドはスクリプトから使うことを考慮されてない物が多い
例えば、copyコマンドは、copyすると
1 個のファイルをコピーしました。
とか人間のためのメッセージが出てくるからテキスト処理に向かない
バッチファイルは人間が操作するのと同じことただやるだけ
(出力を加工しない)なのでバッチファイルから使う分にはそれでもいいが
シェルスクリプトのように出力と入力をつないで処理することには向いていない
だからpwshはWindowsのコマンドを呼び出さない
一方pwshで使うAPIは1行1データのテキストにはなってないし
普段使ってる外部コマンドではない
どちらかと言えばPythonなどの関数に近い
Unix/Linuxの外部コマンド・・・1行1データのAPIインターフェースでCLIからも参照する
pwsh、Python、多くの言語・・・引数と戻り値のAPIインターフェースで言語内から参照しない
APIのインターフェースが大きく違っていて
Unix/Linuxの外部コマンドは改行の扱いが難しいなどの制限があるが
その制限の範囲内ではスクリプトからも人間からも使いやすくて
他の言語には置き換えることが出来ないんだよ Windowsでシェルスクリプト動かそうとすると、パスの\のエスケープで気が狂いそうになるから
その辺捨てたパワーシェルの割り切りは、それはそれで理解できるけどなー >>286
Windowsでシェルスクリプトって何を使ってるの?
パスの\のエスケープなんかしたことないよ
pwshはスクリプト言語としては悪くないと思うよ
ただPythonなんかと同じようなプログラミング用の言語ということ
Pythonにも当てはまるけどプログラミング用の言語は
シェルスクリプトとはスタイルが異なる。
シェルスクリプトは端末操作に特化した言語だから
プログラミングはしにくいが端末操作は得意
まあPowerShellでも普段からコマンドレット使って端末操作してます。
pwshでもコマンドレットをメインで使いますって人なら
シェルスクリプトと同じような感じに見えるかもしれないけど
そんな人いるのかな? ■ このスレッドは過去ログ倉庫に格納されています