Usando sed para cortar uma string começando com n espaços e terminando com n espaços

1

Como usar sed para cortar texto começando com x espaços e terminando com y espaços?

Por exemplo, esta é minha string:

 kkk 111 fff      aaabbb 5d98 ccc         mmmppp 9369d

e quero obter este resultado:

 aaabbb 5d98 ccc

(o número de espaços não é conhecido)

Obrigado.

    
por pr.nizar 13.01.2015 / 14:45

5 respostas

1

Nós falamos sobre algum texto que aparece com uma quantidade desconhecida de espaços, então

sed 's/.* \{2,\}\([[:alnum:]].*\) \{2,\}.*//'

ou com -r (-E)

sed -E 's/.* {2,}([[:alnum:]].*) {2,}.*//'

parece ser suficiente, mas grep é melhor no caso

grep -Po ' {2,}\K[[:alnum:]].*(?= {2,})'

E não tão strong (apenas com dois espaços em branco), mas também correto:

sed -E 's/.*  (\w.*)  .*//'
    
por 13.01.2015 / 15:38
0

Edit: Eu pedi emprestado o -r flag (permite sintaxe de regex estendida) de jimmij para curar backlashitis.

Os seguintes trabalhos, sob as seguintes condições:

  • você está disposto a dizer que o separador de campo é pelo menos n espaços, por exemplo 3
  • o conteúdo do campo de interesse não inclui um espaço em lugar algum.

Nesse caso, esse regex funciona:

    echo ' 01      Title      Chapter 01' |
    sed -r 's/^.* {3,}([^ ]+) {3,}.*$//'

Ou, caso você goste das barras invertidas, isso é o que parece na sintaxe de regex não extendida:

    echo ' 01      Title      Chapter 01' |
    sed 's/^.* \{3,\}\([^ ]\+\) \{3,\}.*$//'

Explicação do regex:

^        start of line
.*       any number of characters at the start of the line
 {3,}    at least 3 spaces
([^ ]+)  1 or more non-space characters (capture this group as )
 {3,}    at least 3 spaces
.*       anything on the rest of the line
$        end of the line. Not needed, because of the .*, but nicely explicit.
    
por 13.01.2015 / 15:02
0

Supondo que você deseja o mesmo número de espaços em ambos os lados:

$ sed -r 's/(^|.*[^[:space:]])([[:space:]]+)([^[:space:]]+)([^[:space:]].*|$)//g' <<<"01      Title      Chapter 01"
Title

(Eu usei a classe de caractere em vez de apenas , com apenas um espaço, a expressão deve ser consideravelmente menor: sed -r 's/(^|.*[^ ])( +)([^ ]+)([^ ].*|$)//g' ).

Usando a referência anterior no LHS, garantimos que o mesmo número de espaços esteja presente nos dois lados.

    
por 13.01.2015 / 15:50
0

Eu acredito que você está tentando pegar o título?

aqui temos uma maneira de pegar as coisas, livrando-se da primeira palavra e das últimas duas palavras, e exibindo o resto (espaços incluídos):

awk '{ $1=""; $(NF-1)="" ; $NF="" ; print $0}'

Ou melhor: livre-se do primeiro elemento, e descarte os últimos 2, e também os espaços extras (alterando um $ n ou NF, forçam um redesenho de $ 0 na maioria das implementações do awk):

awk '{ shift ; NF=(NF-2); print $0}'

exemplo

$   echo   ' 01      Title is   here!     Chapter 01' | awk '{ shift ; NF=(NF-2); print $0}'

 Title is here!

A vantagem do awk é que é fácil adicionar testes (é $ 1 um inteiro? é $ (NF-1) "Chapter"? etc)

    
por 13.01.2015 / 16:59
0

Você pode usar a opção -r para expressões regulares estendidas onde o número de caracteres pode ser especificado dentro de {} , então o seguinte irá imprimir todas as palavras cercadas por 6 espaços:

sed -r 's/.* {6}(\w*) {6}.*//'

No caso, se o title tiver espaços também, a melhor escolha seria

sed -r 's/.* {6}(.*) {6}.*//'
    
por 13.01.2015 / 14:55