awkでのファイル読み込み方法について

このQ&Aのポイント
  • awkを使用してファイルを一行ずつ読み込み、処理する方法がわかりません。
  • 以前にkshとawkを使用してCSVファイルを処理した経験がありますが、記憶が曖昧でうまくいきません。
  • サンプルソースコードや参考資料など、ksh+awkを使用したファイル読み込みの方法について教えていただきたいです。
回答を見る
  • ベストアンサー

awkでのファイル読み込み

シェルを作成しています。 昔kshを作ってたので、ksh+awkでCSVファイル処理をしたいのですが、記憶が古く、覚えていないし、調べてもわかりませんでした。 参考になるサンプルソースや、参考になるHP等助言頂けたうれしいです。 ファイル読み込みがうまくいってないのか、getlineを使うべきなのか..。 #!/bin/ksh -x #Parameter Check if [ $# -ne 1 ];then echo "Error File Name Must Specified" exit 1 fi # Check File Exist ls $1 >/dev/null 2>&1 if [ $? -ne 0 ];then echo "Error File Not Found" exit 1 fi # Read File awk -F"," '{  フィールドセパレター変更→CSVファイルを一行ずつ読み込み→各処理をしたいです。 }' $1 宜しくお願いいたします。

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

現状で、何がどう「うまくいってない」のですか? > フィールドセパレター変更 -F"," でカンマに変更されています。 > CSVファイルを一行ずつ読み込み > 各処理をしたいです 何も設定しなければ、自動的に一行読んで処理を繰り返します。 一般的な処理は 条件(省略可能) {実行する内容} という書式です。 例えば awk -F',' '{print $1}' input.csv だと、input.csvを一行ずつ読み込んで、カンマ区切りの最初のフィールドが出力されます。 入力ファイルの内容によっては、期待した動作をしないかもしれません。 例えば、ファイルには日本語が使われていて、awkがマルチバイト文字に対応していない、とか。 また、kshのスクリプト中に $1 を使っていますが、指定したファイル名に空白等があると、期待した通りに動作しないでしょう。 余談) > シェルを作成しています 「シェル」といったら、kshとかbashとかそのものを指します。 あなたが作っているものは「シェルスクリプト」と言います。 > # Check File Exist > ls $1 >/dev/null 2>&1 > if [ $? -ne 0 ];then こんな複雑な方法を使わなくても、ファイルの存在を確認できます。 man test をよく読んでみましょう。 あるいは、 man ksh として「条件式」「Conditional Expressions」を読みましょう。 手許のman kshより > -e file > True, if file exists. > -f file > True, if file exists and is an ordinary file.

bauzoux
質問者

お礼

回答ありがとうございました。 数年ぶりに作るもので、今の自分には難しいと思いました。 awk処理は諦めて、別の方法を考えます。

関連するQ&A

  • awk外で宣言した変数の参照

    kshを使用して、以下のようなシェルを作成しています。 しかしawk内で$iと$iiが参照出来てない様子です。 どのようにすれば参照できますでしょうか。 ■シェルの中身 #/usr/bin/ksh for i in `cat /tmp/hoge |awk -F : '{ print $3 }' | sort | uniq -d` do if [ $i != "" ]; then for ii in `cat /tmp/hoge` do echo $ii |awk -F ":" '{ if ( $3 -eq $i ) print $ii }' done fi done ■エラー awk: 0602-562 フィールド $() が正しくありません。 入力の行番号は 1 です。 ソースの行番号は 1 です。

  • bashで、gotoのようなラベルによるジャンプ構文をしたいのですが、方法をご教授ください。

    bashで、gotoのようなラベルによるジャンプ構文をしたいのですが、方法をご教授ください。 今はif分毎で、エラー時にメール配信処理してますが、全て同じあて先配信なので、 簡潔に処理内容をまとめたいです。 echo "aaa" if [ $? -ne 0 ] then echo "error desu" > honbun.txt mailx -s "error" aaa@aaa.c.jp < honbun.txt exit 1 else echo "ok" fi echo "bbb" if [ $? -ne 0 ] then echo "error desu" > honbun.txt mailx -s "error" aaa@aaa.c.jp < honbun.txt exit 1 else echo "ok" exit 0

  • Kシェルでの read line と awk

    お世話になっております。 AIX の 標準 kshell にて下記を実行したいと考えております。 <やりたいこと> recode.txt(逐一別のシェルで内容は変更される) の中身に書かれている文字を参照して、test.txt を読み込んで該当する文字列を読み込みたいと考えています。 test.txt は編集可能なので、誤記入対策の為に、空白/タブ行、先頭空白/タブ、行末空白/タブを無視出来るようにしたいと考えています。 例) recode.txt AAAAA test.txt # ~~コメント~~ # ~~コメント~~ # ~~コメント~~ # ~~コメント~~ <AAAAA> test1 test2 test3 <BBBBB> test10 test11 test12 test13 この場合、結果として、test1、test2、test3を得て、このファイルに対して別のシェルを実行したいと思っております。 recode.txt は read line を使って読み込めるのですが、とりあえずテストとして下記のように test.txt を awk( print $1 で先頭空白、先頭タブが無視されるようでしたので) をつかってみたのですが、上手くいきませんでした。 上手くいかないというよりは、「elif [[ ${jug} == "A" ]]; then」の elif がおかしいと言われ、どうも if ~ の部分がおかしいっぽいのですが……すいません、自分ではどうも原因が分からず困っております。 【test.ksh】 (~省略~) (recode.txt 読み込み処理) jug=X while read line ; do if [[ "`awk '{print $1}' ${line}`" == "#" || "`awk '{print $1}' ${line}`" == "" ]]; then elif [[ ${jug} == "A" ]]; then if [[ `awk '{print $1}' ${line}`" == "<BBBBB>" ]]; then break fi test2.ksh ${line} <エラーチェック> elif [[ ${jug} == "B" ]]; then test3.ksh ${line} <エラーチェック> elif [[ "`awk '{print $1}' ${line}`" == "<AAAAA>" and ${recode} == "AAAAA" ]]; then jug=A elif [[ "`awk '{print $1}' ${line}`" == "<BBBBB>" and ${recode} == "BBBBB" ]]; then jug=B fi done < test.txt (~省略~) $line の扱いが間違っているのか、それとも構文的なところなのか…… orz 本業がSEじゃないのでシェルに詳しくなく申し訳ないのですが、基本的なことと存じますが教えて頂けますと幸いです。 宜しくお願い致します。 ※投稿時に先頭空白が上手く処理されないようで、回避方法が解らず、全て左につめられてしまいまして見難く申し訳ありません。

  • Kshでエラー(no closing quote):原因わかりません

    下記のようなファイル管理シェルをLinuxで作っているのですが、 test.sh[42]: no closing quote というエラーがでて解決できません。 何が原因なのでしょうか。どなたかご教授ください。宜しくお願い致します。 #!/bin/ksh #KAKUNIN_DATEから更新されているファイルをリスト KAKUNIN_DATE="10 Jul" #これを随時更新 TODAY=`date +"%x"` TODAY_YMD=`date +"%j"` START_YMD=`date --date="${KAKUNIN_DATE}" +"%j"` let n=TODAY_YMD-START_YMD #対象ディレクトリ CHK_DIR=$1 if [[ -d $CHK_DIR ]];then continue else echo "Not Dir:$CHK_DIR" exit fi #検索文字列 CHK_STR=$2 if [[ $CHK_STR = "" ]];then echo "Pls set check-string" exit fi #ファイル形式 NAME_STR=$3 if [[ $NAME_STR = "" ]];then echo "Pls set file type(if all then \"*\")" exit fi ######## メイン echo "-------------------------------------------------" echo "調査日:$TODAY 検索文字列:$CHK_STR 調査:$CHK_DIR 形式:$NAME_STR - $KAKUNIN_DATE から今日まで($n日内)に更新されたファイル" echo "ヒット,サイズ,更新日,ファイル名" find $CHK_DIR -name "$NAME_STR" -type f -mtime -$n -print| while read StrLine do if [[ `cat $StrLine | grep $CHK_STR` = "" ]];then echo `ls -l $StrLine | awk '{print 0","$5","$6,$7,$8","$9}'` else echo `ls -l $StrLine | awk '{print 1","$5","$6,$7,$8","$9}'` fi done

  • cshの条件式について教えてください

    cshで該当ディレクトリにファイルがなければOK、あればエラーというような処理をしようと思っています。 しかし、下記のような記述ではうまくできません。 1) *************************** if ( -e $DIR/*.* ) then echo "NG" exit 1 else echo "OK" endif exit 0 *************************** if文でなく、外にだせばうまくいくのですが... 2) *************************** test -e $DIR/*.* if($status == 0) then echo "NG" exit 1 else echo "OK" endif exit 0 **************************** if ( test -e $DIR/*.* ) then... でもだめでした。 どうにかしてif文で一発判定をしたいと思っているのですが、正しい記述方法を教えてください。 よろしくお願いします。

  • スクリプトファイル編集について

    ファイル編集について勉強なのですがどうしてもできません。 複数ファイル内よりIF構文を見つけてFILE_A.txtのIF書式へ変換する。 ※編集前にFILE_B.txtの変更箇所をコメント化して編集後に変換、 FILE_A.txtの書式であれば編集しない処理を作りたいと思うのですが・・・ FILE_A.txt if [ $? != 0 ] ; then   echo "てすと" fi 編集前 FILE_B.txt -- if [ -f $file ] then   echo "てすと" fi 編集後 FILE_B.txt -- #if [ -f $file ] #then if [ -f $file ] ; then   echo "てすと" fi 以上よろしくおねがいします。

  • シェルでファイルが2Gを超えているかの判定は?

    posix shでファイルが2Gを超えているかの判定を行いたいです。 size=`ls -l FILE | awk '{printf $5}'` if [ $size > 2147483648 ] then echo "2G超え" fi で、出来るかと思いましたがシェルではこのif文が行えません。 全然違う方法でいいのですが なんとかファイルサイズが2G超えか判定する方法は ありますでしょうか?

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

    シェルスクリプトで条件を指定してファイルの加工を行いたいのですが シェルスクリプト(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

  • awkについて

    度々すみません。awkについて先程教えて頂いたものですが、少し変更しようと思っているのですが上手くいきません。変更していることは、以下の○○○の内容を固定ではなくてコマンドラインから渡したいです。 ウェブで調べたところARGVというのを使うことはわかりました。そこで"○○○"からARGV[0]に変更してコマンド実行時に引数を与えたのですが、「○○○というファイルを開けません」というエラーになってしまいます。実行したのはawk -f awk data.csv ○○○です。なぜ引数をファイル名だと認識してしまうのでしょうか。初歩的で申し訳ありませんが教えて下さい。 BEGIN{ goukei = 0 count = 0 } { #フィールドの8番目の条件が一致する場合のみ9番目を合計 if($8=="○○○"){ goukei += $9 count++ } } END{ if(count!=0){ print "合計は", goukei print "平均は", goukei/count } else{ print "条件に一致するのない” } }

  • awkのファイル出力について

    今までシェルスクリプトではレスポンスが悪い為awkを使い始めました やりたい物は一応作れたのですが、ファイル出力が美しく無いので ご教授ください。 shで A="/export/home/report" echo hogehoge > $[A]/test.txt という感じで、awkの中でファイル出力させるときに パスやファイル名を変数に入れてそこに出力する方法はないでしょうか? こんな感じでやるとエラーになります。 nawk '{ BEGIN{ A="/export/home/report" } END{ echo hogehoge > $[A]"/test.txt" } }'

専門家に質問してみよう