cシェルの中でawkのユーザー定義関数を使う方法について教えてください。
以下の内容の入力ファイルがあったとして、
3 3 306
2 2 258
1 1 105
3列目を数値の大小に応じて、別の数値に置き換えて以下のファイル
3 3 10
2 2 9
1 1 8
を出力したいのです。
cシェルスクリプト中でawkのユーザー定義関数を使って作成したいのですが、シェルスクリプト中に関数をどこでどう定義してよいか分かりません。
cシェルスクリプトの中身は
#/bin/csh -f
gawk'{print $1,$2,symbolsize($3)}' input_data > output_data
で、以下の関数を定義したいのです。
function symbolsize(ccc){
if (ccc >= 300)
return 10 #300以上なら10を返す
if (ccc >= 200 && ccc < 300)
return 9 #200以上300未満なら9を返す
else
return 8 #それ以外なら8を返す
}
プログラミング初心者なので、なにとぞよろしくお願いします。
No.1
- 回答日時:
Cシェルでシェルスクリプトを書くのはお勧めできません。
Cシェルでなければだめなんでしょうか?
質問にあるようなスクリプトであれば、シェルスクリプトではなく
awkスクリプトの先頭を
#!/usr/bin/awk -f
にしたスクリプトで起動してやればいいような気がします
(awkに対する入力と出力は)与える必要がありますが。
どうしてもCシェルスクリプトで解決したいということなら
gawk '\
function symbolsize(ccc){\
if (ccc >= 300)\
return 10 #300以上なら10を返す\
if (ccc >= 200 && ccc < 300)\
return 9 #200以上300未満なら9を返す\
else\
return 8 #それ以外なら8を返す\
}\
{print $1,$2,symbolsize($3)}\
' input.txt
のように行末にバックスラッシュ(円マーク)を置いてやればできますが、
awkスクリプトの内容によってはエラーになる可能性があります。
最低でもBourn シェルを使ったスクリプトにすべきです。
参考URL:http://www.kiso.tsukuba.ac.jp/~makimura/text/nod …
回答ありがとうございます。うまくいきました。
Cシェルを使うことについて、リンク先も拝見しましたが、
もともと、このスクリプトは業務で使っているもので、私は、そのプログラムの
一部を書き換えているだけなので、ご指摘のように他のシェルに書き換えたりすることは
すぐには出来そうにありません。(実際は、他の処理もたくさん入っているプログラムなので
なおさら、、、)
とりあえず、cシェルで動く状態にして、ゆくゆくはBourneシェルに書き換えるか、
プログラミングの勉強もかねて、perlかrubyを使おうと思っています。
役に立ちました。どうもありがとうございました。
No.2
- 回答日時:
awk部分は1行に書き切れる量ではないので
(本当は#1さんの回答のとおり書けなくは無いですが、
可読性が悪いので)、
awkスクリプトを別ファイルにした方が良いと思います。
(fiter.awk)
#! /usr/bin/gawk -f
{
print $1,$2,symbolsize($3)
}
function symbolsize(ccc){
if (ccc >= 300)
return 10 #300以上なら10を返す
if (ccc >= 200 && ccc < 300)
return 9 #200以上300未満なら9を返す
else
return 8 #それ以外なら8を返す
}
(filter.awkを呼び出すcshスクリプト)
#! /bin/csh -f
gawk -f filter.awk input_data > output_data
どうしても1つにまとめたいのであれば、
次のような方法があります。
(1)1つの言語にまとめる。(この場合、awkだけで書くとか、
perlの使用を検討するとか)
(2)ヒアドキュメント機能を使う。
下の例で説明すると、「<<"END_OF_FILE"」と「END_OF_FILE」で
囲まれた部分が実行時にテンポラリファイルとして
作られ、それをawkスクリプトとして使用しています。
#! /bin/csh -f
gawk -f - <<"END_OF_FILE" input_data > output_data
{
print $1,$2,symbolsize($3)
}
function symbolsize(ccc){
if (ccc >= 300)
return 10 #300以上なら10を返す
if (ccc >= 200 && ccc < 300)
return 9 #200以上300未満なら9を返す
else
return 8 #それ以外なら8を返す
}
END_OF_FILE
回答ありがとうございます。たしかに、awkスクリプトを別ファイルにすれば、
シンプルで分かりやすくなりますよね。
私は、この質問を投稿する前に、関数を定義する部分function symbolsize(ccc){・・・}だけを
別ファイルにしたのですが、これを
awk'{print $1,$2,symbolsize($3)}' input_data >output_data
の中にどう組み込んでいいのかわからずにいました。
最初から{print ・・・ }の部分も一緒に別ファイルにしてしまえば、
awk -f ファイル名 input_data >output_data
で動いたのですね。
関数を定義する部分だけを1つのファイルにすれば、別のスクリプトで関数を使うことも出来て
便利だと思ったのですが、無理なのでしょうか
とにかく役に立ちました。どうもありがとうございました。
No.3
- 回答日時:
#2です。
「-f script-file」オプションは、2つ以上指定することが出来て、
その場合、それらは連結された1つのスクリプトファイルのように
扱われるので、
便利な関数の集まりを1つのスクリプトファイル(functions.awk)にして
次のように書くことが出来ます。
|gawk -f my.awk -f functions.awk input_file > output_file
本当は、個別処理(my.awk)はcshスクリプト中に直接書きたいのですが、
コマンドラインに直接書くやり方(awk '{print...')と「-f」オプションは
混在できないようです。
一応ヒアドキュメントを使って以下のように書くことは可能です。
「-f -」は標準入力(ヒアドキュメントの内容が入る)を
スクリプトファイルとして扱うことを指定します。
|gawk -f - -f functions.awk <<"END_OF_FILE" input_data > output_data
|{
| print $1,$2,symbolsize($3)
|}
|END_OF_FILE
プログラムファイルの前に-fをその都度付ければ、連結できるんですね。初めて知りました。
ヒアドキュメントの使い方も参考になります。「-f -」なんて
私には到底思いつきそうにないので。
十分参考になりました。ありがとうございます。
No.4ベストアンサー
- 回答日時:
#3の内容に関して補足です。
-f オプションの複数指定は、gawkでは問題なくできますがどのawkでもできるとは限りません。
(試せないけど Solarisのawkは怪しいと思う)
で、gawkを使ってよいという前提であれば
gawk -f functions.awk --source='print $1,$2,symbolsize($3)'
という記述ができます。
なるほど、gawkでは--sourceを使えば、
ファイルに記述したスクリプトと直接書いたスクリプトを連結できるわけですね。
私の使っている環境はgawkではないので、(質問文中にはgawkと書いてしまいました。すいません)
試すことができませんが、これを機にgawkをインストールしようと思います。
有用な情報、どうもありがとうございました。とても役に立ちました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Visual Basic(VBA) Excel のユーザー定義関数でソルバーが動作しない 1 2022/09/05 19:51
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- JavaScript HTMLでJavaScriptを使ってパスワードの強化判定のプログラムを作成しています。 一通り作っ 2 2022/10/19 01:41
- その他(プログラミング・Web制作) Linuxについて質問です。 引数に指定されたアクセスログのファイルからアクセス数が多い順に上位3つ 1 2023/02/03 03:46
- その他(教育・科学・学問) エクセル関数について 2 2022/12/23 08:59
- C言語・C++・C# C言語の課題が出たのですが自力でやっても分かりませんでした。 要素数がnであるint型の配列v2の並 3 2022/11/19 17:41
- UNIX・Linux Linuxについて質問です。 シェルスクリプト名をfind.shとして、以下の条件をすべて満たすファ 1 2023/02/03 03:50
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- UNIX・Linux 次の要件を満たすにはどのように修正したらよろしいでしょうか 1 2022/11/24 20:57
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA 電話番号の正規表現について
-
プログラマーと学歴の関係性に...
-
vba クリップボードクリアにつ...
-
このURLで広告を出しているのは...
-
ImageMagickでgif画像の一部が...
-
小学1年生の子です。塾に行かせ...
-
プログラミングのPythonのnoteb...
-
GoogleAppsScript文字列置換の...
-
楽しくて最高のプログラミング...
-
ホワイトハッカー
-
プログラミング ソースコード
-
ものづくりに向いているプログ...
-
大学のゼミのレポートがムカつ...
-
スカラーのベクトル微分
-
初心者powershellのPS1ファイル...
-
Google ColaboでGUI作成
-
プログラミングで例えばゲーム...
-
Powershellとコマンドプロンプト
-
MacのPythonでの開発について
-
Latexに関する質問です。
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
プログラミング
-
小学1年生の子です。塾に行かせ...
-
vba クリップボードクリアにつ...
-
プログラマーと学歴の関係性に...
-
Webサイト内に埋め込んだmp4動...
-
正規表現で複数マッチ条件で悩...
-
windowsでテキストファイルの各...
-
楽しくて最高のプログラミング...
-
プログラミング ソースコード
-
Pythonって何を意識した言語な...
-
プログラミングを教えたいです...
-
pythonで複数画像からgifを作る...
-
pythonにてseleniumを使うも、...
-
Pythonでgif画像が上手く作れない
-
Google ColaboでGUI作成
-
テキストファイルのファイル名...
-
プログラミング、アーキテクチ...
-
そのまま使っただけなのに・・...
-
このURLで広告を出しているのは...
-
chatGPTで次々と質問をしていく...
おすすめ情報