質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
AWK

AWKは、UNIX 上で開発されたプログラミング言語で、CSVファイルなどのテキストファイルの処理を目的にデザインされています。

Q&A

解決済

2回答

1475閲覧

(Awk)FILENAME変数を用いてファイル別で配列に数値を代入する方法

Shiro.Shiro

総合スコア9

AWK

AWKは、UNIX 上で開発されたプログラミング言語で、CSVファイルなどのテキストファイルの処理を目的にデザインされています。

0グッド

0クリップ

投稿2020/06/02 09:14

編集2020/06/02 09:16

FILENAME変数を用いてファイル別で配列に数値を代入するために、
以下のScriptを書いてみましたが、それぞれのFILENAME==の行でsyntux errorが発生してしまいます。
どう修正すればエラーを回避できるでしょうか?

{
file1=ARGV[1]
file2=ARGV[2]
FILENAME=="file1" {Ex[NR]=$5 ; IV[NR]=$4}
FILENAME=="file2" {posi[NR]=$2}
}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

文法が間違っています。
条件 { 実行文 }
というのが構文です。

推測すると、こういうことがやりたいことでしょうか?

Awk

1FILENAME==ARGV[1] {Ex[NR]=$5 ; IV[NR]=$4} 2FILENAME==ARGV[2] {posi[NR]=$2}

投稿2020/06/02 09:54

otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Shiro.Shiro

2020/06/02 12:56 編集

ご回答ありがとうございました。 しかし、そのあとに続けてEND{print Ex[2] ; print IV[2] ; print posi[2]} を実行すると、posi[2]の結果だけが空白で出力されてしまいます。 awk -f script file2 file1の順番でコマンドを実行しなおすと次は、print Ex[2]、print IV[2]の方が空白で出力されてしまいます。つまり、二番目においたファイルについて、うまく配列に対する代入ができていない可能性が高いです。原因・解決策ともに何がご助言いただけませんでしょうか。
otn

2020/06/02 15:56

情報がないので推測ですが、file2の中身が期待通りでないのでは?
Shiro.Shiro

2020/06/03 02:24

説明不足で申し訳ございません。 質問させていただいた通り、スクリプトはそのままにして file2を第一引数、file2を第二引数に変えて再実行した際には、file2の内容、つまりEx[2]、IV[2]がprintで出力されます。したがってfile2の中身自体には問題がないと考えております。両者とも区切り文字はtabで共通でございます。
KojiDoi

2020/06/03 07:49

スクリプトはそのままとおっしゃいますが、syntax errorなく実行できたとすれば、何らかの変更はなされたのではないですか。使ったスクリプトを正しく示していただかないと、原因の特定など不可能ですよ。それと最初の数行だけでいいのでfile2の中身も示してください。
Shiro.Shiro

2020/06/03 10:30 編集

$cat file1 1 11 2 12 3 13 4 14 5 15 6 16 7 17 8 18 9 19 10 20 $cat file2 a j b k c l d m e n f o g p e q f r i s $cat script.sh FILENAME==ARGV[1] {Ex[NR]=$1 ; IV[NR]=$2} FILENAME==ARGV[2] {posi[NR]=$2} END {print Ex[2] ; print IV[2] ; print posi[2]} $awk -f script.sh file1 file2 2 12 以上の通りになっております。 質問のマナーがなっておらず大変失礼いたしました。
KojiDoi

2020/06/03 11:20

NRは通しの行番号です。よって、posi[2]は存在しないデータです。 複数のファイルを読み込んだとき、それぞれのファイルごとの行番号を使いたいときはFNRを使う必要が有ります。
Shiro.Shiro

2020/06/03 14:09

FNRに変更すると期待通りの結果が得られました。 NRは行番号がファイルごとでリセットされないが、FNRはリセットされるということですね。 非常に勉強になりました。誠にありがとうございました。
guest

0

どうも基本の基本をきちんと学ぶ必要がある段階のようなので、正解のスクリプトは敢えて示しません。ざっくり説明するのでわからない用語などは教科書を読んでください。教科書を持ってないならまず買ってください。

awkスクリプトは

パターン{アクション}

からなるブロックの繰り返しで構築されるのが基本です。

ただしどちらかを省略することは出来ます。パターンを省略した場合は、「アクションの処理内容を、入力元の一行一行についてそれぞれ行なう」という指示になります。

質問のスクリプトは全体が{}で括ってあるので、これは「パターンが省略されたアクションがひとつだけ書いてある」と解釈されます。

アクションがスクリプトの実質的な内容です。

質問の2行目、3行目はそれぞれコマンドラインの引数の一番目と2番めを変数に代入する処理ですが、このままでは上で説明した通り、入力データが百行あったとすれば100回代入操作が繰り返されることになります。明らかに不要な処理です。入力を受け付ける前に一度だけ実行したいアクションを実現するにはパターンにBEGINを指定します。

質問の4-5行目にあるのはパターン/アクションの書き方です。アクションの中にこれを書いて入れ子にすることは出来ません。条件判定を行いたいなら、ifブロックを書きます。

投稿2020/06/02 09:51

KojiDoi

総合スコア13692

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Shiro.Shiro

2020/06/03 02:26

ご回答いただきありがとうございました。 おっしゃる通り、文法規則がまだ理解しきれておりません。 今回は、「質問のスクリプトは全体が{}で括ってあるので、これは「パターンが省略されたアクションがひとつだけ書いてある」と解釈されます」この認識ができていなかったのが最大の原因であると思いました。 勉強を進めて参ります。とりあえず教科書を2冊購入しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問