comando SED para formatar o arquivo de texto

1

Eu preciso criar um comando SED para modificar um arquivo de entrada com algumas condições explicadas abaixo.

Eu tenho um arquivo de entrada como abaixo.

Item da lista

Rad# ; ID_KEY ; UNIT_ID
1  ; 30000000004 ; 8417920 
2  ; 30000000004 ; 8170811 
         ︙
10  ; 30000000004 ; 1581292
           ︙
1001  ; 3000000000 ; 8285052

Abaixo estão algumas coisas que preciso fazer com este arquivo:

  1. Remover a 1ª linha completamente
  2. Reter apenas o segundo e terceiro grupos de números separados por vírgula
  3. Anexar string ,DATABASE no final de cada linha.

A saída deve ser algo como abaixo.

Item da lista

30000000004,8417920,DATABASE
30000000004,8170811,DATABASE
    
por Sandeep Dongapure 20.03.2015 / 11:30

4 respostas

3

Supondo que a saída na pergunta é a saída desejada, você pode tentar isso.

awk -F';'  'BEGIN{OFS=",";} NR>1{gsub(/ /,""); print $2,$3,"DATABASES"}' filename | sed -e :a -e '$!N;s/\n/,/;ta' 

Provavelmente isso pode ser feito com awk apenas. Remova a parte sed se você quiser linhas na mesma linha.

Como o SE parece ter fins educativos, farei o possível para explicar o que cada sinalizador no comando acima faz.

-F';' # Usa ; como --field-separator
BEGIN {OFS=",";} # Esse é um padrão especial que é executado antes de qualquer comando que se segue e sua saída não é influenciada pelo restante do programa. Então temos ORS

ORS # Como a saída deve incluir uma vírgula , , definimos a Output Record Separator para ter vírgula como um valor. O valor padrão de ORS é uma nova linha "\n"

NR>1 # Aqui dizemos para pular o primeiro registro. NR também é uma variável especial reservada que contém o número total de registros de entrada.

gsub() # É uma função que aceita alguns parâmetros. Se nenhum campo especificado, por exemplo, $2 ou $3 , em seguida, gsub() function usar o registro inteiro, que é $0

Finalmente, print $2,$3,"DATABASE" imprimirá os campos especificados e adicionará DATABASE no final da linha.

print $2,$3 # Aqui usamos vírgula para separar campos. O delimitador padrão FS (Field separator) é um único espaço em branco ' ' .

Espero que esta breve descrição clarifique um pouco as coisas.

    
por 20.03.2015 / 11:48
2

Eu estou supondo que você quer dizer que você quer cada linha de entrada (após o cabeçalho) para traduzir em uma linha de saída (e nem todos executados juntos em uma linha, como a primeira versão da sua pergunta ilustrada). sed é uma ferramenta muito boa para esse trabalho; isso pode ser feito como

sed -e 1d -e "s/.* ; \(.*\) ; \(.*[^ ]\) */,,DATABASE/" filename

onde

  • 1d significa excluir a primeira linha e
  • s/.* ; \(.*\) ; \(.*[^ ]\) */,,DATABASE/
    significa quebrar cada linha (após a primeira) na
    something1 ; something2 ; something3
    e substitua-o por um something2,something3,DATABASE
    A parte .*[^ ] é para excluir quaisquer espaços à direita de something3 .
por 20.03.2015 / 12:12
1

Como nos comentários, solução awk:

awk '{ FS=";"; OFS=","; gsub(/^[ \t]+/, "", $2); gsub(/[ \t]+$/, "", $2); gsub(/^[ \t]+/, "", $3); gsub(/[ \t]+$/, "", $3); } NR > 1 { print $2, $3, "DATABASE" }' file
    
por 20.03.2015 / 11:48
1

Eu provavelmente faria:

cut -d' ' -f3,5 <infile | 
sed -n 'y/ /,/;1!s/$/,DATABASE/p'

... como acho que provavelmente está próximo da solução mais eficiente para esse problema.

    
por 20.03.2015 / 14:16