web-dev-qa-db-ja.com

条件に基づいてラインを抽出する

コンマ区切りファイルの各行には5つのフィールドがあります。

a,b,c,d,e
f,g,c,i,
j,k,c,m,n
o,p,c,r,s
t,u,c,w,
x,y,z,aa,bb

3番目のフィールドにcがあり、5番目のフィールドが空でない行を抽出するにはどうすればよいですか?結果は次のようになります。

a,b,c,d,e
j,k,c,m,n
o,p,c,r,s
5
Reza

awkで可能な解決策:

awk -F',' '$3 == "c" && $5' file

実際のデータによっては、コメントで述べたようにこれが期待どおりに機能しない場合があります(Janisに指摘していただきありがとうございます:f,g,c,i,0がありません。たとえば、5番目のフィールドは0です)。次の操作を実行できます。

awk -F',' '$3 == "c" && $5 != ""' file

そしてこれは受け入れられた答えなので、(cuonglm(+1)ソリューションのように)5番目のフィールドを文字列に強制することはそれほど明白ではありません:

awk -F',' '$3 == "c" && $5""' file
8
taliezin
sed -n '/,$/!s/^\([^,]*,\)\{2\}c/&/p'

... POSIX sedで機能します。 AT&TAugmented正規表現を実装するsedを使用できる場合- astopen パッケージ-次のようにすることができます:

sed -nX '/^(([^,]*,){2}c.*)&(.*,)!$/p'

もちろん、後者のケースが当てはまる場合、おそらく同様のgrepがあります(ksh93ビルトインとしてコンパイルできます)そして、あなたはおそらく代わりにそうするべきです:

grep -xX '(([^,]*,){2}c.*)&(.*,)!'
3
mikeserv

awkの場合:

awk -F, '$3 == "c" && $5""' file

awkでは、0""はブールコンテキストの2つのfalse値です。したがって、$3 == "c" && $5のようなことをすると、5番目のフィールドが0である行が失われます。 $5"" force awk 5番目のフィールドを文字列に強制します。文字列"0"はtrueと評価されます。

2
cuonglm

これはいくつかの回答ほど短くはありませんが、プログラムで要求された内容を正確に言う唯一の回答です。

awk '$3 == "c" && $5 != ""' FS=,
1
Steven Penny

Perlを使用すると、次のようなことができます。

Perl -F, -nlae 'print if $F[2] eq "c" and $F[4] ne ""'

-aオプションは、-Fオプションで指定された区切り文字で行を分割し、後で@F配列のフィールドを確認するだけで済みます。

0
michas

pythonの使用:

#!/usr/bin/env python2
with open('file.txt') as f:
    for line in f:
        fields = line.rstrip().split(',')
        if fields[2] == 'c' and fields[4]:
            print line.rstrip()

ここでは、各行のフィールドをコンマ(,)をリスト(fields)に入れ、必要なフィールドの条件をチェックしました。

0
heemayl