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
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.
Algumas abordagens:
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
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
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
{ 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.
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).
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.
Tags text-processing sed