Linux環境下でtest.csvの内容を順に読み込んでファイルをコピーする方法

このQ&Aのポイント
  • 9月に初めてITエンジニアとしてスタートしましたが、Linux 5の環境下でtest.csvの内容を順に読み込んでファイルをコピーする方法が分かりません。awkの組込変数NRが外部変数として使えないようで、困っています。
  • 初心者のITエンジニアですが、Linux 5の環境下でtest.csvから行の1フィールド目を読み込んでファイルをコピーする方法を知りたいです。awkの組込変数NRを外部変数として使えないため、進めません。
  • 9月にITエンジニアとしてデビューした初心者です。Linux 5の環境でtest.csvから1フィールド目を順に読み込んでファイルをコピーする方法について教えてください。awkの組込変数NRを外部変数として使えないため、困っています。
回答を見る
  • ベストアンサー

この9月にITエンジニアとしてスタートしたばかりの、初心者で恐縮なので

この9月にITエンジニアとしてスタートしたばかりの、初心者で恐縮なのですが、 linux 5の環境下で下記のような事をしようとしています。 ■test.csvの内容を読み込んで結果を出力し、その出力結果を使う。 test.csvの内容 001.txt,100,200 002.txt,300,400 このtest.csvから各行の1フィールド目を順に読み込んで cp -p 001.txt 001_200.txt cp -p 002.txt 002_300.txt という感じで新しくファイルをコピーして作成しようと考えています。 awkで順に出力してコピーしようとしたのですが、 組込変数のNRがawk内で外部変数(?すみません、ここがよく理解できていません)を使えないように 思えて前に進めない状態です。 NR==i (NR==${i}と記述するのはNG??)として for i `seq 1 N` do a=`awk BEGIN{FS=","}(NR==i){print $2}` done のように書きたいのですが、これはawkの文法から不可能なのでしょうか? 大変申し訳ございませんが、追記・追加情報必要であれば補足します。 雲をつかむようですみません。全部のコード(?)を載せるのは仕事上まずいかなと思いまして こんな書き方になってしまいました。

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

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

つい先日も書いたんだけど http://okwave.jp/qa/q6150647.html awkとシェルとはまったく別と言ってよい処理系なので、シェルの変数の内容をawkに渡すには ・シェルの置換機能を使って、awkスクリプト文字列に埋め込む ・awk の -v オプションでawkの変数に代入する という方法を使います。 ただね..... 多分、他の言語(CとかBasicとか)の考え方なのかもしれませんが、NR==で行番号指定して処理するのって、(数行だけならともかく)全行にわたって行うのはすごい無駄です。 特に、この例では行番号は関係ないですから。 先のURLにあるような方法で1行ずつ行う方が効率はいいです。 さらに言えば、処理がそのコピーだけなら、シェル変数に代入する必要すらなく、1行でできます awk 'BEGIN{FS=","} {prinf "cp %s %s_%s.txt" $1,$2,$3}' < test.csv | sh shを使わず、awkのsystem関数を使う方法もあります awk 'BEGIN{FS=","} {system( sprinf("cp %s %s_%s.txt" $1,$2,$3))}' < test.csv あるいは、awkを使わずsedで sed 's/^\([^,]*\),\([^,]*\),\([^,]*\).*/cp \1 \2_\3.txt/' test.csv | sh 先頭の指定行だけ処理したいのなら、headコマンドで head -10 test.csv | sed 's/^\([^,]*\),\([^,]*\),\([^,]*\).*/cp \1 \2_\3.txt/' test.csv | sh (この例は10行) 等々 パイプを使った処理はUnix系OSの肝とも言えるものです。 また、awkは実に便利なプログラム言語です。 解説書や解説サイトも沢山あるので、勉強してみてください。

kurokuro64
質問者

お礼

非常に曖昧な質問に対して、理解し易いご回答ありがとうございます。 慣れてないという事ではなく、根本の理解不足と勉強不足を痛感しました。 kmeeさんのようになれるには、どのくらいの期間を要するのか興味のある所ですが、 これからも解説書や解説サイトで勉強していきます。 本当にありがとうございました。

関連するQ&A

  • C言語でテキストファイルのデータ処理

    はじめまして。 僕はC言語に関して全くの初心者です。 どうぞよろしくお願いします。 例えば、 1,0,0,7,6 2,0,0,5,5 3,1,0,4,9 : : のようなテキストファイル、test.txtがある時、 1行目の4カラム目(7)と5カラム目(6)を、 それぞれの行について差し引くプログラム、 つまり全ての行について4カラム目は7を引き、 5カラム目は6を引くプログラムの事で、 この例では、 1,0,0,0,0 2,0,0,-2,-1  3,1,0,-3,-3 : : となるようなプログラムを書き、結果を出力したいのですが、よく分かりません。 ちなみにawkで書いて実行すると、 (プログラム名はtest.awkとする) BEGIN{ i=0; } { while(i<1){ v3 = $4; v4 = $5; i++; } print $1,$2,$3,($4 - v3),($5 - v4); } 実行するプログラム↓ awk -f test.awk test.txt という感じなのですが…。 これを上述の様に、C言語でプログラムを書いて、 実行するには、例えばどのようなプログラムを書けば いいのでしょうか? なにぶん初心者のため、分からない事だらけですが、 よろしくお願いしますm(__)m

  • 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" } }'

  • 今、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がシングルクォーテーションでくくられているので、 変数展開されなくて困っています。 何かよい方法があればご教授いただけますでしょうか?

  • awkの入力ファイルをリダイレクト先にする方法

    ---------hoge.txt--------- hoge hoge hoge ------------------------- 等としておいて、 $ awk '{print NR":"$1;}' hoge.txt とすると標準出力に ------------------------- 1:hoge 2:hoge 3:hoge ------------------------- と表示されますが、これを $ awk '{print NR":"$1;}' hoge.txt > hoge.txt と自分自身にリダイレクトするとhoge.txtは空になってしまいます。 hoge.txtに上の標準出力を上書きするにはどのように書けば良いのでしょうか、教えてください。 awkだけでなく、テキストファイルを入力にできるコマンド一般についても 上記のようなことができる方法があれば、教えていただきたいです。

  • AWK SQL実行後のファイル出力について

    AWK初心者です。 Linux 7.3 ※前回に続き、お教え下さい。 改行された以下のファイル(num.txt)があります。 productA productB productC productD productE このファイルをAWKスクリプトから読込み、SQLの変数に代入、実行後、productX.rptとして、出力したいのですが、「parse error」となります。 自作では、下記のようになりましたが、希望する結果には程遠いです。 修正点等、アドバイスを宜しくお願いします。 -自作- awk '{ name[FNR] = $0;} { for(i = 1; i <= FNR; i++)  { echo "----- TEST -----" selectfile "SELECT BID FROM BOX WHERE BOX.PRO_NAME like \"$name[i]\" " $name[i].rpt  } } ' num.txt -希望結果- 「productA」から「productE」毎にSQLを実行し、 その結果を同名の「productA.rpt」から「productE.rpt」ファイルを生成したい。 以上、宜しくお願いします。

  • ファイルのコピーについて

    RHEL6で、ファイルをコピーする際に以下の2通りのコマンドがあります。 --------------------- #x.txt ファイル内容の出力結果をy.txt に出力 cat x.txt > y.txt #x.txt ファイルをy.txt としてコピーする cp x.txt y.txt --------------------- 前者と後者では、効率的にはどちらも同じでしょうか。 cat(もしくはcp )を使う方がよいという場合、その理由を教えていただけますか。 お願いします。

  • バッチファイルでテキストファイルを分割したい

    テキストファイルを、指定した数値の倍数の行を、指定した個数に分割するバッチファイルを作成しようとしています。 例えば、以下の様な内容の「in.txt」というテキストファイルを3分割したい場合、 ----- in.txtの内容 ----- 1 2 3 4 5 6 7 8 9 10 ------------------------ 以下の様な内容で、 「out1.txt」「out2.txt」「out3.txt」として出力したいのです。 ----- out1.txtの内容 ----- 1 4 7 10 -------------------------- ----- out2.txtの内容 ----- 2 5 8 -------------------------- ----- out3.txtの内容 ----- 3 6 9 -------------------------- 自分はプログラミングの知識がないので、WEBに書かれている構文を少し書き換えたりして試しているのですが、うまく行きません。 AWKを使い、以下のようなバッチファイルを作成して実行してみましたが、「out3.txt」だけがうまく行きませんでした。構文の意味も分からないので修正も出来ません。 awk "NR%%3==1" "in.txt" > "out1.txt" awk "NR%%3==2" "in.txt" > "out2.txt" awk "NR%%3==3" "in.txt" > "out3.txt" AWKの解説ページを読み始めたのですが、時間的な猶予があまり無く、今回質問させて頂いた処理が出来るようになるまでまだ時間が掛かりそうなので、どなたかお分かりの方がおられましたお教え頂けないでしょうか。 AWKでなくとも、sedでもPerlでもその他のコマンドでも構いませんし、スクリプトファイルを読み込めるコマンドでしたらスクリプトでの書き方でも結構ですので、ご存知の方がおられましたらお教え頂けないでしょうか。

  • gawk複数ファイルを同ファイル名でフォーマットする方法

    gawk複数ファイルを同ファイル名でフォーマットする方法 gawkを使いcsv形式のファイルをjson形式のファイルにフォーマットしようと考えています。 簡単に説明しますと、 ●csvファイル test1.csv test2.csv test3.csv ↓↓↓↓ ●jsonファイル xxx-test1.json xxx-test2.json xxx-test3.json という風にフォーマットさせたいのです。 現在、 jsonファイル出力後の記述を ●aaa.awk BEGIN { FS = ","; printf("{"); } { printf("%s,%s,%s,%s", $1,$3,$4,$5); printf("],"); } END { printf("}"); } このようにし ●コマンドライン gawk -f aaa.awk test1.csv > xxx-test1.json これで一ファイルずつのフォーマットはできたのですが、 ファイル数が複数あり面倒なため、一気にフォーマットしたいのです。 その方法をご教授お願い致します。

  • Solarisのawkでの正規表現の使い方について

    ご存知でしたら、教えてください。 Solarisのawkで、変数に対しての比較に正規表現が使えないのですが、 よい方法をご存知の方がいましたら、教えて下さい。 nawkなら、上手くいくのですが、awkでは無理なのでしょうか? また、Linuxのawkなら、上手くいきました。 よろしくお願いします。 例)下記の場合、./test.shを実行すると、test.awkの正規表現を使用している部分[if ( $7 ~ HENSU )] でエラーになってしまいます。 --------------------test.shの中身-------------------- #!/bin/sh HENSU="3A" cat testdt.txt | \ awk -f test.awk HENSU=${HENSU} exit 0 ----------------------------------------------------- --------------------testdt.txtの中身-------------------- aaaaa bbbb ccc ddd eeeee ffffff gg3Aggggg hhhhhhh iiiii aaaaa bbbb ccc ddd eeeee ffffff gggggggg hhhhhhh iiiii aaaaa bbbb ccc ddd eeeee ffffff gggggggg hhhhhhh iiiii ----------------------------------------------------- --------------------test.awkの中身-------------------- BEGIN{ FS="\t" } { if ( $7 ~ HENSU ) { print $0 } } -----------------------------------------------------

  • awkのBEGINについて

    awkのBIGIN内で、データファイルの途中のレコード情報を取得することは可能でしょうか? 以下が行いたい詳細です。 下記例のテキストファイルの”DATE”行をawkスクリプトファイルのBEGIN内で取得したい。 例:test.txt 11111 22222 33333 DATE=20040706 44444 よろしくお願いいたします。