• 締切済み

awkで複数ファイルのある列を抽出し出力したい

awkプログラミングの初心者です。 今、複数ファイル(1000ファイル)から、それぞれある列(すべて同じ列番号)のデータを抜き出して、1つのファイルに出力したいと考えています。 具体的には、1列目に共通項、2列目以降に1000ファイル分の抽出された列を、合計1001列となるような1つのファイルとして出力したいと考えております。 awkを使って出力するには、どのようなスクリプトを作ればよいか教えていただけませんでしょうか。 <イメージ> 元となるファイル(例えば下記のように3ファイル、実際には1000ファイル)があります。 file1.txt: 1  10 2  15 3  17 :  : 1000  25 file2.txt: 1  5 2  40 3  22 :  : 1000  17 file3.txt: 1  9 2  20 3  16 :  : 1000  32 出力後のファイルイメージ: 1  10  5  9 2  15  40  20 3  17  22  16 :  :  :  : 1000  25  17  32 ちなみに、自分で作成したawkスクリプト(下記)では、上記出力後のイメージとは異なり、 縦にデータが結合されてしまいました。 awk `{print $2}` ./file*.txt > Output.txt 出力後のファイル: 10 15 17 : 25 5 40 :

  • im830
  • お礼率100% (3/3)

みんなの回答

  • h271015
  • ベストアンサー率71% (62/87)
回答No.3

"awk `{print $2}` ./file*.txt" では全てのファイル(file*.txt)の$2行目の内容が、順番に出力されるだけですので、横には結合されません。 ファイルを横に結合して出力できるpasteコマンドを利用するなどして実現できるかも知れません。 もっと良い記述の仕方があるかも知れませんが、たとえば、以下のようなシェルスクリプトです。 ============================================== #!/bin/bash ### awkでfile1.txtの一行目を取得して保存 awk '{print $1}' ./file1.txt > ./file0.tmp ### 各ファイルの2行目を取得して一旦$f.tmpというファイルに書き出す ### (処理をファイル数分繰り返す) for f in file*.txt ; do awk '{print $2}' $f > $f.tmp done ### paste コマンドで結合 paste *.tmp > Output.txt ============================================== ※下記はあくまでサンプルですので、動作確認等、自己責任で実施お願いいたします。 ※ファイル名や一時ファイル出力先・削除などは環境に応じて変更してください。

im830
質問者

お礼

ありがとうございました。

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.2

元ファイルの区切り文字が全角空白になってますが、半角空白かタブ文字と想定して awk '{a[$1]=a[$1] OFS $2} END{for (i in a)print i a[i]}' file* | sort -n : : : : 1 10 5 9 2 15 40 20 3 17 22 16 1000 25 17 32 本当に全角空白なら適切に -F 指定してください。 それとワイルドカードの指示方法に注意が必要です。1から1000迄のファイル名が file0001からfile1000 となっていないと、想定する順序にならないので padding されてない場合は file?.txt file??.txt file???.txt file????.txt と順序良く指定する必要があります。

im830
質問者

お礼

ありがとうございました。

回答No.1

ファイルのデータは正しいものとし、a.awkスクリプトでは数のチェックは行っていません。 awk -f a.awk ./file*.txt > Output.txt awkスクリプト:a.awk BEGIN { fn="" max=0 } { if (FILENAME!=fn) { max++ cnt=1 fn=FILENAME } if (max==1) ARY[cnt]="" cnt ARY[cnt]=ARY[cnt] "\t" $2 cnt++ } END { for (cnt=1;cnt<=max;cnt++) { print ARY[cnt] } }

im830
質問者

お礼

ありがとうございました。

関連するQ&A

  • awkで複数ファイルをそれぞれ集計し、一つのファイルに出力するには

    awkプログラミングを始めたばかりの初心者です。複数ファイルのデータをそれぞれ集計し、一つのファイルに出力するにはどのようなスクリプトを作ればよいのでしょうか。 例 [file1]10,20,30 [file2]20,30,40 [file3]30,40,50 それぞれのファイルの中にある数字を合計して、別のファイル(file4)に一覧表示させる。    ↓ [file4]60 90 120

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

  • 文字列の抽出がうまくできません

    こんにちは。Perl初心者です。みなさんのお力をお借りしたく、初めて投稿させていただきました。よろしくお願いします。 現在、ファイルから特定した行を抽出し、その行に含まれる文字列を抽出しようとしているのですが、その文字列の抽出がうまくできません。 <文字列を含むファイル:xxx.txt> -------------------------- To 鈴木 太郎さん 1行目 : 01,りんご, 3 個, ナシ, 1個 14行目 02,キャベツ, 3 個, なす, 10本 15行目 : -------------------------- <スクリプトファイル:yyy.pl> -------------------------- open(DAT, "./xxx.txt") || die("can't open file : ($!)"); @file = <DAT>; close DAT; if ( $file[0] =~ /(\W+\s)(\W+)/ ) { print "$1\n"; } print "$file[13]\n"; print "$file[14]\n"; -------------------------- <結果> -------------------------- 鈴木 -------------------------- 抽出したい結果は「鈴木 太郎」なんですが、上記のような結果(「1byteのスペース」鈴木「2byteのスペース」)になってしまいます。xxx.txtの「To」と「鈴木」の間と、「鈴木」と「太郎」の間にはそれぞれ1byteのスペースがあります。どうやったら「鈴木 太郎」と抽出できるか教えてください。 スクリプトは「Copal2(ver2.77)」というツールを使って作りました。そのツールではエンコードは「自動判別」となっており実際何が使われているのか分かりません。 また他にも質問があります。 今抽出したい行を指定して出力させてますが、 「To」から始まる行 「01」といった2桁の数字から始まる行 というような抽出の仕方をしたいのですが可能でしょうか? 本当に初心で大変恐縮ではありますが、教えてください。 よろしくお願いいたします。

    • ベストアンサー
    • Perl
  • ある列をキーにして、複数行を1列で出力したい

    AWKで、以下の処理をしたいです。 ・1列目をキーにしたテーブルを作る ・1列目共通で2列目が複数ある場合は、並べて記載したい。 どなたか、スクリプト案お願いします。 例 Input file A あ B あ B い C い Output file A あ B あ/い C い

  • [awk]2つのファイルを参照して1つのファイルに出力する方法

    最近プログラミング(シェル、awk)を始めた者です。 かなり大まかなものは作れるようになったのですが、急遽、大規模なデータ整理を行わないといけなくなってしまったため、皆さんの知恵を貸していただきたく質問いたしましたm(_ _)m 以下に示すような2つのファイルがあります。 (file1)         (file2) 1 6           1  1  2  10 11 2 3           2  3  5  7  8 3 5           3  6  2  12 13 4 1           4  9  4  5  19 5 2           5  10 19 1  5 6 4           6  4  8  2  9 file1を上から1行ずつ順に読んでいき、2列目の値と同じものをfile2の1列目から探します。合致したところで、file2の合致した行の2列目以降を行番号を付けて表示するというものです。 (「file1の2列目の値=file2の1列目の値」を探し、file2の合致行の値を出力。) 上記ファイルですと、結果的に 1  4  8  2  9 2  6  2  12 13 3  10 19 1  5 4  1  2  10 11 5  3  5  7  8 6  9  4  5  19 という具合になります。 2つのファイルの行数は同じではなく、また、両ファイルとも1列目が行番号というだけで、他の列の値に規則性はありません。 file2の行数は100万以上の大規模なものになります。 自分が作ったものを掲載できればよかったのですが、あいにく会社のPC内にありまして、持ち出しできないため、掲載できません。 動作環境はLinux(RedHat)になります。 他のプログラミング言語についてはまだ分からないため、awkもしくはシェルでお願いいたします。

  • awkを使って文字列処理の問題

    awkで以下のことをやりたいですが、 a.txtの中身は aaaa bbbb cccc の三つのレコードがあります。 b.txtの中身は 東京a 埼玉b 千葉c 東京d になってます。 ファイルa.txtのみっつのレコードのを読み込んできて、b.txtに対して検索して、東京 という文字列があれば、そのレコードは、aaaaに置き換えて、あるファイルに出力する ようなスクリプトを書きたいです。 どう書けば、いいですか?教えていただけませんか?

  • awkで項目番号ごとに行を列に並べる

    [入力ファイル] a  10   1 b  10   2 c  10   3 d  10   4 a  20   5 b  20   6 c  20   7 d  20   8 a  30   9 b  30   0 c  30   1 d  30   2 を、2列目の項目番号を行、1列目の記号を列として (エクセルのピボットテーブルのようなイメージです) 以下のように並べ替えたいのです。 [出力ファイル] No.  a  b  c  d 10  1  2  3  4 20  5  6  7  8 30  9  0  1  2 これをawkスクリプトで書きたいのですが、 どのように書けばよいでしょうか? ※下記2点は希望ですが、難しければ非対応でも大丈夫です。  ・入力ファイルの1行目は一応abcdの順番にきれいに並んでいるものですが   順番がabdcなどとずれていても処理できるスクリプトにしたいです。  ・出力後のabcdの列順序は、スクリプトを修正することで   自由に変更できるとさらに助かります。 教えてください。 よろしくお願いいたします。

  • awkのBEGINについて

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

  • awkで可変文字列をマッチング

    シェルなどでawkを使う際に、シェルの引数として渡された文字列をawkに渡し、それを条件にマッチングをかけたいのですが、どうしたら良いのでしょうか?(まあ、素直にgrepを使えばいいのですが・・・) 例えば、 cat foo.txt | awk '{if ($2 == ptn) print}' ptn=$<シェルの引数> とかやれば、2番目のフィールドに完全に一致する行が抽出できるのですが、 cat foo.txt | awk '/ptn/ {print}' ptn=$<シェルの引数> とかやっても、"ptn"という文字列をマッチングしてしまうので、うまくいきません。どの位置に出現するかわからないけど、シェルの引数で指定された文字列が含まれている行だけを出力したい場合、どうしたらよいのでしょう・・・。

  • awkで列を集計するシェルについて

    シェル初心者です。教えてください。 ログファイルが10万行超えるものでシェルにて集計することになり、下記のような集計ができればと思っています。 商店名 商品名  価格 A商店 りんご   100 B商店  ぶどう 300 A商店  みかん 150 C商店  りんご 100 A商店  りんご 100 B商店  みかん 150 C商店  りんご 100 C商店  ぶどう 300 ※各列はブランク(空白)によって区切られ、改行済みで行数は10万行以上 (1)awk '{print $1}' | uniq -d (重複した商店の抽出) (2)awk '{print $2}' | uniq -d (重複した商品名の抽出) (1)、(2)の抽出を満たす「価格」の合計を"集計結果”として > shukei.txt などに出力したいと思ってます。 VBAでいれば、firlterしsumifして合計するようなイメージのものです。 ご教授お願い致します><