• ベストアンサー

awkでの処理

環境はHP-UX,UNIXです。 あるtxtファイルが存在したとして、txtファイルの中身は以下のようになっているとします。 基本思想としては現在行と次の行を比較して、現在行がOUT次の行がINだったら処理実行、もしOUTの次にOUTがきていたら、現在行のOUTの行を削除するとしたいです。 ~OUT ~IN ~OUT ~IN ~OUT ~IN ~OUT   ★ここを削除したいです。 ~OUT ~IN sh内で実装するとしたらどうやったらできますでしょうか ご教授願います。

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

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.5

>今 notnotさんの方法で試すと・・・ >なんですがね~↓↓ それはあり得ません。もう一度よく確認してください。

chabakof
質問者

お礼

ごめんなさい、私の確認ミスで大変申し訳ありません。 結果的に以下のように求めていた結果になっていました。 【理想】 OUT IN OUT★削除 OUT IN OUT IN OUT★削除 OUT IN これでUNIXTIME(sh→perlのUNIXTIME変換ロジック)が使用できます!! すごい悩んでいたので、大変助かりました。 また勉強させてくださいね。

その他の回答 (4)

  • 0909union
  • ベストアンサー率39% (325/818)
回答No.4

不明な点もあるが、私が理解した範囲で。 BEGIN { out_pic=0; out_var=0; } # 正規表現で 末尾がOUT と In の処理をわける。 # out_pic == 0の時だけout_varに第1フィールドをセット。 # var++はイングリメント(参照後に+1になる)。HP-UXで対応してなければvar = (var + 1) # 問題はこの正規表現で確実にヒットするよにテストしてください。/\"\wOUT\>\"になるか単に/\"\wOUT\"/ # また $2~/OUT\>/でもいい。第2フィールドが、単語の最後がOUTと言うこと。 /OUT\>/ { out_var=$1; if(0 != out_pic++){ # printf(); } } /IN\>/ { if(1 == out_pic){ # 計算処理 out_var - $1とか # printf(); } # 初期化 out_var=0; } こちらにHP-UXの環境がないので試せないので、アルゴリズムだけ。 (書式もちぇっくしていない) >順番でならんでない行は削除するとしたかったのです これは元のファイルの行を抹消して上書き保存するという事なのか? もしそうだとすると、変になるので、一旦別のファイルなどに保存し全部終了したら、置き換えるといい。 awk {} >> a.txt として、値をセットした時に、printf()で該当行を出力すればいい もちろん上記はスクリプトファイルにしていることを前提にしているが、SHだと1行にも直せるので、コマンドラインでの実行でも可能。 /IN\>/ && 1 == out_pic なんてやり方もある、No2さんも示されたように、2度目であることを、何かに保存すればいいだけ。オブジェクト指向の言語でないので、補足で示したような、他人に細かく説明するような文を書けば(箇条書きに順番に)、プログラムは50%は終わっています。 順番に書けばいいだけ。

chabakof
質問者

お礼

0909unionさん No2さんのロジックでいこうと思います。 0909unionさんから教えて頂いた内容も実現できましたので お礼申し上げます。 また勉強させて下さい!!

chabakof
質問者

補足

0909unionさん 丁寧にありがとうございます。 今こちら30000stepぐらいのshを組んでいて大変なのです。。。。 お二方に助けて頂いた感じでちょっと動かしてみます。 少々お待ち下さい。

  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.3

No2です。すいません。訂正。 /OUT/{save=$0;next} {if(save!=""){print save;save=""};print} END{if(save!="")print save} OUTがない行が連続しないなら、たまたまさっきのでも良いのですが。

chabakof
質問者

お礼

今 notnotさんの方法で試すと・・・ 【元ファイル】 OUT IN OUT OUT IN OUT IN OUT OUT IN 【結果ファイル】 OUT IN OUT OUT★削除された IN OUT IN OUT★削除された OUT IN 【理想】 OUT IN OUT★削除 OUT IN OUT IN OUT★削除 OUT IN なんですがね~↓↓

chabakof
質問者

補足

notnotさん 丁寧にありがとうございます。 今こちら30000stepぐらいのshを組んでいて大変なのです。。。。 お二方に助けて頂いた感じでちょっと動かしてみます。 少々お待ち下さい。

  • notnot
  • ベストアンサー率47% (4846/10257)
回答No.2

OUTが含まれる行が連続したらその最後の行だけ出すということですね。 awk '/OUT/{save=$0;next} {if(save!="")print save;print} END{if(save!="")print save}'

  • 0909union
  • ベストアンサー率39% (325/818)
回答No.1

結局何をしたいのか、ようわからん。 単に同じ行があったら削除するなら、uniq or sortコマンドで同行は表示しないオプションがあったと思います。HP-UXでもあったのでは・・・ http://docs.hp.com/en/B2355-90680/uniq.1.html http://docs.hp.com/en/B2355-90680/sort.1.html?jumpid=reg_R1002_USEN それで標準入力から渡せば、同じ行は存在しないで、処理ができると思います。 sort|uniq -[忘れた。上記URL確認] xxxx.txt | awk { xxxx } 順番が大事だったら、フィールド管理して、先頭か、最後尾に番号つける(sortなどだと、比較位置きめられたはず)

chabakof
質問者

補足

言葉足らずで失礼しました。 結局こういう感じになってるファイルがあってOUTとINの順番になってたら 2行目の$1から1行目の$1を引き算しようとしていて、 引き算の前にチェックして、 OUTとINの順番でならんでない行は削除するとしたかったのです。。。 以下のように重複行を削除する sort- uとかuniq 文字列指定は使えないのですよ。正直 awkの得意な人に聞いても結構難しいといっていたので、 質問させて頂きました。 13001234 "性能情報:20110412000455278_02OUT" 13001234 "性能情報:20110412000455283_02_IN" 13001234 "性能情報:20110412000502719_01OUT" 13001234 "性能情報:20110412000502724_01_IN" 13001234 "性能情報:20110412000832155_01OUT" 13001234 "性能情報:20110412000832159_01_IN" 13001234 "性能情報:20110412001243737_01OUT" 13001234 "性能情報:20110412001243742_01_IN" 13001234 "性能情報:20110412001347455_06OUT" 13001234 "性能情報:20110412001347459_06_IN" 13001234 "性能情報:20110412001652405_01OUT" 13001234 "性能情報:20110412001652410_01_IN" 13001234 "性能情報:20110412001844606_01OUT" 13001234 "性能情報:20110412001844612_01_IN" 13001234 "性能情報:20110412002258567_05OUT" 13001234 "性能情報:20110412002258572_05_IN" 13001234 "性能情報:20110412002410587_01OUT" 13001234 "性能情報:20110412002410591_01_IN" 13001234 "性能情報:20110412002505697_04OUT" 13001234 "性能情報:20110412002505701_04_IN" 13001234 "性能情報:20110412002911876_01OUT" 13001234 "性能情報:20110412002911881_01_IN" 13001234 "性能情報:20110412003125409_01OUT" 13001234 "性能情報:20110412003125414_01_IN" 13001234 "性能情報:20110412003148432_07OUT"★ 13001234 "性能情報:20110412003148451_01OUT" 13001234 "性能情報:20110412003148456_01_IN" 13001234 "性能情報:20110412003719949_01OUT" 13001234 "性能情報:20110412003719954_01_IN" 13001234 "性能情報:20110412003857663_01OUT" 13001234 "性能情報:20110412003857668_01_IN" 13001234 "性能情報:20110412004020388_01OUT" 13001234 "性能情報:20110412004020393_01_IN" 13001234 "性能情報:20110412004353569_01OUT" 13001234 "性能情報:20110412004353573_01_IN" 13001234 "性能情報:20110412004553447_01OUT" 13001234 "性能情報:20110412004553452_01_IN" 13001234 "性能情報:20110412004614347_01OUT" 13001234 "性能情報:20110412004614352_01_IN" 13001234 "性能情報:20110412005335553_01OUT"

関連するQ&A

  • awkでのsh処理について

    HP-UX環境、UNIXです。 1行目の11カラム目にOUTが含まれているかつ2行目の11カラム目にINが含まれている行だけ ファイルに出力するという処理を以下のように考えたんですが、うまくいきません。 awk'{m == NR % 2} m==1{if($11~ "OUT")} && m==0{if($11~ "IN") print $0} ' [ファイル名] 文法的に誤っていますでしょうか?? 回答宜しくお願い致します。

    • ベストアンサー
    • CGI
  • awkで行ごとの計算について

    HP-UX,UNIX環境です。 あるファイルを⇒a.txtとします。 a.txtには以下のような記述だとします。(行は複数行) 20110322000000 00:00:00 PERFORMANCE all 20110322000100 00:00:00 PERFORMANCE all 20110322000200 00:00:00 PERFORMANCE all 20110322000300 00:00:00 PERFORMANCE all shでのループ処理は以下のようにしたいです。 (1)2行目の1カラム目から1行目の1カラム目を引き算、 (2)計算結果をファイルにリダイレクト (3)4行目の1カラム目から3行目の1カラム目を引き算 (4)計算結果をファイルにリダイレクト ※awkを使えば出来そうですが、やり方がわかりません。 お手数ですが、ご回答宜しくお願い致します。

    • ベストアンサー
    • CGI
  • [awk]でデータ整理がしたいです。

    こんばんは この度、研究で膨大なデータをまとめたいのでawkを使おうと思っています。 元のファイルは約1万個あります。 ファイル名は R150km‐1020010001.txt から R150km‐1021800180.txt まであります。 102までは共通でそのあとの数字が変わります。 0010001...0010180 0020001 0020002...0020180.................1800180 といった形です。 中身は、 0 0 0 34 57 69 79 109 ....... といったように1行で8000列の数値データが入っています。 このファイルを下記のように1行目に0010001のファイルの中身、tabで区切って、2行目に0010002のファイルの中身といった形で一つのtxtにまとめたいです。 0 (tab) 0 (tab) 0 ... 34(tab) 28(tab) 36... 57(tab) 67(tab) 53... 69(tab) 78(tab) 72... 79(tab) 89(tab) 88... 109(tab) 99(tab)107 ... ... .... ... 可能でしょうか?ご回答お待ちしております。 よろしくお願いします。 awk初心者なので何か足りないところあったらすみません。

  • Perlを使って、大文字小文字関係なく、重複行を削除したい。

    現在、下記のコードで重複行を削除し、ファイルを作成しているのですが、 AAA aaa AaA などのように大文字、小文字が混じっている場合は重複とはみなさず削除の対象になりません。 こういった場合も重複とみなして削除させたいのですがどのようにすればいいでしょうか? open(IN, "INfilename.txt"); open(OUT, ">Outfilename.txt"); while(){ if(!exists($count{$_})){$count{$_}++;print OUT $_;} } close (IN); close (OUT);

    • ベストアンサー
    • CGI
  • C言語で書き込んだファイルの重複行の削除と行の並び変えるプログラミング

    C言語で書き込んだファイルの重複行の削除と行の並び変えるプログラミング ファイル名が 0.txt というC言語で書き込んだテキストファイルがあり その中身は以下のようなものとします。 111 000 222 555 000 444 222 000 これらを行ごとに見て重複行を削除し 更に値の小さな順に並び変えたい、つまりファイル内を 000 111 222 444 555 となるようなプログラミングを考えているのですが 調べても分からず悩んでいます。 c言語のプログラム内に UNIXコマンドを扱う方法を考えているのですが c言語内でUNIXコマンドを併用するためのsystem()関数 や 重複行を削除する uniq というUNIXコマンドを どのようにプログラム内に挿入すればいいのでしょうか? ご回答、よろしくお願いいたします。 ちなみに以下のプログラムは system関数が理解できない私の作成失敗したものです。 #include <stdio.h> #include <stdlib.h> int main(void) { system("uniq 0.txt"); }

  • awk の使い方

    sample.txt ファイルには   "中村" "08/01/80" "03.1234.5678"   "木村" "08/01/81" "06.1252.2536" のような情報があります。(フィールドの区別はTabです) そこの3番フィールドが電話番号ですので、awkで検索しようと思っています。 それで、 $ shell 06.1252.2536 #!/bin/sh NUM=$1                    #引数をNUMに代入 awk -v ARGU="$NUM" ' { VAR=substr($3,2,(length($3)-2))      #「"」を取り除いた if ( ARGU == VAR ) {print}         #電話番号と比較 }' /sample.txt のようにして、検索をかけようとしましたが、できません。 どこが間違っているのか教えてください。 awkの他の方法があるとか、違うもの(sed or grep)でできるのであれば、お願いします。

  • UNIX C ファイル出力

    UNIX Cにてあるテキストファイルの中身(1行分)を、別のテキストファイルに出力したいのですが、どうすれば、いいでしょうか。 例。A.txt 123 yano 200612   ↓ B.txt 123 yano 200612

  • 【初歩的質問】重複データがある時のハッシュへの代入について

    perl5.8です。すごくしようもない質問で申し訳ないのですが、次のようなファイルfile.txtの内容を、ハッシュ%hashに入れていくとします。 --- file.txtの中身 --- a,1 c,3 a,1 b,2 c,3 ----------------------- --- ソース(抜粋) ----- open(IN, "file.txt"); @data = <IN>; close(IN); %hash = (); foreach(@data){ chomp $_; @out = split(/,/, $_); $hash{$out[0]} = $out[1]; } ----------------------- 上記の結果は当然ながら、$hash{a}=1,$hash{c}=3,$hash{b}=2となるのですが、重複したデータを読み込んでハッシュに入れようとした時に、ワーニングなりエラーがなにも出なかったのがちょっと気持ち悪いです。重複したキーを読み込んだ時は、内部的には黙ってはじいてくれていると解釈してよいのでしょうか?そうだとすると、こういう書き方は、重複した行を排除するテクニックとなりえるのでしょうか?

  • 複数のファイルを読み込み、1つのファイルとして出力する方法。

    Nakanoです。いつもお世話になっております。 例えばテキストファイルを2つ用意し、1つのテキストファイルとして 出力したいのですが、いまいちやり方が分かりません。出来るのかどうかも 分からないです。(汗) 下にサンプルデータがあります。取り合えず「in1.txt」「in2.txt」 を最終的に『out.txt』の様に仕上げたいのですが… # =in1.txt AAAAA BBBBB CCCCC DDDDD 1,000 2,000 3,000 4,000 1,001 2,002 3,003 4,004 1,010 2,020 3,030 4,040 1,100 2,200 3,300 4,400 =in2.txt EEEEE FFFFF GGGGG HHHHH 5,000 6,000 7,000 8,000 5,005 6,006 7,007 8,008 5,050 6,060 7,070 8,080 5,500 6,600 7,700 8,800 # =out.txt AAAAA BBBBB CCCCC DDDDD EEEEE FFFFF GGGGG HHHHH 1,000 2,000 3,000 4,000 5,000 6,000 7,000 8,000 1,001 2,002 3,003 4,004 5,005 6,006 7,007 8,008 1,010 2,020 3,030 4,040 5,050 6,060 7,070 8,080 1,100 2,200 3,300 4,400 5,500 6,600 7,700 8,800 # ・このデータはタブで区切っています。カンマはない場合もあります。 ・ファイルの中のそれぞれの文字列の数は固定です。行数も固定です。  各文字列の中の文字数はランダムです。  COPYコマンドを利用しても考えてみたのですが、後ろに続いちゃって  上手くいかなかったです。(笑)  Perlだと1つ目のファイルの1行目を配列に入れて、次に2つ目の  ファイルの1行目を配列に入れて、これを一旦出力して、同じ手順の  様な事を行を2行目、3行目、4行目、、とずらして繰り返す。って  感じでイメージしているのですが、どの様にソースを組めばいいのか  分かりませんでした。  どなたかご教授いただけないでしょうか? 宜しくお願い致します。

  • データファイルの処理と保存について

    はじめまして。 C言語についてまだ勉強が不十分なので、ご質問させていただきます。 現在、あるいくつかのデータファイルがあります。 中に入っているデータ数は2000行以上です。 列は3列です。 これを分割したいのですが、1つのデータファイルは100個で構成します。 その100個スケールを10個ずつずらして新しいファイルに入れていきます。 今Excelで手作業でやっているのですが、大変時間がかかります。 Excelですと、行番号1~100を取り出して新しいファイル「ファイル名_1.txt」をつくり、次に先ほどの100番目までのデータのうち、10番目まで削除して行番号11~110を取り出して新しいファイル「ファイル名_2.txt」を作成。 つまりこのファイルは90個のデータが重なっています。 □内にデータが10個だとすると □□□□□□□□□□  □□□□□□□□□□   □□□□□□□□□□    □□□□□□□□□□ といったように10ずつずらして、このようなことを繰り返しているのですが、現在総数666個のデータを用いて分割し、57個のデータファイルができました。 ファイルはそれぞれ100ずつとしていますが、最後のみ106個です。 このようなことをCでできないでしょうか。 ・100個スケールを10個ずつずらして格納。 ・出力ファイル名は「ファイル名_n.txt」(n=1,2,3,4...) ご協力お待ち申し上げております。 よろしくお願いいたします。

専門家に質問してみよう