Como posso dividir uma saída com 2 delimitadores?

2

Ao dividir com os caracteres "·" e "", eu gostaria de mudar isso:

Hel·lo my name is E·ric

Para isso:

Hel·lo my name is E·ric
Hel·lo my name is E·
Hel·lo my name is
Hel·lo my name
Hel·lo my
Hel·lo
Hel·

O código a seguir quase funciona, mas não tenho muita certeza do que preciso ajustar para manter os pontos de sílaba.

sentence="Hel·lo my name is E·ric"
echo $sentence | awk -F'[· ]' -v OFS=" " '{print;for (i=NF;i>1;i--){$i="";print;NF--} }'
    
por TuxForLife 25.07.2015 / 06:48

3 respostas

5
$ echo $sentence | awk -F'[· ]' '{out=$0;print;for (i=NF;i>1;i--){out=gensub(/([· ])[^· ]*[· ]?$/, "\1", "g", out); print out }}'
Hel·lo my name is E·ric
Hel·lo my name is E·
Hel·lo my name is 
Hel·lo my name 
Hel·lo my 
Hel·lo 
Hel·
    
por John1024 25.07.2015 / 07:34
2

Em python:

Como a definição de divisão não é exatamente semelhante para os dois delimitadores (o ponto precisa ser incluído, enquanto o espaço não é), você precisa de duas etapas para dividir:

Em um one-liner (longo):

python3 -c "s = open('f').read().strip(); [print(s[:n]) for n in reversed(sorted([i+1 for i, c in enumerate(s) if s[i] == '·']+[i for i, c in enumerate(s) if s[i] == ' ']+[len(s)]))]"

onde ' f ' é o caminho para o seu arquivo, entre aspas (simples).

Ou mais legível, em um script:

#!/usr/bin/env python3

# read the file
s = open("f").read().strip()
# find the indexes of the character "·" in the line, add 1 to include the dot
n1 = [i+1 for i, c in enumerate(s) if s[i] == "·"]
# find the indexes of spaces in the line
n2 = [i for i, c in enumerate(s) if s[i] == " "]
# combine and sort the found indexes, print the line up to each of the indexes
[print(s[:n]) for n in reversed(sorted(n1+n2)+[len(s)])]

Para corresponder exatamente ao seu exemplo, os índices encontrados são revertidos classificados, do último ao primeiro índice.

Em ambos os casos (como esperado), o resultado é:

Hel·lo my name is E·ric
Hel·lo my name is E·
Hel·lo my name is
Hel·lo my name
Hel·lo my
Hel·lo
Hel·

EDITAR

Um pouco mais sofisticado (e mais flexível) seria:

#!/usr/bin/env python3
# read the file
s = open('f').read().strip()
#--- set your delimiter(s) + the split rules below in the format rules = [(<character>, <additional_index>)]
rules = [('·', 1), (' ', 0)]
#---
[print(s[:n]) for n in [len(s)]+sorted(sum([[i+r[1] for i, c in enumerate(s) if s[i] == r[0]] for r in rules], []))[::-1]]

que lhe dá a "liberdade" de adicionar facilmente mais delimitadores e definir regras para incluir ou não o caractere na string dividida.

por exemplo,

s = 'This|is|a|string'

i.c.w.:

rules = [('|', 0)]

produzirá:

This|is|a|string
This|is|a
This|is
This

mas

s = 'This|is|a|string'

i.c.w.:

rules = [('|', 1)]

produzirá:

This|is|a|string
This|is|a|
This|is|
This|

Nota

O len(s) adicional à lista é incluir a linha inicial na saída.

    
por Jacob Vlijm 25.07.2015 / 09:25
2

Eu sei que você já tem respostas muito boas, mas eu gosto da pergunta e não resisto:

echo $sentence |
perl -C -ne 'do {print} while(s/(.*)[ ·].*/$1/)'
    
por JJoao 04.11.2015 / 10:41