X



シェルスクリプト総合 その27
■ このスレッドは過去ログ倉庫に格納されています
0001名無しさん@お腹いっぱい。
垢版 |
2018/05/03(木) 17:54:23.25
シェルスクリプトの総合スレです。
□お約束
・特記なき場合は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/
0329名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 11:02:49.39
>>327
住民に限定し、しかも馬鹿にしたい欲求を生んだ過去があったのだろう。馬鹿にされたとか、単になにか否定されたとか
0332名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 12:42:33.56
改行コード含んだデータ扱いたいという前提の質問かと思ったら
改行コード含んだデータなどナンセンスであるという主張だった
0336名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 13:40:18.16
なんかただ否定している感じにしか見えんけど
シェルスクリプトで扱うまでも考えて否定してんのかな?
0338名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 14:38:11.53
>>337
動くかどうかだったら動くけど
速度が遅過ぎで現実的じゃないよ
なにせ一行一行forkとプロセス起動が必要になるしね
0341名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 15:18:34.26
>>326
だってどうせCSVの話だろ?区切り文字を換える話をすると
後出しじゃんけんでソレは違うって言い出すのが常套手段
0343名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 15:59:54.35
因みにCSVはRFCで「内部改行はCRLF」と定まっているので
ここから攻めるというのもアリ。
「\r\n」という組はフィールド区切りとしては無効にすればよろし
え? CSV出力すると内部改行がLFになるLibreOffice Calc?
知らない子ですね…
0345名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:07:14.39
> "Excelから出力したCSVのように" 一行(?)の中に改行が含まれた
> データを扱うにはどうしたら良いでしょうか?

> カンマ区切りのCSVデータだと "仮定して" 、

> 今回はCSVではありませんが、


こう書いてあるのに、CSV形式だって思い込むのは
頭が悪いと思います。
0347名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:10:01.41
だったらお前がそのわけわからんCVS形式でない答えを応えれtばええんちゃんですかね?具体的に何も言ってないのに対する汎用的な
自称賢いらしいから時間かけずになんでもござれの汎用的的なのかけるだろ?
0349名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:10:50.12
>>343
> 一度全部置換してから読み取ればいいんじゃないですか(名推理

そして一行ずつ読み取るわけですねw

そりゃそうでしょう。\nを全部改行コードに戻してしてしまったら、
区別できないですからね
0352名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:12:08.78
>>347
> だったらお前がそのわけわからんCVS形式でない答えを応えれtばええんちゃんですかね

データの中に改行コードがあるってだけで、
フォーマットは最初から指定してないよ?

その場合どういうやり方があるでしょうって話なんだが、
CSVだと思いこんで効率の悪い方法しか思いつかず
指摘したら逆ギレするのやめなよ?ダサいから
0354名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:13:10.06
>>351
なにが言いたいのかわからんが、RFCのCSVの仕様に改行コードを
エスケープするという仕様はない。ダブルクォートでくくればいいだけ
0359名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:23:33.86
データ | フィルタ | シェルスクリプト(関数なり) | フィルタ > データ
フィルタをどう作るかは具体的じゃないとでCVSしか例にあげてないからCVSなだけなんだが
っていういたって普通のことなのに。そうじゃないナニかを想定しているらしけど、そのナニかの具体的なことは全く言わずに指摘wという否定なだけだもんな
その指摘もトンチンカンなこともあり、ただただ無闇に偉ぶりたいだけにしか見えんなあ
0361名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:25:32.32
>>360
それは最初&最終形態だよ。途中で処理の都合のよいようにするのに仕様もなんもないわっ
マジあほとしか思えない
0362名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:26:22.60
もう一つ解説記事

https://codezine.jp/article/detail/2364

>  改行コードはプラットフォームによって異なります。一般的にWindowsは
> <CR><LF>、UNIXは<LF>です。

>  ※2008/04/16追記:RFCでは末尾(レコードの区切りとして)の改行は
> <CR><LF>を推奨しています。CSVを解釈するプログラムではどちらの
> 改行コードでも読めるように作ることをお勧めします

> ダブルクォートで囲む場合
> "山田","太郎","値に
> 改行や,カンマや""ダブルクォートが含まれても問題ありません。"

> まれにCSVの方言で\エスケープを行うことがあります。
>
>\エスケープを行う特殊な例
>"山田","太郎","値に改行\nや\,カンマや\"ダブルクォートが含まれても問題ありません。"
> この方言はあまり普及していませんので、利用するのは避けましょう。
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
0365名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:28:23.86
CSVスレになってんのはなぜなんだ
勉強にはなるけど
0366名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:28:48.64
もう一つw
https://www.upken.jp/kb/csv.html

> RFC4180準拠
>  基本
>  ヘッダーはあってもなくてもよい
>  空データフィールドがある
>  前後にスペースがあっても無視しない
>  ダブルクォーテーションで囲む場合は同じレコードのすべてのフィールドをダブルクォーテーションで囲む
>  改行、ダブルクォーテーション、カンマを含むフィールドは、ダブルクォーテーションで囲むべき
>  ダブルクォーテーションで囲まれているフィールドでダブルクォーテーションを使用する場合は、ダブルクォーテーションでエスケープする
>  非常に長い文字列を考慮
>  複合パターン
0367名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:29:45.29
>>364
> シェルスクリプトでどう扱うかだぞ?

CSVを扱うという話はしてない
\ でエスケープするのは遅くて無駄という話ならしたがね
0371名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:36:40.96
>>368
CSVの仕様を得意げにーっていうのは

> 因みにCSVはRFCで「内部改行はCRLF」と定まっているので
↑こいつのことですかな?w

まあ、RFCでCRLFと決まってないんですがw
0373名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:39:16.71
>>372
「だいたい」しか「想像」出来てないのに偉そうだなおい
かけないんだろう?だから人にいちゃもんつけるだけなんだろ
いい加減ごめんなさいって言った方がいいぞ?
0374名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:39:21.31
1データの中に改行が含まれてる
そのままだとデータ区切りの改行と見分けがつかない
CSV形式の話はしていない

\nにエスケープする方法では、1データずつ処理しなければならず
外部コマンド呼び出しの必要があるから遅い

ここまでは理解できてんのかなー?
0375名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:39:51.59
>>371
いや、お前のこと。たぶん
それは単に利用できそうなキーポイントでそれを利用してって話でしかないな
たぶん、お前だろうが、得意げには仕様が絶対でどうであれ利用しちゃダメっていう変なヤツ
0377名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:42:26.75
>>373
だいたいの普通の人はその処理方法を想像できる「だいたい」だし、想像=書けるってことなんだが
お前が無闇に絡んでる&お前も具現生ゼロなのになんで謝らなきゃならんのねん
0379名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:45:59.83
今更なんの話かわかってませんっていうのかよ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から出力したデータのように
改行やカンマやダブルクォートやシングルクォートや空白が入ることがあるのです
0380名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:50:13.04
何を言っているのだか。最初からCSV形式のデータ扱う話なんかしてないって言っておきながら、前レスではCVSのこと「だけ」のレスなことだから、そのCVSのことだけのことを何を言いたいのかだよ

すでに書いたが、
データ | フィルタ | シェルスクリプト(関数なり) | フィルタ > データ
でしかない。CVSはどうフィルタを書く上では具体的にそれしかでしかないからだけだな

てか、その設問がそんなにきになるならお前が答えろよっw
0381名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:54:06.97
>>380
お前、実際に脳内でどう変換されるか考えてないだろ?
最初のフィルタで\nを全部改行コードにしてしまうと
シェルスクリプトで区別できなくなるんだよ。
0383名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:55:28.23
>>381
はあ????
最初のフィルタでやることは改行コードを他の何かにするに決まってるだろ。なんで逆のことをするねん?さっぱりわからん
0385名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 16:57:43.94
>>383
>改行コードを他の何かに
行端/レコードの終わりでない改行コードだけな。異次元な人なので、行端/レコードの終わりもと思われそうなので、いちおうw
0387386
垢版 |
2018/06/10(日) 17:02:32.48
最 初 の フ ィ ル タ で デ ー タ に 含 ま れ る
改 行 コ ー ド を 他 の な に か に 変 換 す る な ら ば
今度はシェルスクリプトの関数に渡す前に
改行コードに戻さないといけません

でないとこれが実現できません

> syori "a1" "a2" "a3" "a4"
> syori "b1" "b2" "b3" "b4"
> syori "c1" "c2" "c3" "c4"
>
> という風にsyori関数を呼び出したいのです。

なので1データごとに改行コードをもとに戻す処理が必要になります。
すでに指摘してますがforkが発生し遅くなります。
0388名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 17:02:57.65
言質ww
まあ、永遠に「否定だけ」してろ。もうオツムの具合わかったので、いいよ、どう思われようが
0389名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 17:04:45.37
>>385
それを実現するには1データずつ処理 
しなければいけませんね。

デ ー タ 全 体 を 一 気 に 変 換 し よ う と す る と、
区別できないんで
0390名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 17:05:24.55
>>387
言い方が伝わらなかったようで、それは残念。データの改行を他の何かにな。そういう意味での>>386なんだがなあ。まあ、言い方は悪かったかもしれない
で、その指摘はなんらアホな指摘にしかなってません...もう、いいや、勝手にしてくれ
0392名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 17:07:51.94
多分\エスケープ云々は途中でなんらか処理をする時にRFC準拠のエスケープだと不都合だからじゃないかな
「Mika says "I'm Happy"」という文を一つのフィールドとして処理するとき
RFC準拠だと
「Mika says ""I'm Happy""」になるけど、例えばこれをsed(1)やらawk(1)に通したいと思ったときは
「Mika says \"I'm Happy\"」という形にしたほうが処理しやすいでしょう?

そういうことなんじゃないかな。
0394名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 17:09:28.43
>>390
だから デ ー タ の中の改 行を何かに変 換すると
もとに戻す処 理を 一 行 一 行やらない といけないから
遅くなるって指摘をずーっと前にした
その遅く なる理由を思 いつかなかった んだろ?
0397名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 17:17:21.14
>>394
なんで一行一行なんだか。sedかtrでやりゃええことやん。それが一行一行か?
遅くなる遅くなるって遅くなるに決まってるやん。条件によりそれが妥当かどうかなんてなんでそう否定できるのか不思議でならない
んな速度速度言うなら、Cなりでやればって言うw 遅い遅い言うてるけど、お前のもじゃどうすんの?ってのがさっぱりだな
0399名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 17:22:11.92
>>392
> 「Mika says \"I'm Happy\"」という形にしたほうが処理しやすいでしょう?
今の話はもっと複雑で

「Mika says "I'm Happy
'couse picked up \10."」

という文だったらどうするか?って話なんだけどな。
いやわかるよ。どうすればいいかは。
問題はどうやってそれを実現するかって話

sedやawkに通す前に、変換すんの?
0401名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 17:25:37.95
>>397
sedやtrを使うと遅いfork、子プロセス生成が行われるからね
データ量に比例してその回数が増えるやり方は駄目
1回か固定の数回でできるって言うなら話は別だけど
0402名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 17:26:19.38
>>400
最初だけできてもだめ駄目

これが実現できないと駄目

> syori "a1" "a2" "a3" "a4"
> syori "b1" "b2" "b3" "b4"
> syori "c1" "c2" "c3" "c4"
>
> という風にsyori関数を呼び出したいのです。
0404名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 17:48:10.30
思ったんだが
正規表現でやらずに有限状態機械を作って
if ダブルクオートで始まらない
  コンマを探して終了
else
  ""でない"に続くコンマを探して終了

とすれば解決するんじゃないかな。少なくともRFC勧告に則ってるCSVは。
0411名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 20:50:13.84
>>408
後処理のだぞ。そのデータ中の改行と行の区切りの区別をつけるために最初にータ中の改行を処理して、終わったらデータ中の改行を戻すって話だぞ?
少しは処理を想像そしてからなんか言ったら?すごい近視眼で明後日な文句言う前に
0412名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 20:55:32.25
>>409
CSVじゃないからあって言うのもいるけど、だったらデータはどう表すのだろうな
データ中の改行と行の区切りの改行ってわからなくね?そのためにデータの始め終わりを表す何かが必要でそれが何かを言ってないんだったら、それを " として話をしてもおかしくはないってか、それしかないだろう
なんでそんな近視眼なツッコミばかりやねん
0413名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 20:56:07.54
>>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
0414名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 22:03:59.12
>>411
> 終わったらデータ中の改行を戻すって話だぞ?
そのときに全データの改行を一度に戻すとデータの中の改行と
データ区切りの改行の区別がつかなくなってしまうので、
1データずつ処理する=1行ずつsedなどを実行して遅くなるってことには
気づきましたか?
0415名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 22:29:15.51
>>411
データ中の改行とデータの区切りの改行はどう区別するんだよ。
同じコードだろ。しかもCSVじゃないんだろ?""でくくられてないんだぜ。
0419名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 22:49:09.09
もうそろそろ、安全な文字に変換するというアプローチ
(例えば>>289のようなもの)が
ムダで効率が悪いってことに気づきませんかね?

もう一回煽りますね?

>>323
正直、そういう解答を出してほしかったね。だせるかなーって思っていたけど
シェルスクリプトでそういうデータを扱うなんておかしいとかのたまうばかり
\x1c(ファイル分離)、\x1d(グループ分離)、\x1e(レコード分離)、\x1f(ユニット分離)は
まさにそういう用途で使うもの。ここの連中の技術力の低下を感じる。
0420名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 22:49:14.03
もう一から説明しないと、情報処理の基本すらわかってないようなので
バカバカしすぎだけど、

・改行がデータ中とレコードの終わりを示すのが混在している
・シェルスクリプトは基本、改行は改行でしかなく、データ中なんて知らんただの一行=レコードがブッタ切られる
・データ中の改行を他のナニかに変えれば、シェルスクリプトは一行=1レコードと認識する

前処理:データ中の改行だけをナニかに変える
本処理:改行が終端の一行=1レコードを処理する
後処理:ナニかに変えたのを改行に戻す

たった、これだけのことをなぜ理解できないでトンチンカンなことばっかり言うのか。前処理をsedでできるなんて言ったことないぞ(できるかもだが、それはもっと面倒なの俺は考えんw)。後処理はsedでできることは馬鹿でもわかるだろうにぃぃぃ
0423名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 22:53:10.76
>>420
> 前処理:データ中の改行だけをナニかに変える
> 本処理:改行が終端の一行=1レコードを処理する
> 後処理:ナニかに変えたのを改行に戻す

それは理解しているが、
1. 改行を何かに また 何かを改行にするには、どうやるのか?
2. 変える または 戻す 処理は1コマンドで実行できるのか?

の答えが、1行ずつfork、execしなきゃならないから
データ量に比例して遅くなるって話をしてる
0424名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 22:55:00.78
>>423
お前にじゃねえよ。お前は面倒なのでいいよw
遅い遅い言っていれば。1行ずつfork、execしなくてもいい方法もあるのにそこには考えが及ばないだろうし
0428名無しさん@お腹いっぱい。
垢版 |
2018/06/10(日) 22:58:11.88
>>426
お前馬鹿だわ
U+001EやU+001Fを区切り文字として利用するんだから
わざわざ改行コードなどを使われない文字に変換する必要ねーだろw
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況