como inserir texto no começo de cada parágrafo no bash

2

Eu tenho um arquivo com vários parágrafos separados por linha em branco. Tecnicamente, eles não são parágrafos, apenas seções de texto separadas por linhas em branco.

Eu quero numerar os parágrafos, por assim dizer, inserindo um número na primeira linha de cada linha seguindo uma linha em branco. Então, se meu arquivo diz:

This is text.
This is more text.
Even more text!

This is text in section two.
Some more text.
You get the point...

Eu quero dizer:

1This is text
this is more text
Even more text!

2This is text in section two.
Some more text.
You get the point...
    
por OB7 02.05.2015 / 06:04

2 respostas

1

Tente isso com os comandos incorporados do bash:

#!/bin/bash

l=1                          # paragraph counter
echo -n $l                   # print paragraph counter without new line
while read x; do             # read current line from file, see last line
  if [[ $x == "" ]]; then    # empty line?
    echo                     # print empty line
    read x                   # read next line from file, see last line
    ((l++))                  # increment paragraph counter
    echo -n $l               # print paragraph counter without new line
  fi
  echo "$x"                  # print current line
done < file
    
por 02.05.2015 / 07:32
1

Em geral, usar o shell para análise de texto é muito lento e complicado. Aqui estão algumas outras opções:

  1. Perl no "modo de parágrafo"

    perl -00pe 's/^/$./' file 
    

    Explicação

    O -00 ativa o modo de parágrafo onde "linhas" são definidas por \n\n consecutivos, parágrafos em outras palavras. O s/^/$./ substituirá o início da linha ( ^ ) pela atual "linha" (parágrafo) número $. . O -p diz ao perl para imprimir cada linha do arquivo de entrada depois de executar o script fornecido por -e sobre ele.

  2. Awk

    awk -vRS='\n\n' -vORS='\n\n' '{print NR$0}' file
    

    Explicação

    -vRS='\n\n' define o separador de registros do awk para caracteres consecutivos de nova linha. Como o modo de parágrafo do perl, isso faz com que ele trate os parágrafos como "linhas". Em seguida, informamos para imprimir o número da linha atual ( NR ) e a "linha" atual $0 . O -vORS= define o separador de registro de saída como novas linhas consecutivas, de forma que os parágrafos também sejam separados por linhas em branco na saída. Observe que isso adicionará 2 linhas vazias no final da saída. Para evitar isso, você pode usar head :

    awk -v RS='\n\n' -vORS='\n\n' '{print NR$0}' file | head -n -2
    

Por meio de comparação, aqui estão os horários que as várias soluções tomaram no meu sistema quando executadas em um arquivo de teste de 10M:

$ time a.sh > /dev/null ## a.sh is Cyrus's solution

real    0m1.419s
user    0m1.308s
sys     0m0.104s

$ time perl -00pe 's/^/$./' file  > /dev/null 

real    0m0.087s
user    0m0.084s
sys     0m0.000s

$ time awk -v RS='\n\n' -vORS='\n\n' '{print NR$0}' file | head -n -2 >/dev/null

real    0m0.074s
user    0m0.056s
sys     0m0.020s

Como você pode ver acima, as soluções perl e awk são uma ordem de magnitude mais rápida que a abordagem shell.

    
por 18.05.2015 / 16:19