Use sed para encapsular a primeira palavra de cada parágrafo com i / i?

3

Então, obviamente, estou tentando colocar em itálico a primeira palavra de cada parágrafo em um documento enorme. Eu acho que é relativamente fácil adicionar o prefixo, mas como delinear apenas a primeira palavra para o postfix ao invés do final da linha? O arquivo deve ser delimitado por espaço.

sed -e 's/^/<i>/' file > file.new

Preciso executar o sed duas vezes com sintaxe diferente ou isso é possível com um comando? Eu estou saindo para um novo arquivo no caso de eu estragar.

Aqui está um exemplo de algumas linhas do arquivo:

Snapdragon  Plant with a two-lipped flower.

Snap-fastener  = *press-stud.

Snapper  Any of several edible marine fish.

Snappish  1 curt; ill-tempered; sharp. 2 inclined to snap.

Eu quero que seja como abaixo:

<i>Snapdragon</i>  Plant with a two-lipped flower.

<i>Snap-fastener</i>  = *press-stud.

<i>Snapper</i>  Any of several edible marine fish.

<i>Snappish</i>  1 curt; ill-tempered; sharp. 2 inclined to snap.

nem todas as linhas são únicas, alguns termos têm várias linhas de definição.

    
por DanMan3395 06.07.2018 / 17:42

4 respostas

3

Usando sed,

  • se houver uma carta no começo da linha,
  • capture qualquer quantidade de caracteres que não sejam espaços em branco e
  • substitua os caracteres capturados pelo <i> ... </i> .

assim:

sed '/^[a-zA-Z]/ s!\([^ ]*\)!<i></i>!' < file > file.new

Nesta entrada de amostra:

Snapdragon  Plant with a two-lipped flower.

Snap-fastener  = *press-stud.

Snapper  Any of several edible marine fish.

Snappish  1 curt; ill-tempered; sharp. 2 inclined to snap.

A saída é:

<i>Snapdragon</i>  Plant with a two-lipped flower.

<i>Snap-fastener</i>  = *press-stud.

<i>Snapper</i>  Any of several edible marine fish.

<i>Snappish</i>  1 curt; ill-tempered; sharp. 2 inclined to snap.

Para detalhar as partes do comando sed:

  • /^[a-zA-Z]/ - este é um filtro de endereço; significa aplicar o comando subseqüente somente às linhas que correspondem a essa expressão regular. A expressão regular requer que uma letra (minúscula a-z ou maiúscula A-Z ) deva seguir o início da linha ^ .

  • s!\([^ ]*\)!<i></i>! - este é o comando de pesquisa e substituição. Utiliza um delimitador entre a busca e a substituição; o delimitador comum é uma barra invertida, mas como o texto de substituição possui uma barra invertida, alterei o delimitador para um ponto de exclamação ! . O termo de pesquisa tem duas partes: o parêntese de captura, que precisa ser escapado, e a expressão regular [^ ]* , que diz: "corresponde a qualquer coisa - exceto um espaço, zero ou mais vezes * . A substituição text faz referência a esse grupo capturado com e o envolve com a tag HTML.

Para envolver adicionalmente cada linha não vazia com tags de parágrafo, adicione outra expressão sed:

sed -e '/^[a-zA-Z]/ s!\([^ ]*\)!<i></i>!' -e '/./ { s/^/<p>/; s!$!</p>! }' < file

A expressão adicional diz:

  • linhas de correspondência que têm um (qualquer) caractere - isso salta as linhas em branco
  • { agrupa os próximos dois comandos juntos
  • pesquise e substitua o início da linha ^ por uma tag de parágrafo de abertura
  • pesquise e substitua o fim da linha $ por uma tag de parágrafo de fechamento
  • } termina o agrupamento
por 06.07.2018 / 18:08
2

Você pode fazer isso com sed :

$ sed '/^$/n;s#^\([^ ]*\)#<i></i>#' input.txt
<i>Snapdragon</i>  Plant with a two-lipped flower.

<i>Snap-fastener</i>  = *press-stud.

<i>Snapper</i>  Any of several edible marine fish.

<i>Snappish</i>  1 curt; ill-tempered; sharp. 2 inclined to snap.

Explicação

O sed acima inclui 2 blocos. O primeiro bloco detecta todas as linhas em branco, /^$/ e as ignora, n .

  • pule todas as linhas em branco /^$/n

O segundo bloco faz todo o trabalho pesado s#..#..# e detecta sub-strings que não incluem um espaço \([^ ]*\) . Esse padrão é "salvo" por meio do \(..\) que o envolve, para que possamos reutilizá-lo posteriormente por meio do .

  • corresponde à subcadeia até o primeiro espaço \([^ ]*\)
  • salvar correspondência, e envolvê-la com <i>...</i>
por 06.07.2018 / 18:21
1

Você pode tentar com o awk:

awk '{$1="<i>$1</i>"; print $0}' file > file.new

    
por 06.07.2018 / 17:53
0

sed expressão regular estendida

Coloque as tags <i> e </i> ao redor da primeira subcadeia de caracteres [^[:space:]] (não espaciais), usando & para representar o termo de pesquisa no padrão de substituição, independentemente de a linha estar recuada. / p>

Usando -E para ativar as expressões regulares estendidas de sed :

sed -E 's/[^[:space:]]+/<i>&<\/i>/' file

Ao usar / para separar os termos de pesquisa e substituição, você precisa preceder outros / com \ (como na segunda tag aqui). Você pode evitar essa etapa extra usando um caractere diferente de / para separar os termos de pesquisa e de substituição, desde que esse caractere não apareça nos termos. Por exemplo, usando vírgulas:

sed -E 's,[^[:space:]]+,<i>&</i>,' file

Esse é o caminho mais curto.

O + (que significa uma ou mais ocorrências do padrão) não funciona em expressões regulares comuns ( -e em vez de -E ), mas você pode fazer a mesma coisa usando * ( que representa zero ou mais ocorrências) com um pouco mais de digitação:

sed -e 's,[^[:space:]][^[:space:]]*,<i>&</i>,' file
    
por 06.07.2018 / 21:28