Manter apenas a coluna .csv contendo dados X Y Z?

1

Como posso manter dados da linha .csv que contenham apenas as palavras dog ou cat e só verificar na segunda coluna, se a palavra "cachorro" aparecer em qualquer outra coluna, mas não na segunda, deve ser ignorado.

Por exemplo, se eu tivesse:

email1.com dog
email2dog.com steve
email3.com cat

Resultado esperado:

email1.com dog
email3.com cat

Talvez haja uma longa lista de palavras a serem mantidas, se possível, carregá-las de outro arquivo.

    
por Teddy291 17.06.2015 / 09:41

5 respostas

4

com sed :

$ sed -n -e 's/dog$/&/p' -e 's/cat$/&/p' file
email1.com dog
email3.com cat

Ou você pode usar awk :

awk '$2~/^dog|cat$/' file
    
por 17.06.2015 / 09:44
1

Algumas abordagens:

  1. Se a dog ou cat for sempre a última palavra na linha:

    awk '/(dog|cat)$/' file
    grep -E '(dog|cat)$' file
    sed -n '/\(dog\|cat\)$/p' file
    perl -ne 'print if /(dog|cat)$/' file
    
  2. Se o dog ou cat puder estar em qualquer lugar no segundo campo delimitado por espaço :

    awk '$2~/dog|cat/' file
    grep -E '^\S+\s+\S*(dog|cat)\S*\s*' file
    perl -ane 'print if $F[1]=~/dog|cat/' file
    sed -nr '/^\S+\s+\S*(dog|cat)\S*\s*/p' file
    sed -n '/^\S\+\s\+\S*\(dog\|cat\)\S*\s*/p' file
    
  3. Para ler os padrões de pesquisa de um arquivo, você pode fazer:

    awk '{if(NR==FNR){a[$0]++; next}for(p in a){if($2~p){print}}}' patterns  file
    
por 17.06.2015 / 11:12
1
{   sed 's/[]$^&\./*[]/\&/g;s/$/$/'|
    grep -f- ./greppedfile
}   <words

lidaria com o caso em que você lida com muitos padrões de correspondência em words que continha um padrão por linha. Ela cuida para escapar qualquer possível regexp metacharacters e, em seguida, ancora o padrão resultante - na cauda da linha - de modo que qualquer personagem em words será acompanhado literalmente por grep e seu padrão só serão correspondidos se palavra ocorrer na cauda de uma linha - que é o que eu acho que entendo ser desejado.

Normalmente, com grep , não temos as fugas do metachar, porque podemos usar os padrões -F ixed-string - que não têm nenhum. Mas isso também significa que não podemos usar o $ metachar para ancorar o padrão, então trabalhamos com o que temos.

    
por 17.06.2015 / 15:42
0

Eu faria assim em perl:

#!/usr/bin/perl;
use strict;
use warnings;

my @words      = qw ( dog cat );
my $column_num = 1;                #perl starts arrays zero.

my $regex = join( "|", map {quotemeta} @words );
$regex = qr/$regex/;

while (<>) {
    print if ( split() )[$column_num] =~ $regex;
}

Você 'carrega' uma expressão regular com @words - qw é simplesmente 'palavras entre aspas', por exemplo espaço delimitado. Você transforma isso em uma expressão regular.

Em seguida, usando o operador de diamante <> que lê a partir de <STDIN> ou abre os arquivos conforme listado na linha de comando (então cat $file | ./myscript.pl ou ./myscript.pl <filename> ) - nós lemos cada linha.

Verificamos a presença dessa expressão regular no número da coluna designada (divisões no espaço em branco por padrão).

    
por 17.06.2015 / 12:17
0

Usando grep com o PCRE:

$ grep -P '^[^ ]+\s+dog|cat(?=\s|$)' file.txt 
email1.com dog
email3.com cat

Isso imprimirá as linhas em que dog ou cat aparece apenas na segunda coluna da linha.

    
por 17.06.2015 / 13:11