Remove colunas específicas do csv usando o awk

0

Consegui obter minhas colunas no formato csv conforme mostrado abaixo:

,col1,col2,col3,col4,col5,,

Eu usei este comando awk para obter o nosso arquivo neste formato:

awk -vORS=, '$0 && p {print $2}; $2 == "name" {p=1} ''

e depois usei os dois comandos a seguir para remover as duas vírgulas iniciais e finais:

   cols=${cols:1}
   cols=${cols:0:${#cols}-2}

Agora recebo a saída neste formato:

col1,col2,col3,col4,col5

Eu quero remover colunas específicas da direita que correspondem a uma lista. Por exemplo, se eu chamar a função com o parâmetro "col4, col5", o awk deve remover as duas últimas colunas e imprimir a saída assim:

col1,col2,col3

Como isso pode ser feito no shell script (de preferência com awk ou grep ou algum outro comando suportado pelo shell)?

Atualização: O conteúdo inicial do arquivo é exibido em uma tabela, conforme mostrado abaixo:

+-----------------------------------------+--------+---------+
| name                                    | type   | comment |
+-----------------------------------------+--------+---------+
| col1                                    | int    |         |
| col2                                    | int    |         |
| col3                                    | string |         |
| col4                                    | string |         |
| col5                                    | string |         |
+-----------------------------------------+--------+---------+
    
por user2441441 16.01.2018 / 16:52

2 respostas

1

Você pode usar 'cortar' para extrair certas colunas de dados delimitados. Por exemplo, o abaixo para extrair as duas últimas colunas:

echo col1,col2,col3,col4,col5 | cut -d , -f 4,5

imprime

col4,col5

O argumento -d especifica o delimitador e o -f especifica o índice ou intervalo de índices para os campos resultantes que você deseja em seus resultados

EDITAR

Para torná-lo um pouco mais dinâmico, o abaixo irá selecionar as últimas colunas X com base em um delimitador de Y:

function lastCols {
        endcol=$(($(head -n 1 $1 | grep -o , | wc -l) + 1))
        startcol=$(($endcol-$2+1))
        cut -d $3 -f $startcol-$endcol < $1
}

lastCols $1 $2 $3

Eu não fiz muitos testes sobre isso, então é provável que tenha um pouco de bugs. Use como abaixo:

[]$ cat temp.txt
col1,col2,col3,col4,col5
col1,col2,col3,col4,col5
col1,col2,col3,col4,col5
col1,col2,col3,col4,col5
col1,col2,col3,col4,col5
col1,col2,col3,col4,col5
col1,col2,col3,col4,col5
col1,col2,col3,col4,col5
col1,col2,col3,col4,col5

[]$ ./lastCols.sh temp.txt 2 ,
col4,col5
col4,col5
col4,col5
col4,col5
col4,col5
col4,col5
col4,col5
col4,col5
col4,col5
    
por 16.01.2018 / 17:14
0

Aqui está uma coisa que eu escrevi há vários anos para resolver exatamente esse problema quando eu estava trabalhando muito em openstack e fiquei incomodado com o resultado difícil de analisar das ferramentas openstack:

#! /usr/bin/perl

# untable.pl
#
# Copyright (C) 2012, 2013 Craig Sanders <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# script to strip mysql-style table formatting from nova, keystone,
# glance, etc commands
#
# also works for any tables output from mysql, and from tables produced
# by 'links -dump'
#
# makes the output easily parsable and usable in other scripts.
#
# TODO: command-line option to allow forcing of output style (2-column
# or multi-column) rather than detection.


use strict;

use Carp;
use Getopt::Long;

my $print_headers=0;
my $separator = '';
my $tab = '';
my $result = GetOptions("headers!"  => \$print_headers,
                        "separator=s" => \$separator,
                        "tab" => \$tab,
                       );
$separator = "\t" if ($tab);

my $propval = -1;
our @headers;

while(<>) {
  chomp;
  next if (m/^\+/);

  s/^\|\s*|\s*\|$//iog;  # this / is here to fix SE''s broken perl syntax highlighting.

  my @columns = split '\|';
  # strip leading and trailing spaces
  for my $col (0..scalar @columns-1) {
    if ($columns[$col] eq '') {;
      delete $columns[$col];
    } else {
      $columns[$col] =~ s/^\s+|\s+$//iog;
    };
  }

  # find type of table - 2-column Property/Value, or multi-column
  if ($propval == -1) {
    if ($columns[0] eq 'Property') {
      $propval = 1 ;
      $separator = ": " if ($separator eq '');  # default to ': ' unless specified on cmd line
    } else {
      $propval = 0;
      $separator = "\t" if ($separator eq '');  # default to TAB unless specified on cmd line
      @headers = @columns;
      print (join($separator,@headers),"\n") if $print_headers ;
    };
    next;
  } else {
    print join($separator,@columns),"\n" if (defined $columns[1]);    # skip line unless we have more than one column to output
  }
}

Exemplos:

Duas colunas:

$ keystone tenant-get 93c14424ed06494c832457d974b9505e
+-------------+-----------------------------------------+
|   Property  |                  Value                  |
+-------------+-----------------------------------------+
| description | Anonymous Tenant Description            |
| enabled     | True                                    |
| id          | 93c14424ed06494c832457d974b9505e        |
| name        | ANON1                                   |
+-------------+-----------------------------------------+

$ keystone tenant-get 93c14424ed06494c832457d974b9505e | ./untable.pl
description: Anonymous Tenant Description
enabled: True
id: 93c14424ed06494c832457d974b9505e
name: ANON1

Várias colunas:

$ keystone user-list 810
+-----+---------+-----------------------------+-----------------------------+
|  id | enabled |            email            |             name            |
+-----+---------+-----------------------------+-----------------------------+
| 414 | 1       | [email protected]    | [email protected]    |
| 500 | 1       | [email protected]    | [email protected]    |
| 610 | 1       | [email protected]    | [email protected]    |
| 729 | 1       | [email protected]    | [email protected]    |
+-----+---------+-----------------------------+-----------------------------+

$ keystone user-list 810 | ./untable.pl
414     1       [email protected]    [email protected]
500     1       [email protected]    [email protected]
610     1       [email protected]    [email protected]
729     1       [email protected]    [email protected]
    
por 16.01.2018 / 17:30