Como obter a string após o primeiro numérico?

0

Eu tenho uma estrutura de strings como essa bob-type-8.2-mp2-2017-93-43-11-65-48.spr form onde eu preciso extrair 8.2-mp2-2017-93-43-11-65-48 .

Isso significa que a string de saída deve conter todos os caracteres depois de encontrar o primeiro valor numérico e, em seguida, remover o .spr disso.

Como posso fazer isso?

    
por subrat prusty 03.10.2017 / 14:58

7 respostas

1

Tente isto :

echo "bob-type-8.2-mp2-2017-93-43-11-65-48.spr" | sed 's/^[^0-9]*//;s/\.[^.]*$//'

A saída será:

8.2-mp2-2017-93-43-11-65-48

Explicação :

Sed usa o padrão ' s/pattern/replace_pattern/' para localizar pattern e substituí-lo por replace_pattern

Assim, o padrão 's/^[^0-9]*//' obtém todos os símbolos do início da linha e antes da ocorrência dos primeiros dígitos e os substitui por nada ( replace_pattern estão vazios).

O próximo passo - excluir extention. Podemos fazer isso com o mesmo padrão de sed 's///' .

s/\.[^.]*$// - encontre todos os símbolos que não são . no final $ da linha e substitua-os por nada.

; - padrões de devid.

Para entender melhor, você pode usar este comando:

echo "bob-type-8.2-mp2-2017-93-43-11-65-48.spr" | sed -e 's/^[^0-9]*//' -e 's/\.[^.]*$//'
    
por 03.10.2017 / 15:08
1

No Bash, com extglob :

$ shopt -s extglob
$ var=bob-type-8.2-mp2-2017-93-43-11-65-48.spr
$ res=${var##*([^0-9])}
$ res=${res%.spr}
$ echo "$res"
8.2-mp2-2017-93-43-11-65-48

*([^0-9]) corresponde a qualquer sequência de não dígitos, ${var##pattern} remove o padrão de correspondência mais longo do início da sequência, ${var%pattern} remove o padrão de correspondência (mais curto) do final.

    
por 03.10.2017 / 15:25
1

outra abordagem com sed .

sed 's/^[^[[:digit:]]*\(.*\)\.spr$//' <<<"bob-type-8.2-mp2-2017-93-43-11-65-48.spr"
  • ^[^[[:digit:]]* corresponde a tudo, desde o começo da string até o primeiro dígito ser visto; O mesmo que ^[^0-9]*

  • \(.*\) corresponde a tudo depois de correspondências acima e parênteses \(...\) são usados para capturar uma correspondência de grupo com como seu back -reference .

  • \.spr$ corresponde a um ponto literal seguido por spr no final da string de entrada.

  • imprime apenas correspondência de grupo capturada.

por 03.10.2017 / 15:21
1

Tantas sed de respostas! Que tal uma solução bash pura usando =~ padrão de correspondência e a matriz de referência não tão comum BASH_REMATCH ?

# put your string in variable named 'input'
patt='^[^0-9]*(.*)\..*' && [[ $input =~ $patt ]] && echo "${BASH_REMATCH[1]}"

Apenas para se destacar da multidão. ;)

    
por 03.10.2017 / 15:36
1

POSIXly:

string=bob-type-8.2-mp2-2017-93-43-11-65-48.spr
newstring=${string#"${string%%[0-9]*}"}
newstring=${newstring%.*}
  • ${string#pattern} : remova do início de $string o que corresponde a pattern , que neste caso é:
  • ${string%%[0-9]*} $string despojado de sua parte mais longa que corresponde ao padrão [0-9]* . Então essa é a parte até o primeiro dígito.
  • ${newstring%.*} : $string despojado de sua parte posterior menor que corresponde ao padrão .* . Então, remove a extensão.

com zsh :

newstring=${(M)${string:r}%%[0-9]*}
  • ${string:r} : expande para o nome raiz (removeu a extensão) como em csh
  • ${(M)var%%pattern} , retorna o que é M atched pelo operador %% (que sem (M) removeria a parte mais longa no final que corresponderia ao padrão como nos shells POSIX).
por 03.10.2017 / 15:43
1

Que tal isso?

echo bob-type-8.2-mp2-2017-93-43-11-65-48.spr | sed -r 's/^[^0-9]*(.*)\..*$//'

Isso leva tudo, desde o primeiro valor numérico encontrado após o início da string até o final da string, menos o último ponto e o que segue.

  • ^[^0-9]* ignora todos os não numéricos: NÃO zero a nove ( [^0-9] ), 0 a N vezes ( * ), desde o início da linha ( ^ ).
  • \..*$ corresponde a qualquer caractere ( . ), 0 a N vezes ( * ), antes do final da linha ( $ ) e precedido por um ponto ( \. ). No nosso caso, isso é .spr , mas pode ser aplicado a qualquer outra extensão de arquivo "dot + N-characters": .s , .yaythatsacoolextension , etc, também funcionam.
  • (.*) , referido como depois, mantém (este é o propósito dos parênteses, não poderíamos nos referir a ele mais tarde) o que está no meio: qualquer caractere ( . ), 0 a N vezes (% código%). Isso nos dá * .

Portanto, se você precisar listar em um arquivo os nomes normalizados de todos os 8.2-mp2-2017-93-43-11-65-48 contidos no diretório atual, por exemplo, você pode fazer algo assim:

for i in *.spr
do
    echo $i | sed -r 's/^[^0-9]*(.*)\..*$//' >> mylist.lst
done

E amanhã, se você precisar fazer isso com .spr arquivos, basta transformar o .blop acima em *.spr .

    
por 03.10.2017 / 15:11
0

Sed é uma das abordagens possíveis

echo bob-type-8.2-mp2-2017-93-43-11-65-48.spr | sed 's/^[^0-9]*//;s/....$//'
8.2-mp2-2017-93-43-11-65-48

regexps mean

  1. substitua todos os símbolos não numéricos do começo ao nada até o primeiro numérico
  2. substitua os últimos 4 caracteres por nada
por 03.10.2017 / 15:08