シェルスクリプト総合 その27
■ このスレッドは過去ログ倉庫に格納されています
シェルスクリプトの総合スレです。
□お約束
・特記なき場合は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に逃げずにシェルスクリプトで処理するのが頭のいいやり方。
質問に対して問題が間違ってるといちゃもんをつけるのもやめましょう
前スレ シェルスクリプト総合 その26
https://mevius.5ch.net/test/read.cgi/unix/1489979246/ >>358
左手でつり革に捕まっていても、左手で痴漢できるそうですよ
日本の裁判所は素晴らしいです >>368
どうかしてるって言うなら、答えを書きなよ
なんど言われれば分かるんだ? >>368
CSVの仕様を得意げにーっていうのは
> 因みにCSVはRFCで「内部改行はCRLF」と定まっているので
↑こいつのことですかな?w
まあ、RFCでCRLFと決まってないんですがw >>370
答えって...だいたい想像できるだろう。めんどくさいだけで
お前のやり方がわからんわ。指摘するお前が出せよw >>372
「だいたい」しか「想像」出来てないのに偉そうだなおい
かけないんだろう?だから人にいちゃもんつけるだけなんだろ
いい加減ごめんなさいって言った方がいいぞ? 1データの中に改行が含まれてる
そのままだとデータ区切りの改行と見分けがつかない
CSV形式の話はしていない
\nにエスケープする方法では、1データずつ処理しなければならず
外部コマンド呼び出しの必要があるから遅い
ここまでは理解できてんのかなー? >>371
いや、お前のこと。たぶん
それは単に利用できそうなキーポイントでそれを利用してって話でしかないな
たぶん、お前だろうが、得意げには仕様が絶対でどうであれ利用しちゃダメっていう変なヤツ >>375
俺は最初からCSV形式のデータを扱う話なんかしてないんですが? >>373
だいたいの普通の人はその処理方法を想像できる「だいたい」だし、想像=書けるってことなんだが
お前が無闇に絡んでる&お前も具現生ゼロなのになんで謝らなきゃならんのねん >>376
だったら何を言いたいのかさっぱり。単に絡みたいだけか 今更なんの話かわかってませんっていうのかよw
↓この話だろ。「?」で聞いているところが質問だよ。それぐらいわかれアホ
Excelから出力したCSVのように一行(?)の中に改行が含まれた
データを扱うにはどうしたら良いでしょうか?
もう少し具体的に書きます。
カンマ区切りのCSVデータだと仮定して、
シェルスクリプトの中に関数を一行ごとに呼び出し、
列を引数に対応させたいです。
例えば以下のような内容のファイルがあったとして
a1,a2,a3,a4
b1,b2,b3,b4
c1,c2,c3,c4
syori "a1" "a2" "a3" "a4"
syori "b1" "b2" "b3" "b4"
syori "c1" "c2" "c3" "c4"
という風にsyori関数を呼び出したいのです。
ただし実際には各項目(a1等の部分)にExcelから出力したデータのように
改行やカンマやダブルクォートやシングルクォートや空白が入ることがあるのです 何を言っているのだか。最初からCSV形式のデータ扱う話なんかしてないって言っておきながら、前レスではCVSのこと「だけ」のレスなことだから、そのCVSのことだけのことを何を言いたいのかだよ
すでに書いたが、
データ | フィルタ | シェルスクリプト(関数なり) | フィルタ > データ
でしかない。CVSはどうフィルタを書く上では具体的にそれしかでしかないからだけだな
てか、その設問がそんなにきになるならお前が答えろよっw >>380
お前、実際に脳内でどう変換されるか考えてないだろ?
最初のフィルタで\nを全部改行コードにしてしまうと
シェルスクリプトで区別できなくなるんだよ。 >>380
× CVS
○ CSV
まあ、たぶん他でもやってるだろうけど、すまんが、読み替えてください >>381
はあ????
最初のフィルタでやることは改行コードを他の何かにするに決まってるだろ。なんで逆のことをするねん?さっぱりわからん ダメだ。異次元すぎる>>381なんて言われると、バカだろとしかおもえん >>383
>改行コードを他の何かに
行端/レコードの終わりでない改行コードだけな。異次元な人なので、行端/レコードの終わりもと思われそうなので、いちおうw >>383
> 最初のフィルタでやることは改行コードを他の何かにするに決まってるだろ。
はい、言質を取りました 最 初 の フ ィ ル タ で デ ー タ に 含 ま れ る
改 行 コ ー ド を 他 の な に か に 変 換 す る な ら ば
今度はシェルスクリプトの関数に渡す前に
改行コードに戻さないといけません
でないとこれが実現できません
> syori "a1" "a2" "a3" "a4"
> syori "b1" "b2" "b3" "b4"
> syori "c1" "c2" "c3" "c4"
>
> という風にsyori関数を呼び出したいのです。
なので1データごとに改行コードをもとに戻す処理が必要になります。
すでに指摘してますがforkが発生し遅くなります。 言質ww
まあ、永遠に「否定だけ」してろ。もうオツムの具合わかったので、いいよ、どう思われようが >>385
それを実現するには1データずつ処理
しなければいけませんね。
デ ー タ 全 体 を 一 気 に 変 換 し よ う と す る と、
区別できないんで >>387
言い方が伝わらなかったようで、それは残念。データの改行を他の何かにな。そういう意味での>>386なんだがなあ。まあ、言い方は悪かったかもしれない
で、その指摘はなんらアホな指摘にしかなってません...もう、いいや、勝手にしてくれ >>388
「言質」しらんのか?
そんなことじゃ不慮の事故で死んだ時困るぞ 多分\エスケープ云々は途中でなんらか処理をする時にRFC準拠のエスケープだと不都合だからじゃないかな
「Mika says "I'm Happy"」という文を一つのフィールドとして処理するとき
RFC準拠だと
「Mika says ""I'm Happy""」になるけど、例えばこれをsed(1)やらawk(1)に通したいと思ったときは
「Mika says \"I'm Happy\"」という形にしたほうが処理しやすいでしょう?
そういうことなんじゃないかな。 >>389
シェルスクリプトに合わせた出力すればええねん >>390
だから デ ー タ の中の改 行を何かに変 換すると
もとに戻す処 理を 一 行 一 行やらない といけないから
遅くなるって指摘をずーっと前にした
その遅く なる理由を思 いつかなかった んだろ? つーかなんでさっきから、おっぱいがいっぱいとかで
書き込めないんだ?変な言葉書いてないだろ >>394
なんで一行一行なんだか。sedかtrでやりゃええことやん。それが一行一行か?
遅くなる遅くなるって遅くなるに決まってるやん。条件によりそれが妥当かどうかなんてなんでそう否定できるのか不思議でならない
んな速度速度言うなら、Cなりでやればって言うw 遅い遅い言うてるけど、お前のもじゃどうすんの?ってのがさっぱりだな >>392
> 「Mika says \"I'm Happy\"」という形にしたほうが処理しやすいでしょう?
今の話はもっと複雑で
「Mika says "I'm Happy
'couse picked up \10."」
という文だったらどうするか?って話なんだけどな。
いやわかるよ。どうすればいいかは。
問題はどうやってそれを実現するかって話
sedやawkに通す前に、変換すんの? >>399
最後にマジれすすると最初のフィルタはひとつのawkだけでできる。めーんどくさいけど >>397
sedやtrを使うと遅いfork、子プロセス生成が行われるからね
データ量に比例してその回数が増えるやり方は駄目
1回か固定の数回でできるって言うなら話は別だけど >>400
最初だけできてもだめ駄目
これが実現できないと駄目
> syori "a1" "a2" "a3" "a4"
> syori "b1" "b2" "b3" "b4"
> syori "c1" "c2" "c3" "c4"
>
> という風にsyori関数を呼び出したいのです。 >>401,402
ダメダメ言ってないで、少しは考えろ。どっちも指摘がトンチンカン 思ったんだが
正規表現でやらずに有限状態機械を作って
if ダブルクオートで始まらない
コンマを探して終了
else
""でない"に続くコンマを探して終了
とすれば解決するんじゃないかな。少なくともRFC勧告に則ってるCSVは。 盛り上がりすぎだろwwww一日100近く伸びるってどんだけだwwww >>397
sedは改行コードで切れちゃうから、データ中の改行と行の区切りの区別をつけられないだろ >>404
CSVじゃないらしいので、"が閉じてる必要はないだろう? >>408
後処理のだぞ。そのデータ中の改行と行の区切りの区別をつけるために最初にータ中の改行を処理して、終わったらデータ中の改行を戻すって話だぞ?
少しは処理を想像そしてからなんか言ったら?すごい近視眼で明後日な文句言う前に >>409
CSVじゃないからあって言うのもいるけど、だったらデータはどう表すのだろうな
データ中の改行と行の区切りの改行ってわからなくね?そのためにデータの始め終わりを表す何かが必要でそれが何かを言ってないんだったら、それを " として話をしてもおかしくはないってか、それしかないだろう
なんでそんな近視眼なツッコミばかりやねん >>282
GNU awk の FPAT を使ってみる。一論理行のデータ数は4個で固定、という前提。
gawk -v RS='\0' -v FPAT='"(([^,\n]*)|(([^"]|\\\\"|\"\")*))"' \
'function syori(v1,v2,v3,v4){ ## ここで何らかの処理 ## }
{
i=1
while(i<NF){
syori($(i++),$(i++),$(i++),$(i++))
}
}' data.txt >>411
> 終わったらデータ中の改行を戻すって話だぞ?
そのときに全データの改行を一度に戻すとデータの中の改行と
データ区切りの改行の区別がつかなくなってしまうので、
1データずつ処理する=1行ずつsedなどを実行して遅くなるってことには
気づきましたか? >>411
データ中の改行とデータの区切りの改行はどう区別するんだよ。
同じコードだろ。しかもCSVじゃないんだろ?""でくくられてないんだぜ。 >>412
だからさ、それ、sedで書いてみろよ。
絶対おまえにはかけないから。 >>414-416
前処理と後処理を混同してあーだこーだ言われても。アホかっ >>417
言い訳はいいから書いてみろよ
前提条件は後出しでどんどん追加していいからw もうそろそろ、安全な文字に変換するというアプローチ
(例えば>>289のようなもの)が
ムダで効率が悪いってことに気づきませんかね?
もう一回煽りますね?
>>323
正直、そういう解答を出してほしかったね。だせるかなーって思っていたけど
シェルスクリプトでそういうデータを扱うなんておかしいとかのたまうばかり
\x1c(ファイル分離)、\x1d(グループ分離)、\x1e(レコード分離)、\x1f(ユニット分離)は
まさにそういう用途で使うもの。ここの連中の技術力の低下を感じる。 もう一から説明しないと、情報処理の基本すらわかってないようなので
バカバカしすぎだけど、
・改行がデータ中とレコードの終わりを示すのが混在している
・シェルスクリプトは基本、改行は改行でしかなく、データ中なんて知らんただの一行=レコードがブッタ切られる
・データ中の改行を他のナニかに変えれば、シェルスクリプトは一行=1レコードと認識する
前処理:データ中の改行だけをナニかに変える
本処理:改行が終端の一行=1レコードを処理する
後処理:ナニかに変えたのを改行に戻す
たった、これだけのことをなぜ理解できないでトンチンカンなことばっかり言うのか。前処理をsedでできるなんて言ったことないぞ(できるかもだが、それはもっと面倒なの俺は考えんw)。後処理はsedでできることは馬鹿でもわかるだろうにぃぃぃ >>418
なんでそんなに出せ出せ言うのかww
その頭の悪さというか未経験ぶりは、元の質問者か?と疑うぞ >>420に補足すると、
(POSIXの範囲では)readは必ず改行コードでぶった切られる >>420
> 前処理:データ中の改行だけをナニかに変える
> 本処理:改行が終端の一行=1レコードを処理する
> 後処理:ナニかに変えたのを改行に戻す
それは理解しているが、
1. 改行を何かに また 何かを改行にするには、どうやるのか?
2. 変える または 戻す 処理は1コマンドで実行できるのか?
の答えが、1行ずつfork、execしなきゃならないから
データ量に比例して遅くなるって話をしてる >>423
お前にじゃねえよ。お前は面倒なのでいいよw
遅い遅い言っていれば。1行ずつfork、execしなくてもいい方法もあるのにそこには考えが及ばないだろうし やたらスレが延びてるけど動くモノが出来上がる気配がない
さっさと手を動かせよ >>419
「効率悪い」のに「そういう解答を出してほし」かったの?
ちょっと意図が分かりかねるな > 1行ずつfork、execしなくてもいい方法もあるのに
それがもっと遅くなる方法だったら笑うがねw >>426
お前馬鹿だわ
U+001EやU+001Fを区切り文字として利用するんだから
わざわざ改行コードなどを使われない文字に変換する必要ねーだろw 最初の質問者じゃなかった、何を目的に延々と絡んでるのか意味不明すぎ
できないできないってばかりで あ、「安全な文字」っていうのは「通常の用途に使われるけれども日本語圏では滅多に使われない文字」の意味だったのね。
俺の解釈としてはUnicodeに収録されてる四種の区切り文字も「安全な文字」の類に入るからさ。
勘違いしてすまんな bash拡張は置換命令あるけど、
POSIXシェルの場合、外部コマンドを呼び出す以外に
置換命令はないんだよ。知ってる? >>430
> 俺の解釈としてはUnicodeに収録されてる四種の区切り文字も「安全な文字」の類に入るからさ。
まさに、ぽか〜んだわw
今度はお前にUTF-8の講釈をしないといかんのか?
Unix系で簡単に使えるUnicodeはUTF-8しかないが
(その他のエンコードは、文字の中にNULL文字が入るためシェルスクリプトで扱えない)
そのUTF-8はASCII互換であるため、U+001EやU+001Fは
ASCIIコードの0x1Eと0x1Fと全く同じであるため、
この文脈で、Unicodeかどうかなんて考える必要ないんだよ >>428
それは元々のデータがそうであるってこと?そんなんだったら別にこのスレで話題にするようなもんじゃないだろう
いつからそんなのが前提になってるねんwなんかムチャクチャぶりが...ww >>430
なんか変に絡まれてるな
全く理解できるから気にすんなw >>433
> それは元々のデータがそうであるってこと?
ちょっと違うな
「元々のデータがそうであってもよい」ってこと
元々のデータ形式について指定はないのだから
(処理するには効率の悪い)CSVデータでもOKだし、
どんなデータでもよい
そのデータ形式も含めて、
どうしたらいいでしょうか?という話だ >>435
データの改行とそうじゃない改行をどうすんの?どうやんの? まあ、そのデータもシェルスクリプトで生成はするんだけどな
シェルスクリプト1 → 何らかのデータ形式 → シェルスクリプト2
「何らかのデータ形式」のデータの中に(データ区切りの改行とは別に)
1データの値として改行等が含まれることがあるのでどうすっかなーって話 >>432
お前は>>323を引用して
> そういう解答を出してほしかった
と言ってるんだろ? UnicodeはASCIIの範囲ではそれと互換なんだからUnicodeかそうじゃないかなんてどうでもいいだろうが
お前が言ってるのは
「フィールド区切りにはカンマやアルメニア文字ではなくそれ専用に用意されている文字種を使いましょうね」
ってことだろ? なんか間違ってる?
「ポカーン」とするのもいいけれど、その前に文章をよく読め。脊髄反射でレスするな。 >>436
> データの改行とそうじゃない改行をどうすんの?どうやんの?
そこをどうするのが質問だって〜の
> Excelから出力したCSVのように一行(?)の中に改行が含まれた
> データを扱うにはどうしたら良いでしょうか?
って書いてあるんだろ >>437
ん?変換するんじゃないの?変換するなら別にコードがどの値とかは関係ないだろうし??ん?? >>438
> ってことだろ? なんか間違ってる?
間違ってるよ。
>>289 の案に対して置換すんなボケっていってる >>440
だから 改行コードとか\を 安全な文字に置換すんなってw また変換すんな君が出てるし。代替案を何も言わずに遅い遅いだけな。お前が遅々として進まんわっ >>442
> 初期から出てるだろ
残念 ながら出てない。 \ を安全 な文字に変 換ってことは
つまりデータを 変 換すると言ってる わけだが、
データは 変換(置換)するななってのが
俺の煽ってる内容 >>435
CSVのRFCはフィールド・レコード区切りにU+001F/Eを使えなんて一言も言ってねぇぞ
つーかそれこそコンマと改行が区切り文字ですよと言ってる。
そういうデータを扱うことを議論してる時に、横から偉そうな態度で
「データ区切り専用の文字があるんだから元のデータにそれを使うべき」
なんて言われてもなぁ……。
あなたは論理的思考に弱いようだからもう一度同じことを違う言い方で繰り返すと、
「前提を無視した発言は控えてください」
分かった? >>445
お前は何も進まないので、もう以後無視します >>444
代替案は >>323ででている
俺が煽ってる内容は↓これな。おまいらに>>323のような代替案をだせよって言ってる
326 自分:名無しさん@お腹いっぱい。[sage] 投稿日:2018/06/10(日) 08:14:53.42
>>323
正直、そういう解答を出してほしかったね。だせるかなーって思っていたけど
シェルスクリプトでそういうデータを扱うなんておかしいとかのたまうばかり
\x1c(ファイル分離)、\x1d(グループ分離)、\x1e(レコード分離)、\x1f(ユニット分離)は
まさにそういう用途で使うもの。ここの連中の技術力の低下を感じる。 >>446
> CSVのRFCはフィールド・レコード区切りにU+001F/Eを使えなんて一言も言ってねぇぞ
この期に及んでなんでまだCSVの話してんの?
CSVじゃないですって何度も言ってるよね? >>448
いやいやいやいやwwダメだこりゃ
なんら代替案にもなってないのだけど。なんかやけに繰り返すなwやっぱり遅々として進まんな。じゃ、お元気で >>449
お前さ&も一人さ、わざとめちゃくちゃなレスをして楽しんでるだけだろ?
もうそうとしか思えない >>450
お前本当に馬鹿だなw
1データの中に改行コードが含まれてるなら、
(データの中に含まれる改行コードではなく)
データの区切りの方を改行コードではなく、
そのために作られた制御文字を使うって話で
代替案になってるだろ
頭硬すぎw
なんで1データを必ず改行コード区切りにしないといけないのか
シェルスクリプトは1行ずつ読み取る(のが得意)ってだけで
データの区切りまで改行コード区切りにする必要はない
つーかこの制御文字がなぜ用意されているかに気づかんの?
いやはや、ここまで言わんと理解できないのか >>424
だからやり方書いてみろよ。
出来もしないくせに煽るからバカだと言われてることに気づけよいい加減w >>455
>>422を書いたのも俺なんですけど?w
readが改行コードでぶった切られるからって、
データ区切りとする必要はありませんよねぇ(にやにや >>453
なんでそんな高圧な奴に「教えて」あげなきゃならんねんwアホか
下手くそな煽りだな >>454
> なんでこんなに荒れてんのよ
俺様がたどり着いたゴールにおまいらが
どこまでたどり着けるかを試していたらこうなった >>456
ん?よくわからんな。にやけぶりがw>>422はトラップすぎだなw >>459
トラップでも何でもないよ。
readの-dでできると言われたとき、
それbash拡張だって指摘するのが面倒だから
先に注意してあげただけ >>460
あー、そういうことか。いちおう試してみていたんだけどね。できんの?
後処理が必要ないのでそれができるのなら確かにそうだな >>460,461
& 遅い君
確かにできるね。っかしいなあw
これができての、後処理が無駄という話なら全然それに異存はないな。変に絡んでいたらすまんかった >>461
ん? ようやく理解したのか?
煽りフェーズが終わると途端につまらなくなるなw
普通にできるし、俺はすでに近い形のものを実装している
自分の用途に合わせて最適化してるんで、汎用的にはなってないがな
(その後に>>282を質問という形でおまいらに問題を出したのだよ)
最初はデータの方をエスケープしてたんだが目に見えて遅くなってな
エスケープの方式をシェルビルトインのprintfでアンエスケープ
できるようにもしたが大した効果はなかった。
そこで制御文字を眺めていたら、その用途ピッタリの文字を見つけたのだよ
データとしては、0x1F(US: Unit Separator)を各項目の区切り(CSVでいうカンマ相当)
0x1Eを(RS: Record Separator)を名前の通り、データ区切りとして使ってる
USの方はIFSを使うことでPOSIX準拠でforなどで処理することができる
さらに0x1D(GS: Group Separotor)を使えば階層構造があるデータを取り扱えるだろうし
0x1C(FS: File Separator)を使えば標準入力で複数のファイルを渡すようなこともできるだろう
便利だがそれに気づいたのは>>323が最初。
おまいらは最初、シェルスクリプトで扱うもんじゃないとか言っていた
>>323のあともその使い道に気づかないでいた。まだまだだなw おまけで、一つだけ>>431に補足しておいてやろう
(もちろん>>431を書いたのも俺だけどなw)
> bash拡張は置換命令あるけど、
> POSIXシェルの場合、外部コマンドを呼び出す以外に
> 置換命令はないんだよ。知ってる?
置換命令は無いが、fork相当のことをせずにprintfも使わずに
エスケープされた文字をアンエスケープする方法はある
例えばエスケープの方式がよくある\記号を使うやり方だとして、
IFS='\' (エスケープが必要だったかも知れない)でデータをsplitして
caseで n*) なら改行を表すエスケープ文字と解釈して
一文字目のnを ${STRING#?} で削除しつつ、
改行コードを一文字目に加えるという方法だ
これはこれで遅くなるので却下したんだがなw 性格が歪んでるな。これ以後の質問者とかどうするとか思わないのだろうな >>466
もう人は俺がたどり着いた答えとは別の
もっといい案が出るのではないかと思って
先入観を与えないために、あえて俺がたどり着いた答えを出さずに
質問の形でかいた。
しかし、俺がたどり着いた答えに辿り着く前に
諦める奴らばかりだった。情けないなw ■ このスレッドは過去ログ倉庫に格納されています