Como adicionar uma nova linha após uma expressão

0

Eu tenho um arquivo semelhante a este:

random_string
83: some words 45: large error report 326: send emails to certain peple
random_string
34: some words 143: job success

Eu quero segmentar o padrão "#:" (um número seguido por dois pontos) e adicionar uma nova linha após o texto que a segue; então é assim:

random_string
83: some words
45: large error report
326: email certain people

random_string
34: some words
143: job success

Eu tentei um comando sed de:

sed "s#'([0-9]*[0-9]:)'#a '/n'#" file.txt
sed "s#'([0-9]*[0-9]:)'#\n#g" file.txt

(Eu não gosto de usar barras como delimitadores, as postagens dificultam a leitura)

e um comando awk de:

awk '/[0-9]*[0-9]:/ {printf "%s\n",$0}' file.txt

E nenhum deles funcionou. Eu olhei para problemas semelhantes postados aqui e tentei suas soluções, mas nada funcionou. Eu sei que a resposta é muito provavelmente muito semelhante e pode até ter algo a ver com a sintaxe na minha expressão numérica, mas eu não consigo descobrir sozinho. Eu não tenho preferência para awk ou sed mas acho que eles seriam as melhores ferramentas à minha disposição.

Ajuda?

    
por cdruckemiller 27.07.2017 / 17:16

4 respostas

1

Aqui está uma solução Perl:

$ perl -pe 's/(\d+:.*?)(?=\d+:|$)/$1\n/g' file
random_string
83: some words 
45: large error report 
326: send emails to certain peple

random_string
34: some words 
143: job success

Explicação

  • (\d+:.*?) : corresponde a um ou mais números ( \d+ ) seguidos por : e, em seguida, a menor string (o ? in .*? torna-o não-voraz, parará assim que o primeiro fósforo é encontrado) correspondendo ao resto do regex. Aqui, continuará até a parte explicada abaixo.
  • (?=\d+:|$) : o (?=foo) é chamado de lookahead positivo . Ele corresponderá, mas o que corresponder não será incluído no resultado real. Portanto, bar(?=foo) corresponderá a todos os casos de bar que forem seguidos por foo . Aqui, estamos procurando por uma sequência de números seguida por um : ( \d+: ) ou o final da linha ( $ ).

Agora, o operador de substituição substituirá todas as ocorrências do primeiro padrão por si próprio e uma nova linha que deverá fornecer a saída desejada.

    
por 27.07.2017 / 17:42
0
$ cat file
random_string
83: some words 45: large error report 326: send emails to certain peple
random_string
34: some words 143: job success

Você pode usar sed:

$ sed 's/[0-9]*: [a-z ]*/&\n/g' file

Saída:

random_string
83: some words 
45: large error report 
326: send emails to certain peple

random_string
34: some words 
143: job success
    
por 27.07.2017 / 17:29
0

awk parece fazer o truque:

$ awk '{ for( i=1; i<=NF; i++ ) { if( match( $i, ":" ) ) { printf "\n" } printf( "%s ", $i ) } }' /path/to/file
random_string
83: some words
45: large error report
326: email certain people random_string
34: some words
143: job success
    
por 27.07.2017 / 17:54
0

Comparando sua entrada à sua saída, parece que sua descrição do que você quer está incorreta. Você diz "Eu quero segmentar o padrão #: (um número seguido por dois pontos) e adicionar uma nova linha depois de" quando uma descrição mais precisa seria:

  • substitua o espaço antes de qualquer número de dígitos seguido por dois-pontos com uma nova linha.
  • insira uma nova linha antes de cada linha não vazia não começar com um dígito.
  • pule a primeira linha de entrada porque não há nada que precise ser alterado nela.

Este script sed implementa isso. Ele usa expressões regulares estendidas ( -E ) em vez da regex básica padrão de sed para minimizar o número de escapes de barra invertida necessários e melhorar a legibilidade.

$ sed -E -e '2,$ {s/ ([0-9]+:)/\n/g; s/^[^0-9]/\n&/}' file.txt
random_string
83: some words
45: large error report
326: send emails to certain peple

random_string
34: some words
143: job success

BTW, se houver uma possibilidade de tabulações em vez de espaços antes dos caracteres [0-9]+: ou vários espaços em branco, use [[:space:]]+ em vez de apenas um espaço. por exemplo,

sed -E -e '2,$ {s/[[:space:]]+([0-9]+:)/\n/g; s/^[^0-9]/\n&/}' file.txt
    
por 28.07.2017 / 03:41