Encontre apenas o padrão correspondente em um arquivo CSV

5

Estou tentando imprimir apenas o padrão correspondente em um arquivo CSV. Exemplo: todas as colunas começam com 35=its value . Obrigado.

Arquivo CSV:

35=A,D=35,C=129,ff=136
D=35,35=BCD,C=129,ff=136
900035=G,D=35,C=129,ff=136
35=EF,D=35,C=129,ff=136,35=G
36=o,D=35,k=1

Saída:

35=A
35=BCD
35=EF
35=G

O comando que usei não funcionou:

sed -n '/35=[A-Z]*?/ s/.*\(35=[A-Z]*?\).*//p' filename
    
por user102299 13.06.2017 / 13:28

5 respostas

12

Com GNU grep , que suporta a opção -o , para imprimir somente strings correspondentes, cada uma em sua própria linha

$ grep -oE '\b35=[^,]+' ip.csv 
35=A
35=BCD
35=EF
35=G
  • \b é limite de palavras, de forma que 900035 não corresponderá a
  • [^,]+ para corresponder a um ou mais não , caracteres
  • assume que os valores não contêm ,


Com awk

$ awk -F, '{ for(i=1;i<=NF;i++){if($i~/^35=/) print $i} }' ip.csv 
35=A
35=BCD
35=EF
35=G
  • -F, set , como separador de campos de entrada
  • for(i=1;i<=NF;i++) iterar em todos os campos
  • if($i~/^35=/) se o campo começar com 35=
    • print $i imprime esse campo

Similar com perl

perl -F, -lane 'foreach (@F){print if /^35=/}' ip.csv 
    
por 13.06.2017 / 13:38
13

Usando tr para substituir todas as vírgulas por novas linhas e, em seguida, grep para obter todas as linhas que começam com a string 35= :

$  tr ',' '\n' <data.in | grep '^35='
35=A
35=BCD
35=EF
35=G
    
por 13.06.2017 / 14:38
5

Com perl:

$ perl -lne 'print for /(\b35=[^,]+)/g' filename
35=A
35=BCD
35=EF
35=G

ou talvez de forma mais geral / robusta usando o Módulo Text :: CSV

$ perl -MText::CSV -lne '
  BEGIN{$p = Text::CSV->new()} 
  print for grep { /^35=/ } $p->fields(), $p->parse($_)
' filename
35=A
35=BCD
35=EF
35=G
    
por 13.06.2017 / 13:50
2

Looks de Perl com grep funcionam muito bem.

grep -oP '(?<=35\=).*?(?=,)'

Isso retorna a informação exata menos o 35= bit

grep -oP '(?<=35\=).*?(?=,)' file.csv retornará isso

A
BCD
G
EF

    
por 13.06.2017 / 13:51
0

Solução pura de Bash:

(                                                  # Use parentheses as scope for IFS
    IFS=$',\n'                                     # Split on both , or \n
    for c in $(</tmp/file.csv)                     # For every column or row
    do
        [[ "$c" =~ ^35= ]] && echo ${line##35=}    # Find ^35= and print while removing ^35=
    done
) # Optionally >/tmp/filtered-output.txt

Observação: use isso apenas por sua legibilidade e flexibilidade - se puder lê-lo , caso contrário, você poderá usar a seguinte abordagem:

# Read            | Replace     | Find        | Remove
cat /tmp/file.csv | tr ',' '\n' | grep '^35=' | sed 's/^35=//'

que é mais intuitivo e eficiente.

Entrada (/tmp/file.csv):

35=A,D=35,C=129,ff=136
D=35,35=BCD,C=129,ff=136
900035=G,D=35,C=129,ff=136
35=EF,D=35,C=129,ff=136,35=G
36=o,D=35,k=1

Saída:

A
BCD
EF
G
    
por 13.06.2017 / 23:04