Unix - Comando Sed relacionado

Unix - Comando Sed relacionado

#nomedoarquivo como $1

#nome comercial como $2

#atualizado no ano $3 #Pode corresponder a qualquer vírgula dentro dos valores de cotação, desde que esteja antes do V correspondente para o código postal. Todos eles começam com V.

./script6_1.sh bcindigenousbusinesslistings.csv "B.*" 2021

Para encontrar todos os negócios que começam com B atualizados em 2020 ou posteriormente.

#O primeiro sed é para colocar da linha 2 até a última linha #O segundo sed : No início da linha, pode corresponder a qualquer padrão até o V (código postal) então irá parar $3 irá corresponder a qualquer número que tem padrão de 20(1 a 3) e (0-9) para o último dígito

*sed -n '2,$p' $1 | sed -e 's/^\('$2'[^,]*,[^,]*,[^,]*,.*[^V],\)\('$3'202[0-9]\)/\1\2/'*

O ponto principal é extrair 3 colunas, cada uma separada por vírgulas. Negócio, descrição, endereço. A última coluna é Ano atualizado. Dentro da descrição da coluna, pode haver mais vírgulas separadas.

Estou tendo um erro nisso, pois apenas imprime toda a linha, sem extrair o padrão correspondente.

Responder1

Se você quiser trabalhar com colunas dentro de uma linha em vez de com a linha inteira, então awkor perlseria uma ferramenta muito melhor para esse trabalho do que sed.

E, como você precisa lidar com campos entre aspas (com vírgulas dentro deles), seria melhor usar perlporque tem umTexto::CSVmódulo que analisa arquivos CSV assim. Você poderia fazer isso com awk, mas teria que escrever seu próprio analisador para lidar com aspas e vírgulas dentro dos campos.

Se você estiver executando o Debian ou similar, instale com apt install libtext-csv-perl. Outras distros provavelmente também o possuem. Caso contrário, instale-o com cpan.

A seguir está um exemplo bastante simples do que você pode fazer com Text::CSV. Corra man Text::CSVpara obter detalhes.

#!/usr/bin/perl

use strict;

use Text::CSV qw(csv);

my ($filename, $search, $year) = @ARGV;

my $csv = Text::CSV->new({allow_whitespace => 1,
                          allow_loose_quotes => 1,
                          quote_space => 0,
                         });

open(my $in, "<", $filename) or die "couldn't open $filename: $!";

my @headers = $csv->header($in);
pop @headers;                   # discard last field from @headers
$csv->say(*STDOUT, \@headers);  # print the headers

while (my $row = $csv->getline($in)) {

  # note: perl arrays start from zero, not one. So $row->[0] is
  # the first field.  $row->[3] is the fourth.

  if ($row->[0] =~ m/$search/i && $row->[3] == $year) {
    pop @{ $row };  # discard last field (year)
    $csv->say(*STDOUT, $row);
  }

}
close($in);

Salve-o como, por exemplo, extract.ple torne-o executável com chmod +x extract.pl- da mesma forma que faria para um script de shell.

Você não forneceu dados de entrada ou saída de amostra em sua pergunta, então tive que inventar algumas bobagens.

Dado o seguinte arquivo de entrada input.csv,:

business,description,address,year
"ABC","sells some items","123 Somewhere Street, Somewhere, V1234",2020
"BCD Co.","sells some items","123 Somewhere Street, Somewhere, V1234",2021
"BBB Pty Ltd","sells some items","123 Somewhere Street, Somewhere, V1234",2020
"BXYZ","sells some items","123 Somewhere Street, Somewhere, V1234",2021
"CDE","sells some items","123 Somewhere Street, Somewhere, V1234",2020
"DEF","sells some items","123 Somewhere Street, Somewhere, V1234",2020

Ele produzirá a seguinte saída:

$ ./extract.pl input.csv '^b' 2021
business,description,address
BCD Co.,sells some items,"123 Somewhere Street, Somewhere, V1234"
BXYZ,sells some items,"123 Somewhere Street, Somewhere, V1234"

ou seja, todos os nomes comerciais que começam com "B" ou "b" (a correspondência de regex não diferencia maiúsculas de minúsculas) com o ano 2021. Somente os 3 primeiros campos são impressos.

Observe como a saída cita campos apenas onde é essencial (ou seja, onde há vírgulas dentro dos campos). Se você quiser que os campos que contêm espaços também sejam citados, altere quote_space => 0para quote_space => 1no script (ou apenas exclua essa linha, pois citar campos com espaços é o padrão para Text::CSV)

informação relacionada