LoginSignup
akaikasa
@akaikasa

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【シェル芸】改行毎にawkで区切り、grepで特定の文字列が入っているレコードを抽出したい

[address.txt]から改行毎に区切り、4つのレコードとし、そのうち「合格」という文字列が入っているレコードを抽出するにはどうすればよいでしょうか。

address.txt
---ここから---
東川 雄一
合格
080-1111-1111
〒111-1111
××県××区A町 1-1-1
ABCビル1001

西村 祐二
不合格
080-2222-2222
〒222-2222
××県××市B町 2-22

南山 裕三
合格
080-3333-3333
〒333-3333
××県××市C町 3-3-3
XYZハイツ3号室

北岡 優四
不合格
080-4444-4444
〒444-4444
××県××区D町 4-4-4
---ここまで---

以下のコマンドを入力しても何も出力されません。
cat address.txt | awk 'BEGIN{RS="";FS="\n"}' | grep '合格'

0

2Answer

PythonやPerlなどで処理したほうがよいような気もしますが、AWKでやるならこんな感じでしょうか?

cat address.txt  | awk '{a = a ? a "\n" $0 : $0} /^合格$/{x=1} /^$/{if(x) print a; a=x=0}'
0

こちらはいかがでしょうか.

cat address.txt |
  awk 'BEGIN{RS=""} {$1=$1; print}' |
  grep -v "不合格"
  • RSでレコード区切りを変更後に, 変更を適応するために{$1=$1}のアクションを加えます. 最後にprintで出力します. (ご提案のコードで何も出力されなかったのはアクションにprintがなかったからです. )
  • grep "合格"では"合格"も"不合格"もマッチしてしまうので, "不合格"を除くという方針にしました.
0

Comments

  1. @akaikasa

    Questioner
    ありがとうございます。できました!

    最初のご回答で、awk 'BEGIN{RS=""}{$1=$1}1' とありましたが、どちらが良いでしょうか。
  2. 良かったです!
    `awk 'BEGIN{RS=""}{$1=$1}1'`と`awk 'BEGIN{RS=""}{$1=$1; print}'`はまったく同じ意味ですが、私はタイプ量をすこしでも減らすために前者を使います。(printも塵も積もれば山となるので…)
    ただ後者のほうが可読性が高いので、こちらでも良いと思います。

Your answer might help someone💌