Como SED estes parágrafos para o formato MCQ?

5

Meus dados:

Question Nr.  311
Main proteins are in the lorem ipsun
A Lorem RNA test
B Cells
C Metoclom
D Cells
E Muscles

Question Nr.  312
Main proteins are in the lorem ipsun
A Lorem
B Cells
C Metoclom
D Cells
E Muscles

...

Formato desejado:

\item 
Main proteins are in the lorem ipsun

A Lorem RNA test

B Cells

C Metoclom

D Cells

E Muscles

\item
Main proteins are in the lorem ipsun

A Lorem

B Cells

C Metoclom

D Cells

E Muscles

\item ...

Onde estou planejando apresentar as opções em cada nova linha.

Minha tentativa:

sed s/Question Nr.*/\item/g

Qual deve substituir todas as linhas com Pergunta Nr [qualquer coisa na linha] - problema está na detecção do que vem depois, já que pode haver muitas opções, mas o fim das opções é \n\n , ou seja, a nova linha.

Problema de semistagem aqui:

\item 
Main proteins are in the lorem ipsun
A Lorem RNA test
B Cells
C Metoclom
D Cells  
E Muscles

\item 
Main proteins are in the lorem ipsun
A Lorem
B Cells
C Metoclom
D Cells  
E Muscles

Outros desafios

  • Ter palavras em maiúsculas como HIV e RNA nas opções; algumas soluções abaixo inserem linha vazia depois de HI e RN

Como você pode obter minha saída desejada em sed / perl ?

    
por Léo Léopold Hertz 준영 20.11.2015 / 23:36

5 respostas

5

Outra maneira com tr + sed :

tr -s \n <infile | sed '$!G;s/Question Nr.*/\item/'

tr comprime todas as novas linhas e sed acrescenta conteúdo de espaço (nova linha vazia) a cada linha, exceto a última, substituindo Question Nr.* por \item . Com esse método, você não poderá editar o arquivo no local. Eu escolhi tr aqui, pois é mais rápido que a regex de sed (mesmo que não seja tão limpa quanto uma solução sed -only)

    
por 21.11.2015 / 12:18
6

com sed :

sed 's/^Question Nr\..*/\item/; s/^\([A-Z] .*\)/\n/' file
  • O primeiro s/// substitui Question Nr. por \item semelhante ao comando sed em sua pergunta.
  • O segundo substitui a linha que começa com uma letra maiúscula de A a Z , mas apenas uma seguida por um espaço. Esta linha inteira é substituída por si mesma repending a newline \n .

A saída:

\item
Main proteins are in the lorem ipsun

A Lorem

B Cells

C Metoclom

D Cells

E Muscles

\item
Main proteins are in the lorem ipsun

A Lorem

B Cells

C Metoclom

D Cells

E Muscles
    
por 20.11.2015 / 23:47
5

Se não precisar ser sed , o "modo de parágrafo" de Perl é perfeito para isso. De man perlrun :

   -0[octal/hexadecimal]
        specifies the input record separator ($/) as an octal or
        hexadecimal number.  [...]

        The special value 00 will cause Perl to slurp files in paragraph
        mode.  [...]

Portanto, usando -00 diz ao perl para definir "linhas" como parágrafos, ele usa \n\n como o caractere de fim de linha. Com isso em mente, você poderia fazer algo como:

$ perl -00pe 's/Question.*/\item/; s/[A-Z] /\n$&/g;' file
\item
Main proteins are in the lorem ipsun

A Lorem

B Cells

C Metoclom

D Cells

E Muscles

\item
Main proteins are in the lorem ipsun

A Lorem

B Cells

C Metoclom

D Cells

E Muscles

O primeiro operador de substituição substitui todas as linhas que correspondem à string Question com \item e a segunda adiciona uma nova linha antes de cada letra maiúscula seguida por um espaço.

    
por 20.11.2015 / 23:47
5
sed -e'/./!d;$!G;/^Q/c\' -e'\item' <in >out

Isso irá d excluir todas as linhas em branco na entrada, G et uma linha em branco fora do espaço de espera e anexá-las a todas as linhas não em branco que são ! não $ last e c hange qualquer espaço de padrão ^ começando com o caractere Q na sequência de uma linha fixa \item na saída.

Quando executado em sua entrada de exemplo, a saída é:

\item
Main proteins are in the lorem ipsun

A Lorem

B Cells

C Metoclom

D Cells

E Muscles

\item
Main proteins are in the lorem ipsun

A Lorem

B Cells

C Metoclom

D Cells

E Muscles

(sem linha em branco no final da saída)

Portavelmente, a instrução sed -e xpression não deve terminar em uma barra invertida como essa e, portanto, pode estar escrito:

sed -e'/./!d;$!G;/^Q/c\'"$(printf '\n\\item')" <in >out
    
por 21.11.2015 / 01:01
4

Agora com awk :

awk '$1 ~ /[ABCDEM]/ {print $0"\n"} $1 ~ /Question/ {print "\item"}' inputfile

Se a linha começar com A, B, C, D, E ou M (para Main), esta linha é impressa e um \n extra. Se a linha começar com "Pergunta", ela simplesmente imprime \item .

    
por 20.11.2015 / 23:49