Extraindo linhas com base nas condições

5

Cada linha em um arquivo separado por vírgulas tem 5 campos.

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

Como posso extrair as linhas que têm c no 3º campo e o 5º campo NÃO está vazio? O resultado seria:

a,b,c,d,e
j,k,c,m,n
o,p,c,r,s
    
por Reza 30.05.2015 / 23:54

6 respostas

8

Possível solução com awk :

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

Dependendo dos dados reais, isso pode não funcionar como desejado, como mencionado nos comentários (obrigado Janis por apontar isto: perderá f,g,c,i,0 , por exemplo, 5º campo é 0) para que você possa fazer o seguinte:

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

E como esta é a resposta aceita que estou adicionando não é tão óbvia forçando o 5º campo para string (como na solução cuonglm (+1)):

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

... funcionará para um POSIX sed . Se você puder usar um sed que implementa expressões regulares AT & T Aumentadas - como a disponível gratuitamente no astopen - você pode fazer como:

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

É claro que, se o último caso for verdadeiro, você provavelmente terá um grep semelhante (como pode ser compilado como ksh93 builtin, incidentally) e provavelmente você deve fazer em vez disso:

grep -xX '(([^,]*,){2}c.*)&(.*,)!'
    
por 31.05.2015 / 06:49
2

com awk :

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

Em awk , 0 e "" são dois valores falsos no contexto booleano. Portanto, se você fizer algo como $3 == "c" && $5 , perderá as linhas cujo quinto campo é 0 . $5"" force awk forçar quinto campo para string, string "0" será avaliado como verdadeiro.

    
por 31.05.2015 / 06:34
1

Isso não é tão curto quanto algumas respostas, mas é a única resposta que programaticamente diz exatamente o que é perguntado:

awk '$3 == "c" && $5 != ""' FS=,
    
por 31.05.2015 / 06:51
0

Com o perl, você pode fazer algo como:

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

A opção -a divide as linhas pelo delimitador especificado pela opção -F e depois você pode simplesmente verificar os campos na matriz @F .

    
por 31.05.2015 / 00:05
0

Usando 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()

Aqui, colocamos os campos de cada linha divididos em vírgula ( , ) em uma lista ( fields ) e verificamos as condições nos campos obrigatórios.

    
por 31.05.2015 / 00:07