Separe dois valores de um grande texto, enquanto cada uma das leituras é separada por uma linha em branco

1

Eu tenho uma paz de grande arquivo de texto com leituras como abaixo,

name=ABC
class=3
age=7
roll_no=41 

name=XYZ
class=4
age=9
roll_no=23 

Então, como posso separar cada name com seus respectivos age e escrever o resultado em uma única linha, valores separados por um espaço, como este

ABC 3
XYZ 9

Existe alguma ferramenta / script para salvar o resultado no formato JSON ?

Tentei horas com awk , sed , tr , grep etc. etc. mas sou horrível no processamento de texto na linha de comando, obrigado antecipadamente.

    
por Arnab 30.09.2016 / 08:53

4 respostas

2

Eu usaria o awk:

awk -F"=" '
    {data[$1] = $2} 
    function output() {
        if ("name" in data && "age" in data) 
            print data["name"], data["age"]
        delete data
    }
    NF == 0 {output()} 
    END     {output()}
' filename
    
por 30.09.2016 / 12:18
1

Se perl estiver disponível, pedaços de texto separados por uma ou mais linhas em branco serão perfeitos para processamento com o modo de parágrafo de perl :

perl -n00e ' # Read the input file paragraph-by-paragraph
  # Split each paragraph into lines and join the lines with an = sign:
  $s = join "=",split /\n/;
  # Split the joined fields on = signs (with possible blanks around them):
  %h = split /\s*=\s*/,$s;
  print "$h{name} $h{age}\n" # Print the required information
' your_file

Acima, o código analisa seu arquivo na estrutura hash ( %h ), onde as chaves são os nomes dos campos (à esquerda dos sinais = ) e os valores são os valores dos campos (à direita dos sinais = ) em cada linha. Depois que o parágrafo foi analisado nessa estrutura, imprimimos os valores dos campos "name" e "age".

    
por 30.09.2016 / 09:08
1

Você pode usar o comando abaixo:

grep -E "name|age" filename | sed 'N;s/\n/ /' | sed 's/[=,]/ /g'| awk '{ print $2, $4}'

isso dará saída como:

ABC 7
XYZ 9

EDITAR:

Abaixo, o comando fornecerá a linha com a string name ou age

grep -E "name|age" filename

name=ABC
age=7
name=XYZ
age=9

Este comando fará uma linha de duas linhas

grep -E "name|age" filename | sed 'N;s/\n/ /'
name=ABC age=7
name=XYZ age=9

Abaixo, o comando removerá o sinal igual = da saída

grep -E "name|age" filename | sed 'N;s/\n/ /' | sed 's/[=,]/ /g'
name ABC age 7
name XYZ age 9

Abaixo do comando imprimindo seu requiremnt

grep -E "name|age" filename | sed 'N;s/\n/ /' | sed 's/[=,]/ /g'| awk '{ print $2, $4}'
ABC 7
XYZ 9

awk imprimindo o segundo e quarto argumento da saída de comando anterior

você ainda está enfrentando algum problema para entender qualquer sintaxe que o google possa explicar em profundidade :).

    
por 30.09.2016 / 12:02
0

Desde que você pediu outro idioma. Aqui está uma maneira de fazer isso em Python, salvando a entrada em um dicionário para que você possa acessar facilmente os valores com as chaves name e age :

#!/usr/bin/env python3

myDict = {}

with open("ages") as inFile:
    for line in inFile:
       if line == "\n":
            print(myDict['name'].rstrip() + " " + myDict['age'], end="")
            continue
       (key, value) = line.split("=")
       myDict[key] = value

print(myDict['name'].rstrip() + " " + myDict['age'], end="")

Dado este infile ( ages ):

name=ABC
class=3
age=7
roll_no=41

name=XYZ
class=4
age=9
roll_no=23

Eu recebo este resultado:

./pyAges.py 
ABC 7
XYZ 9
    
por 30.09.2016 / 11:35