• ベストアンサー

シェルスクリプトについて(POSIX)

シェルスクリプトを書いていますが、思うように動きません。シェルにお詳しい方がいらっしゃいましたら、ご教授ください。以下のような仕様です。 1.Working dierctoryの中から目的のファイルを検索 2.検出されたファイルの内容を1行ずつ表示させる。 このような簡単な仕様なのですが、awkを使用する必要はありますでしょうか? シェルは初めてなので勉強不足なため、ここで質問するにあたり、情報が不足していましたら、どうぞ補足してください。宜しくお願い致します。

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

  • ベストアンサー
  • onosuke
  • ベストアンサー率67% (310/456)
回答No.3

今までの話の流れで役立ちそうなディレクティブをちょっと紹介。 注:Cシェル系は記述方法が大分違います。 --------------------- #!/bin/sh for name in *;do echo $name done --------------------- 以下 $name はファイル名に当たります。 --------------------- if [ -f $name -a -r $name ];then echo $name;fi (注:[] は test コマンドです。以下と全く同じ) test -f $name -a -r $name --------------------- grep $string $name >/dev/null 2>&1 && echo true || echo false --------------------- head -$line_number $name | tail -1 --------------------- read input;echo $input --------------------- さあ,試して,man page引いて,改造してみよう。 特に,grep はモノによって多彩なオプションが使えます。 う,awk使わずに終わるかも。。。

kiroro302
質問者

お礼

onosukeさん、ご回答ありがとうございます。御礼が大変遅くなり申し訳ありません。仕事場の開発環境はそのシェルを使用してもOKなのですが、 個人のPC上でも動作を確認してみたくて、また、B系の構文とC系のものではどのくらい違うものなのか興味もあり、Bashでもかけるかしらと思い、どのシェルでもいいと書いてしまいました。とても参考になります。手元にBシェル系の参考書がなく、man pageで調べて格闘しております。自分なりに改造してみようと思います。エラー処理をどうしようか悩んでおります。 どうもありがとうございました。

その他の回答 (7)

  • onosuke
  • ベストアンサー率67% (310/456)
回答No.8

tcsh(Cシェル系)がよいのなら,POSIXは書かない方が… POSIXなシェルっていうと,BシェルかKシェルですよん(^^;;; (どっちもBシェル系)

  • mph
  • ベストアンサー率54% (39/72)
回答No.7

ちょっとやって見ました。 環境はsolarisでbashを使っています。あるhtmlファイルの複数あるディレクトリで文字列 "IPv6" を検索してます。 bash-2.03$ export HOGE=`grep ipv6 * |awk '{FS=":"} /.*/{print $1;}'|sort|uniq`;less `echo $HOGE` 一度お試しください。

kiroro302
質問者

お礼

mphさん、ご回答ありがとうございます。Bashですね。とても参考になります。私個人の環境がBashなので、いろいろ試してみようと思います。lessのところを少し変更してみようかと思っております。やはり、ユーザーに表示させたい行番号を入力させて、任意の行を表示できると、より操作が楽かなと思いましたので。 アドバイスありがとうございます。やる気でてきました。がんばります。 御礼が遅くなり大変申し訳ありません。また宜しくお願い致します。

  • mph
  • ベストアンサー率54% (39/72)
回答No.6

grep 文字列 * してその出力の先頭(ファイル名の部分)をsedやawkで切り出して、sortしてuniqした結果をshell変数にセットして、moreやlessの引数に与えるっていうのが一番簡単な気がします。 moreやlessで気に入らない場合はもう一工夫必要ですね。(perlやexをつかうか?) 一度コマンドラインでやってみて気に入ればshellスクリプトに起こしてみてはいかがでしょうか?

noname#207274
noname#207274
回答No.5

>1.行指定の入力ありでその行のみを表示、Returnを押すとその次の行を表示 基本的にはNo4で回答したものでOKと思われます。 行指定の入力の場合にReturnで次の行表示という事ですが、そうするのであれば、何が入力されたときに表示終了させるかが必要になります。 この部分は簡単だと思われますので是非、検討してみてください。 もし駄目でしたら再度補足なりにアップしてください。

noname#207274
noname#207274
回答No.4

Kshですが参考になればと思います。 (moji:ファイル名で検索したい文字です) (number:ファイルの中身で表示したい行の番号です) #!/bin/ksh print -n "INPUT MOJI = " read moji for name in $(ls | grep $moji);do if [[ -f $name ]] ; then print "File Name:"$name print -n "Max Line number ";cat $name | wc -l print -n "INPUT Line Num = " read number if [[ $number != "" ]] ;then while [[ $number != "" ]] ; do head -$number $name | tail -1 print -n "INPUT Line Num = " read number done else cat $name fi # fi done

kiroro302
質問者

お礼

HIROさん、ご回答ありがとうございます。社内にKシェルに詳しい方がいるのですが、「こういうスマートなプログラムを書けるようになれ!!」といわれました。 No.3のonosukeさんが書いてくださったプログラムと比較するとやはりおなじBシェル系で似通ったところが多いと思いましたが、コマンドなど違いもありますね。 大変勉強になります。参考にさせて頂きます。このシェルを少し自分なりに変更して、まず動作を確認してみようと思います。それから、tcshに書き直してみようかなとも思っております。 本当にありがとうございました。御礼が遅くなりまして申し訳ありませんが 今後も宜しくお願い致します。

noname#207274
noname#207274
回答No.2

すいませんがもっと詳しく教えていただけないでしょうか。下記イメージでよろしいのでしょうか。 1)directoryにある、特定の文字列を持つファイルを検索する。 特定の文字列はユーザーがkey入力する。 2)ファイルが存在した場合は、表示したい行番号を入力するかenterのみを入力する。 3)複数ファイルの場合は上記2)が繰り返し(ファイル数分)実行される。  複数ファイルの場合は上記2)でenterされた場合に次ファイルの処理に移る。

kiroro302
質問者

補足

ご回答ありがとうございます。すこし仕様を再検証してみたのですが、ディレクトリ検索の部分は手動でやって(処理をするファイルを最初から指定する)ファイルの中身を、 1.行指定の入力ありでその行のみを表示、Returnを押すとその次の行を表示  (例えばユーザーが5と入力したら、まず5行目を表示させる)     2.行指定の入力なし→Returnで全行一気に表示、 というふうにしたいのですが、いかがでしょうか? 大変恐縮ですがどうかお力をお貸しください。 シェルはできれば標準のkshかCsh(tcshならよりいいです。)がいいのですが、 Bシェルでもかまいません。宜しくお願い致します。

  • mph
  • ベストアンサー率54% (39/72)
回答No.1

不明な点 ・shellの種類はなにでしょうか? ・ファイルの検索とは? 検索の方法はなにですか? ファイル名検索の場合複数一致した場合はどうする? ・ファイルの内容を一行づつ表示とは? ユーザになにか入力させる? 一気に表示ではだめですか? この程度の説明がないと非常に答えにくいと思います。 やりたいことがはっきりしないのでなんですが、私はawk使いなのでawk使うような気がする。

kiroro302
質問者

補足

mphさん、ご回答ありがとうございます。 ・shell… POSIX ・ファイルの検索…WorkingDirectoryの中に、複数のテキストファイルがありま  す。同じようなファイルがあるため、指定した文字列を含むファイルを検索しま す。複数一致した場合はシェルの引数にファイル名を入れて実行する。以下1行ず つ表示させます.(申し訳ありません.1行ずつという表現は混乱しますね。)  例えばユーザーに行番号を入力させてその1行を表示させる、もし何も入力されず Returnキーをおしたら、すべての行が一気に表示される、というような動きを実 行させることはできますでしょうか?

関連するQ&A

  • 今、awkを使ったシェルスクリプトを作っています。

    今、awkを使ったシェルスクリプトを作っています。 aaa bbb ccc ddd ee ff gggg hhh といったファイルから、 bbb,ccc ff,gggg を取り出したいと思っています。 そこで、以下のコマンドをwhileでまわして、$iを増加させることにより、 ファイルを一行ずつ読み取り、目的の列を取り出したく思っています。 A=`cat sample.txt|awk 'NR == $i {print NR, $2;}'` B=`cat sample.txt|awk 'NR == $i {print NR, $3;}'` ところが、awkコマンドの中の$iがシングルクォーテーションでくくられているので、 変数展開されなくて困っています。 何かよい方法があればご教授いただけますでしょうか?

  • 簡単なシェルスクリプトを見てください。

    次のようなシェルスクリプトを作成しました。 #!/bin/sh echo [$1] awk '/"0312345678"/ {print}' /test > /test1 awk '/$1/ {print}' /test > /test2 のように簡単なスクリプトです。 $ sample \"0312345678\" で実行させたら、echo では"0312345678"に出力されます。 しかし、test1にはちゃんと結果が入っていますが、test2は空のファイルです。 なぜ、結果が違うのですか? 実行時、引数を渡す方法で、test1と同じ結果を得たければ、どうすればいいのですか?

  • シェルスクリプトについて

    シェルスクリプトについて Linuxで先頭にスペースが入っている行をひとつ上の行につなげたいと考えています。 その場合、シェルスクリプトはどのように書けばよいかご教示願います。 【ファイル内容】 aaa △bbb ccc ddd (b行の先頭のみスペース(△)が入っています。) 【変換後のファイル】 aaa bbb ccc ddd

  • シェルスクリプトに関する質問です

    シェルスクリプトに関する質問です 以下のようなシェルスクリプトを書きたいのですが,難しくて出来無いのでどなたか ご協力お願いします。 foldaという名前のフォルダの中に1~100のフォルダがある. それら100個のフォルダの中に,それぞれfile.txtというテキストファイルがあり,これには 112.73 のように小数点ありの数字が1行書かれている. このfile.txtの内容を全て読み取って,それら100個分のデータを 1つのファイルに出力するスクリプト スクリプトファイルはfoldaの中にあるものとする. よろしくお願いします.

  • シェルスクリプトでmd5sum

    シェルスクリプトでmd5sumを計算して2つのファイルを比較しようとしています。 /bin/sh # ファイル名を出力 echo "fileout1_${file1DirFile}"→/var/log/httpd.log 入っています。 echo "fileout2_${file2DirFile}"→/root/httpd.log 入っています。 #-- MD5値取得 file1DirFileMD5=`md5sum ${file1DirFile} | awk '{printf("%s",$1)}'` file2DirFileMD5=`md5sum ${file2DirFile} | awk '{printf("%s",$1)}'` この後、ifで「file1DirFileMD5」と「file2DirFileMD5」比較。 <質問> #-- MD5値取得 の部分の下二行で、シェルスクリプトが止まります。 止まる原因が分からないのです。(処理が進まず、止まったままになります) 原因がわからず困っております。 別の書き方でも構わないので、解決方法はないでしょうか。 ご教授お願いします。

  • UNIXでシェルスクリプトを作ることを始めましたが、まだ未熟者です。

    UNIXでシェルスクリプトを作ることを始めましたが、まだ未熟者です。 既存のスクリプトが複数あるのですが、 全てに対して同じ処理を入れ込む必要があります。 入れ込む内容はレイアウトを変更するだけ(awkで書く予定)なので簡単なのですが、 既存スクリプトに全て書き込むのは大変です。 また入れ込んだ処理内容に変更があったときに、全てのスクリプトに変更をひとつひとつ反映させるのは大変です。 入れ込む処理を別ファイルで作成しておいて、 既存スクリプトからはこのファイルを参照するだけにしたいのですが、 どのように書いたらいいのでしょうか?教えてください。

  • シェルスクリプト

    シェルスクリプトに関しては、まったくの初心者です。 OSは、SolarisとLinuxですが、シェルスクリプトを利用して下記のような自動実行プログラムを作りたいのですが、どなたかご教授下さい。 一台のWWWサーバのログ(例:access.log)を、1日に一回(出来ましたら朝の5時)に別サーバに送信するプログラムなのですがいかがでしょうか?このとき、出来れば送信先のファイル名は、送信した日付(例:20020222.log)にしたいです。説明不足かも知れませんが、ひとまずこれでお願いします。

  • シェルスクリプトで、空白(スペース)を含む変数をawkに渡したいのです

    シェルスクリプトで、空白(スペース)を含む変数をawkに渡したいのですが、どうしたらいいでしょうか? 例えば、以下のようなtest.shというファイルを作ったとします。 --------------- #!/bin/sh AAA="x y" echo "" | awk '{print $AAA}' -------------- としたとき、$AAAが正常に出力できません。(なお、echo "" は、awkを走らせる為の単なるダミーです。) printの部分を ・awk '{print '$AAA'}' ・awk '{print "'$AAA'"}' などともしてみましたが、ダメでした。どのようにすればうまくいくでしょうか?

  • シェルスクリプトで条件を指定してファイルの加工を行いたいのですが

    シェルスクリプトで条件を指定してファイルの加工を行いたいのですが シェルスクリプト(ksh)で、入力ファイルから条件に該当する行だけ抽出して出力したいと考えています。 ただ1つ条件があって、【awkは使用禁止】です。 処理としては ID00001,山田太郎,社員 ID00002,田中花子,社員 ID00003,中島次郎,派遣 というCSVファイルがあって、3列目の値が社員のものを抽出して ID00001,山田太郎,社員 ID00002,田中花子,社員 というファイルを出力したいのです。 下記のようなシェルになるとは思いますが手詰まりです。awkなら一瞬で終わるのですが、シェルだけですと3列目の抽出方法がよくわかりません。シェルに詳しい方、ご教示願えます。 while read line do if (3行目を抽出する条件); then print ${line} >> output.csv fi done < input.csv

  • シェルでファイルを読み込む

    csh を使っています。 ファイル hoge には1行に一つずつファイルの / からのパスが記されています。 hoge から 1行ずつファイルパスのリスト読み込んでそのファイルについて ls -al を行なった結果をファイル foo に保存したいのですが、どのようなシェルプログラムを作れば宜しいでしょうか? awk/sed も使える環境ですので、これらを使ったスクリプトでも構いません。 非常に初歩的な質問で申し訳ありませんが、宜しくお願いします。