みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

awkでの処理

環境はHP-UX,UNIXです。

あるtxtファイルが存在したとして、txtファイルの中身は以下のようになっているとします。
基本思想としては現在行と次の行を比較して、現在行がOUT次の行がINだったら処理実行、もしOUTの次にOUTがきていたら、現在行のOUTの行を削除するとしたいです。

~OUT
~IN
~OUT
~IN
~OUT
~IN
~OUT   ★ここを削除したいです。
~OUT
~IN

sh内で実装するとしたらどうやったらできますでしょうか
ご教授願います。

投稿日時 - 2011-04-16 12:43:55

QNo.6672025

すぐに回答ほしいです

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

>今 notnotさんの方法で試すと・・・

>なんですがね~↓↓

それはあり得ません。もう一度よく確認してください。

投稿日時 - 2011-04-16 22:22:19

お礼

ごめんなさい、私の確認ミスで大変申し訳ありません。

結果的に以下のように求めていた結果になっていました。
【理想】
OUT
IN
OUT★削除
OUT
IN
OUT
IN
OUT★削除
OUT
IN

これでUNIXTIME(sh→perlのUNIXTIME変換ロジック)が使用できます!!
すごい悩んでいたので、大変助かりました。
また勉強させてくださいね。

投稿日時 - 2011-04-16 23:36:41

ANo.5

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.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%は終わっています。

順番に書けばいいだけ。

投稿日時 - 2011-04-16 18:38:39

補足

0909unionさん

丁寧にありがとうございます。
今こちら30000stepぐらいのshを組んでいて大変なのです。。。。

お二方に助けて頂いた感じでちょっと動かしてみます。
少々お待ち下さい。

投稿日時 - 2011-04-16 19:00:24

お礼

0909unionさん

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

また勉強させて下さい!!

投稿日時 - 2011-04-16 23:39:28

ANo.3

No2です。すいません。訂正。

/OUT/{save=$0;next}
{if(save!=""){print save;save=""};print}
END{if(save!="")print save}

OUTがない行が連続しないなら、たまたまさっきのでも良いのですが。

投稿日時 - 2011-04-16 18:15:01

補足

notnotさん

丁寧にありがとうございます。
今こちら30000stepぐらいのshを組んでいて大変なのです。。。。

お二方に助けて頂いた感じでちょっと動かしてみます。
少々お待ち下さい。

投稿日時 - 2011-04-16 19:00:53

お礼

今 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

なんですがね~↓↓

投稿日時 - 2011-04-16 19:48:19

ANo.2

OUTが含まれる行が連続したらその最後の行だけ出すということですね。

awk '/OUT/{save=$0;next}
{if(save!="")print save;print}
END{if(save!="")print save}'

投稿日時 - 2011-04-16 17:45:31

ANo.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などだと、比較位置きめられたはず)

投稿日時 - 2011-04-16 13:43:39

補足

言葉足らずで失礼しました。

結局こういう感じになってるファイルがあって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"

投稿日時 - 2011-04-16 14:08:06

あなたにオススメの質問