- ベストアンサー
awkでの処理
環境はHP-UX,UNIXです。 あるtxtファイルが存在したとして、txtファイルの中身は以下のようになっているとします。 基本思想としては現在行と次の行を比較して、現在行がOUT次の行がINだったら処理実行、もしOUTの次にOUTがきていたら、現在行のOUTの行を削除するとしたいです。 ~OUT ~IN ~OUT ~IN ~OUT ~IN ~OUT ★ここを削除したいです。 ~OUT ~IN sh内で実装するとしたらどうやったらできますでしょうか ご教授願います。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
>今 notnotさんの方法で試すと・・・ >なんですがね~↓↓ それはあり得ません。もう一度よく確認してください。
その他の回答 (4)
- 0909union
- ベストアンサー率39% (325/818)
不明な点もあるが、私が理解した範囲で。 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%は終わっています。 順番に書けばいいだけ。
お礼
0909unionさん No2さんのロジックでいこうと思います。 0909unionさんから教えて頂いた内容も実現できましたので お礼申し上げます。 また勉強させて下さい!!
補足
0909unionさん 丁寧にありがとうございます。 今こちら30000stepぐらいのshを組んでいて大変なのです。。。。 お二方に助けて頂いた感じでちょっと動かしてみます。 少々お待ち下さい。
- notnot
- ベストアンサー率47% (4900/10358)
No2です。すいません。訂正。 /OUT/{save=$0;next} {if(save!=""){print save;save=""};print} END{if(save!="")print save} OUTがない行が連続しないなら、たまたまさっきのでも良いのですが。
お礼
今 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 なんですがね~↓↓
補足
notnotさん 丁寧にありがとうございます。 今こちら30000stepぐらいのshを組んでいて大変なのです。。。。 お二方に助けて頂いた感じでちょっと動かしてみます。 少々お待ち下さい。
- notnot
- ベストアンサー率47% (4900/10358)
OUTが含まれる行が連続したらその最後の行だけ出すということですね。 awk '/OUT/{save=$0;next} {if(save!="")print save;print} END{if(save!="")print save}'
- 0909union
- ベストアンサー率39% (325/818)
結局何をしたいのか、ようわからん。 単に同じ行があったら削除するなら、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などだと、比較位置きめられたはず)
補足
言葉足らずで失礼しました。 結局こういう感じになってるファイルがあって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"
お礼
ごめんなさい、私の確認ミスで大変申し訳ありません。 結果的に以下のように求めていた結果になっていました。 【理想】 OUT IN OUT★削除 OUT IN OUT IN OUT★削除 OUT IN これでUNIXTIME(sh→perlのUNIXTIME変換ロジック)が使用できます!! すごい悩んでいたので、大変助かりました。 また勉強させてくださいね。