Redirecionar saída filtrada para arquivo

4

Eu redireciono minha saída para um arquivo e recebo algo assim:

|  id  | code | color_code | 
-------+------+------------+
|11A00B|  15  | 9129102    |
|11A00C|  16  | 9129103    |
(2 rows)

|  id  | code | color_code | 
-------+------+------------+
|11B00B|  25  | 9129152    |
|11B00C|  36  | 9129162    |
(2 rows)

|  id  | code | color_code | 
-------+------+------------+
|11C00B|  22  | 9129107    |
|11C00C|  9   | 9129108    |
(2 rows)

Como posso convertê-lo em estilo csv como:

|  id  | code | color_code | 
|11A00B|  15  | 9129102    |
|11A00C|  16  | 9129103    |
|11B00B|  25  | 9129152    |
|11B00C|  36  | 9129162    |
|11C00B|  22  | 9129107    |
|11C00C|  9   | 9129108    |

Para obter o primeiro arquivo, o loop é executado e inicia os scripts SQL. Tudo que faço é simplesmente > file . Mas eu não tenho controle sobre o loop. Provavelmente, informações já podem ser filtradas durante a iteração. Mas isso é bastante duvidoso.

    
por user1648825 18.10.2016 / 10:32

6 respostas

6

awk :

awk 'NR==1; /^\|[0-9]/'
  • A ação padrão em awk é imprimir o registro

  • NR==1 corresponde ao primeiro registro (linha)

  • /^\|[0-9]/ corresponde a qualquer registro começando com | seguido por um dígito

Exemplo:

% cat file.txt                    
|  id  | code | color_code | 
-------+------+------------+
|11A00B|  15  | 9129102    |
|11A00C|  16  | 9129103    |
(2 rows)

|  id  | code | color_code | 
-------+------+------------+
|11B00B|  25  | 9129152    |
|11B00C|  36  | 9129162    |
(2 rows)

|  id  | code | color_code | 
-------+------+------------+
|11C00B|  22  | 9129107    |
|11C00C|  9   | 9129108    |
(2 rows)

% awk 'NR==1; /^\|[0-9]/' file.txt
|  id  | code | color_code | 
|11A00B|  15  | 9129102    |
|11A00C|  16  | 9129103    |
|11B00B|  25  | 9129152    |
|11B00C|  36  | 9129162    |
|11C00B|  22  | 9129107    |
|11C00C|  9   | 9129108    |
    
por heemayl 18.10.2016 / 11:54
5

Você pode canalizar sua saída por meio do comando sed :

sed '1p;/^|/!d;/^|\s*id/d'

Explicação:

  • A expressão 1p apenas ecoa a primeira linha.
  • A expressão /^|/!d remove qualquer linha que não comece com | .
  • A expressão /^|\s*id/d remove qualquer linha que comece com | e, em seguida, alguns (ou nenhum) caracteres em branco, seguidos por id . Nós já imprimimos nosso cabeçalho usando a primeira expressão, então está tudo bem que esta expressão descarte agora.
por Melebius 18.10.2016 / 10:57
3

Você pode usar sed para imprimir apenas as coisas que deseja

sed -n '1p; /^|[0-9]/p' file

Explicação

-n não imprime nada até solicitarmos 1p imprimir a primeira linha
^|[0-9]/p imprimir a linha se começar com | seguido de um número

    
por Zanna 18.10.2016 / 10:58
1

Aqui está um pequeno script em Perl que você pode usar para isso:

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

my$file="file.txt";

open(IN,"<",$file); 
my$head=<IN>; 
print $head; 
while(<IN>)
{
  print $_ if $_=~/^\|\S+/;
} 
close IN;

Isto irá imprimir a primeira linha do seu arquivo de entrada como cabeçalho e então passar o resto do arquivo e imprimir as linhas de conteúdo.

Nota:

Estou assumindo aqui que suas linhas de conteúdo sempre começam com um símbolo de pipe, seguido por um ou mais caracteres que não são espaços em branco ( |\S+ ). Por favor, deixe-me um comentário, se esse não for o caso, então eu posso ajustar o regex.

    
por Wayne_Yux 18.10.2016 / 10:47
1
your_command | grep "|"

eliminará essas linhas (2 linhas) e vazias. Você pode adicionar outro grep -v "id" que irá remover todos os cabeçalhos, então você só precisa adicionar um cabeçalho com o comando echo ao início.

    
por marosg 18.10.2016 / 10:47
1

Que tal este pequeno script de shell? Ele usa a resposta do user596137 com grep e grava a saída nesse arquivo

#!/bin/bash

FILE=
FIRST_LINE='head -n1 ${FILE}'
INPUT='cat ${FILE} | grep "|" | grep -v "id"'

echo "$FIRST_LINE" > $FILE; echo "$INPUT" >> $FILE

Salve esse script e conceda permissão de execução a ele. Este script precisa de um nome de arquivo como o primeiro parâmetro.

    
por Kev Inski 18.10.2016 / 11:02