• ベストアンサー

cshで文字列分割

ヤマトです。 cshの文字列分割について質問します。 環境はRed Had Linux7.2です。 set DATA = hoge1;hoge2;hoge3 のデータを";"区切りでDATA_ARR(配列)に入れたいのですが、分かりません。 調べた所、[awk]と[split]を使えばできるようなのですが、 実際どのようにSHに記述していいか分かりません。 n = split(DATA,DATA_ARR,";") をどのように記述したらよいのでしょう? 教えて頂けると有り難く思います。宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • nightowl
  • ベストアンサー率44% (490/1101)
回答No.2

こんにちは、ヤマトさん。 csh の配列というのは、例えば DATA が「foo;bar;baz」であったとき、 DATA_ARR には「foo bar baz」という値を入れたいということでいいでしょうか。 split を使えばこのようになりますか。最後には Control-D を押す必要があります。 この例では split の結果は配列 A の中に格納されます。 「DATA=$DATA」はシェル変数 DATA の値を AWK で用いる変数 DATA に代入するという意味です。 set DATA_ARR=`awk 'END{split(DATA,A,";");print A[1],A[2],A[3]}' DATA=$DATA` split を使わない別解として、標準入力を用い set DATA_ARR=`echo $DATA | awk 'BEGIN{FS=";"}{print $1, $2, $3}'` とも書けます。こちらは C-d は不要です。 BEGIN 節の中の「FS」とはフィールド区切り文字(field separator)の意味で、 AWK は $0 をこの値によって自動的に split してくれます。 なお、FS については BEGIN 節の中で記述せず、 「-F\;」のようにAWK へのオプションとしても指定できます。 (「;」をエスケープしていることにご注意) 「OFS」という出力フィールド区切り文字(output FS)もあり、 print などの出力はこれを挟んで表示されます。 初期値はスペースで、上記の例でもこの初期値を利用しています。 結果は「echo $DATA_ARR[1]」などとしてご確認ください。 独習されているようですので、いい参考書が必要でしょう。 「LINUX クイックリファレンス(第2版)」(オライリー・ジャパン)がお勧めです。 この1冊の中に各種シェルや awk, perl、GNU コマンドなどが要領よく解説されています。 お値段は高めですが、それだけの値打ちはあると信じます。 http://www.oreilly.co.jp/BOOK/linuxnut2/ AWK の参考書としては同じくオライリー・ジャパンの「sed&awk プログラミング 改訂版」 (Dougherty, Robbins 共著、福崎 俊博訳)か、 「プログラミング言語 AWK」(エイホ・カーニハン・ワインバーガー共著、 足立高徳訳/シイエム・シイ)がいいでしょう。 ちなみに「AWK」の名前の由来はこの三人 Aho, Weinberger, Kernighan の 頭文字を取ったものです。 http://www.oreilly.co.jp/BOOK/sedawk/ http://www.amazon.co.jp/exec/obidos/ASIN/4901280406/ref%3Dase%5Fseshopcom-22/250-8600902-9060234 スクリプト言語として AWK もいいのですが、基本的にフィルタ言語ですから 制御構造が標準入力を読み込むためのループに縛られる傾向があります。 今から学ぶとしたら、Ruby や Perl または Python の方がよりやり甲斐があると思います。 特に私の好きな Ruby ではこのように書けます。 ruby -e "print '$DATA'.split(/;/).join(' ')" (ba)sh においては以下のようにしてください。 ruby -e "print \"$DATA\".split(/;/).join(' ')" join は split の逆で、配列要素を区切り文字で挟んだ文字列を返します。 split の括弧の中身がシンプルなのがおわかりでしょうか。 左から右へすんなりと処理が進んでいくのは、 Ruby の「オブジェクト指向」の御利益なのです。 http://www.ruby-lang.org/ja/ http://www15.web24.jp/~c01763n1/rubytips/ 最後にちょっとお節介。 csh を使ってみて、やっぱり込み入った引用符の処理が (ba)sh に比べて洗練されていないと感じました。 最後の Ruby の実行例でも、''で囲まれて展開されないはずの $DATA が 実際には展開されたり、エスケープしたはずの「"」が 実際にはされなくてエラーになったりしました。 bash ではちゃんと思い通りの結果が得られます。 シェルスクリプト言語としては、sh をお使いになった方が リダイレクションなどいろいろと楽だと思います。 http://faqs.jmas.co.jp/FAQs/csh-whynot-jp bash でもバージョン2から配列が使えるようになっています。 表記は「${DATA_ARR[1]}」のようになります。あ、「man gawk」も忘れずに。 http://lagendra.s.kanazawa-u.ac.jp/ogurisu/manuals/awk/intro/

参考URL:
http://aoki2.si.gunma-u.ac.jp/Hanasi/Algo/awk.html,http://www.kt.rim.or.jp/~kbk/gawk-30/gawk_toc.html
jyamato
質問者

お礼

nightowlさん 有難う御座いました。 詳しく説明してくださり助かります。 色々勉強になりました。

その他の回答 (1)

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.1

以下のようなスクリプトを作成してください。 #!/bin/csh set DATA = "data1;data2;data3;data4" set DATA_ARR = `echo $DATA | awk '{n=split($0,arr,";") ;for (i=1;i<=n;i++) print arr[i]}'` echo "DATA=$DATA" foreach i ($DATA_ARR) echo $i end 実際に必要なのは3行目のset DATA_ARR...です。

jyamato
質問者

お礼

tatsu99さん 有難う御座いました。 できました!

関連するQ&A

  • cshでsubstr

    ヤマトです。 cshの文字列分割について質問します。 環境はRed Had Linux7.2です。 set DATA = A01/B/テスト文字列 のデータの5文字目の文字列は何か取得したいのですが、 substr($DATA,5,1)みたいな書き方は、 awkを使用してできるのでしょうか? ===sample.sh一部抜粋=== set DATA = A01/B/テスト文字列 set AAA = substr($DATA,5,1) ←(?) echo $AAA ===結果=== B 教えて頂けると有り難く思います。宜しくお願いします。

  • cshの文字列置換

    ヤマトです。 cshでファイル文字列を置換したいのですが、分かりません。 環境はRed Had Linux7.2です。 hoge1.txt の中の 'HIDUKE' という文字列を今日の日付に置換し、 hoge2.txt に出力するようなシェルを作りましたが、正常に動作しません。 ====hoge1.txt(置換前)==== 今日はHIDUKEです。 ====hoge1.txt(置換前)==== 今日は030814です。 ====SAMPLE.sh(一部抜粋)==== set TODAY = `date +"%y%m%d"` sed 's/HIDUKE/$TODAY/g' < hoge1.txt > hoge2.txt 以上のようなシェルを作りました。 結果として、hoge2.txtには出力されるのですが、 「今日は$TODAYです」 となってしまいます。 変数の値を置換するにはどのようにしたら良いのでしょうか? 教えて頂けると有り難く思います。宜しくお願いします。

  • cshの文字列操作(0埋め)

    ヤマトです。 cshの文字列操作について質問します。 環境はRed Had Linux7.2です。 数値を文字列に変換し、更に0埋めするのはどのようにしたら良いのでしょうか? 以下に例を書きます。 ====SAMPLE.sh(一部抜粋)==== @ NUM_AAA = 1 ECHO NUM_AAA set CHR_AAA = ××××× ECHO CHR_AAA ====SAMPLE.sh(実行結果)==== 1 01 以上の ××××× に当てはまる処理が分かりません。 C言語とかで言うなら、sprintf のような処理をしたいのですが。 どのようにしたら良いのでしょうか? 教えて頂けると有り難く思います。宜しくお願いします。

  • cshでSJISにエンコード

    ヤマトです。 cshの文字列のエンコードについて質問します。 環境はRed Had Linux7.2です。 set NAME = ヤマト のデータをSJISに変換したいのですが、できるのでしょうか? ===sample.sh一部抜粋=== set DATA = ヤマト set DATA = **** ←(SJISに変換し同変数へ格納) echo $DATA ===結果(出力SJIS)=== ヤマト 教えて頂けると有り難く思います。宜しくお願いします。

  • cshのsed

    ヤマトです。 cshのsedについて質問します。 環境はRed Had Linux7.2です。 文字列置換でsedを使っています。 置換文字列に'/'が入ってしまう場合正常に動作しません。 原因は分かります。'/'が多いって事ですよね(曖昧な言い方ですみません) どのようにしたら、できるでしょうか? 以下に、サンプルを書きます。 ====SAMPLE.sh(一部抜粋)==== set DATA_DIR = /home/hoge set FILE_NAME = hoge.txt sed "s/__DIR__/$DATA_DIR/g" < FILE_NAME > FILE_NAME.sed ====hoge.txt==== 置換した ディレクトリは __DIR__/です ====hoge.txt.sed(作成したいファイル)==== 置換した ディレクトリは /home/hoge/です どのようにsedしたら良いのでしょうか? 教えて頂けると有り難く思います。宜しくお願いします。

  • cshでファイルサイズ取得

    ヤマトです。 cshでファイルのサイズを取得したいのですが、分かりません。 環境はRed Had Linux7.2です。 hoge.txtのファイルサイズが0バイトの場合、処理を行うという事をやりたいのですが・・・ =======SAMPLE====== if ( hoge.txtのファイルサイズ = 0 ) then echo "サイズは0バイトです。" endif 教えて頂けると有り難く思います。宜しくお願いします。

  • 複雑な/による文字列の分割について

    $str = "hello/$(hoge/$(hoge/good)/id)/namae"; このような文字列を/で以下のように分割して配列に入れようと考えています。 Array ( [0] => hello [1] => $(hoge/$(hoge/good)/id) [2] => namae ) しかし単にsplitで分割してもこのようにならないので正規表現でやりたいんですがどのようにしたらこのように分割できるでしょうか??

    • ベストアンサー
    • PHP
  • awkからcshへの複数値返却

    スペースデリミタのデータファイルをcsh+awkで解析する機能を作っているのですが、shのreadを使った場合のように、複数の値をshell側に返す方法がわかりません。 例)shの場合(本当はva1,val2は1つの変数に設定したいので、あくまで例) ------------------------------------- % less list KIND1 YES NO KIND2 NO YES % less echo_hoge.sh #!/bin/sh while read val1 val2; do ←★このval1 val2に設定する手段がcshで見つからない echo $val1 $val2; done < list ------------------------------------- cshでスペースデリミタでかつ使用不可文字なしのデータファイルを行単位に処理するのは難しいと考え、awkを使って処理しようと考えたのですが、awkだと1つの処理結果しかshell変数に設定できない(ように思える)ため、困っています。 例)csh+awk ------------------------------------------------ set kind1 = `cat list | awk '{ if ( $1 == "KIND1" print $2 $3)}'` set kind2 = `cat list | awk '{ if ( $1 == "KIND2" print $2 $3)}'` ------------------------------------------------ 上記のように2回読まずにうまくshell変数に設定する方法がないか教えてください(sh使用は政治上の理由でNGです)。 よろしくお願いします。

  • C# 文字列の分割

    VS2005を使用しているものです。 複数のURL(入力)を格納したString型の配列があるのですが、 この配列から各要素(URL)の最後尾にあるファイル名だけを 取り出して別のString型の配列に入れたいのですが Splitなどを駆使すればよいのでしょうか? 例 C:\○○○\▲▲▲\××.拡張子 (元の配列の要素の一例)   などから××.拡張子の文字列だけを取り出して   別の配列に格納する感じです。 splitを使う際は\などを区切りに考えています。 for文の中でsplitを駆使しようと考えたのですが、分割した文字列を別で配列に格納して、その最後尾の要素だけ取り出したいのですが、URLの長さは入力によってまちまちなのでどのようにして取り出せばよいか困っています。 勉強不足で恐れ入りますが、何かご教授願えれば幸いです。

  • ■str_split()で指定した文字数ではなく、指定した文字までを配列に入れることは可能ですか?

    いつもお世話になっています。 文字列を配列に入れようと思って、str_split()を調べました。 $str = "Hello Friend"; $arr = str_split($str, 3); print_r($arr); の結果は Array ( [0] => Hel [1] => lo [2] => Fri [3] => end ) になりますよね?これを $str = "今日はいい天気です。遠足に行きましょう。楽しかったですね。"; としたときに、「。」までを区切りとして配列に入れることは可能でしょうか? つまり、この後何かしらのことをして、 print_r($arr); をすると、以下のように出力されるようにしたいのです。 今日はいい天気です。 遠足に行きましょう。 楽しかったですね。 str_split()で指定した文字数ではなく、指定した文字までを配列に入れることは可能でしょうか?

    • ベストアンサー
    • PHP

専門家に質問してみよう