$logに

hoge1 hoge2 "hoge3 hoge4 hoge5/hoge6 hoge7 gomi1/hoge8gomi2 gomi3/hoge9gomi4 hoge10"
というのが入っていて
hoge3,hoge4,hoge5,hoge6,hoge8,hoge9,hoge10
というのを出力させたいのですが、
HOGE3=`echo $log | awk '{sub(/\"/,"",$3); print $3 }'`
HOGE4=`echo $log | awk '{print $4}'`
HOGE5=`echo $log | awk '{print $5}' | awk 'BEGIN{ FS="/"; } { print $1 }'`
HOGE6=`echo $log | awk '{print $5}' | awk 'BEGIN{ FS="/"; } { print $2 }'`
HOGE8=`echo $log | awk '{print $7}' | awk 'BEGIN{ FS="/"; } {gsub (/gomi2/,""); print $2}'`
HOGE9=`echo $log | awk '{print $8}' | awk 'BEGIN{ FS="/"; } {gsub (/gomi4/,""); print $2}'`
HOGE10=`echo $log | awk '{sub(/\"/,"",$9); print $9}'`

echo "$HOGE3","$HOGE4","$HOGE5","$HOGE6","$HOGE8","$HOGE9","$HOGE10"

とかやってますが、あまりにも馬鹿っぽいので、もっと良いやり方を教えてはもらえないでしょうか。
UNIX Shell限定です。
awkやsedはおkです。

回答の条件
  • URL必須
  • 1人2回まで
  • 登録:2007/12/05 17:45:34
  • 終了:2007/12/09 15:38:36

ベストアンサー

id:kn1967 No.3

kn1967回答回数2915ベストアンサー獲得回数3012007/12/05 20:45:56

ポイント27pt

環境が無いのでUNIXシェルでの動作確認はしてませんが

BEGIN{
    FS = "\"";
}
{
    gsub(/gomi1\/|gomi2|gomi3\/|gomi4/,"",$2);
    gsub(/\/| /,",",$2);
}
END{
    print $2;
}

でお望みどおりにはなりませんか?

(インデントつけたりしてますが1行にしてももちろん結構です)


gomi1とgomi3が可変ということですが仮にアルファベットと数字で構成されているとすれば

BEGIN{
    FS = "\"";
}
{
    sub(/\//,",",$2);
    gsub(/gomi2 |gomi4 | /,",",$2);
    gsub(/,[a-z|A-Z|0-9]+\//,",",$2);
}
END{
    print $2;
}

といったような具合でいかがでしょう?


awkは15年以上触っていないので正規表現は下記ページを参考にしました。

http://homepage2.nifty.com/mozu/koza/park_of_text.html

id:UME

おお。subとかgsubを連続して使うとこんなことができるのか。

なんか一番これがわかりやすいのかも。

スペースも検索対象になるのですね。よくわかりました。

ありがとうございます。

2007/12/06 23:14:28

その他の回答(2件)

id:bonlife No.1

回答回数421ベストアンサー獲得回数752007/12/05 18:29:15

ポイント28pt

以下のような感じでいかがでしょう。

質問文より、 hoge... は可変値で gomi... は固定値だと判断いたしました。

#!/bin/sh

log='hoge1 hoge2 "hoge3 hoge4 hoge5/hoge6 hoge7 gomi1/hoge8gomi2 gomi3/hoge9gomi4 hoge10"'
echo $log

echo $log | awk -F\" '{print $2}' | sed "s/\// /g" | sed s/gomi1// | sed s/gomi2// | sed s/gomi3// | sed s/gomi4// | awk '{print $1","$2","$3","$4","$6","$7","$8}'
hoge1 hoge2 "hoge3 hoge4 hoge5/hoge6 hoge7 gomi1/hoge8gomi2 gomi3/hoge9gomi4 hoge10"
hoge3,hoge4,hoge5,hoge6,hoge8,hoge9,hoge10
  1. 最初の awk でダブルクォートの中身だけ抽出
  2. 次の sed でスラッシュをスペースに置換
  3. 次の sed で gomi1 削除
  4. 次の sed で gomi2 削除
  5. 次の sed で gomi3 削除
  6. 次の sed で gomi4 削除
  7. 最後の hoge7 以外を awk でカンマ区切りで出力

途中で変数を使う必要はなくなりました。

ただ、sed で gomi... を削除している部分は、 hoge... に入る値によっては問題になりますね。

(Perl使って良ければもっと楽ですが。)

id:UME

やっぱり、sed使うのか・・・ふむなるほど。

実はgomi1とgomi3も可変でした。説明不足でごめんなさい。

でも、大体わかりました。awkでダブルコーテーションの中身だけっていうのは、こうやるんですね。

やり方あるんだろうなーと思いながらやってました。ふむふむ。

ありがとうございます。

2007/12/05 18:58:39
id:b-wind No.2

b-wind回答回数3344ベストアンサー獲得回数4402007/12/05 20:33:34

ポイント27pt

正直前提条件がさっぱりわからないんですが、

(" は無視していいのかとか、hoge8 と gomi2 の分割条件とか)

log='hoge1 hoge2 "hoge3 hoge4 hoge5/hoge6 hoge7 gomi1/hoge8gomi2 gomi3/hoge9gomi4 hoge10"'
echo $log | sed 's/gomi[1234]//g;s|[/"]| |g;' | awk '{print $3,$4,$5,$6,$8,$9,$10}'

とりあえず、目的の出力は出ました。

AWK$B$NBh0lJb(B

id:UME

なるほど。

sedでまとめて消すのか・・・ふむ。

条件とかは僕の説明不足ですよね。すいません。

ありがとうございます。

2007/12/06 23:01:28
id:kn1967 No.3

kn1967回答回数2915ベストアンサー獲得回数3012007/12/05 20:45:56ここでベストアンサー

ポイント27pt

環境が無いのでUNIXシェルでの動作確認はしてませんが

BEGIN{
    FS = "\"";
}
{
    gsub(/gomi1\/|gomi2|gomi3\/|gomi4/,"",$2);
    gsub(/\/| /,",",$2);
}
END{
    print $2;
}

でお望みどおりにはなりませんか?

(インデントつけたりしてますが1行にしてももちろん結構です)


gomi1とgomi3が可変ということですが仮にアルファベットと数字で構成されているとすれば

BEGIN{
    FS = "\"";
}
{
    sub(/\//,",",$2);
    gsub(/gomi2 |gomi4 | /,",",$2);
    gsub(/,[a-z|A-Z|0-9]+\//,",",$2);
}
END{
    print $2;
}

といったような具合でいかがでしょう?


awkは15年以上触っていないので正規表現は下記ページを参考にしました。

http://homepage2.nifty.com/mozu/koza/park_of_text.html

id:UME

おお。subとかgsubを連続して使うとこんなことができるのか。

なんか一番これがわかりやすいのかも。

スペースも検索対象になるのですね。よくわかりました。

ありがとうございます。

2007/12/06 23:14:28

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません