Como obter esta substring no script bash?

4

Estou trabalhando no script bash.

Eu tenho um var com uma string nele. Esta é a string:

tSA_15_20161014_11-12-50

Basicamente, o formato é tSA_(id)_(year)(month)(day)_(hour)-(min)-(seg)

Informações importantes:

  • O ID pode ser um número de 0 a 999
  • O formato do ano é yyyy
  • Formato do mês mm
  • Formato do dia dd
  • Formato de hora 24h

A string que eu quero pegar é algo como:

20161014111250

Qual é yyyymmddHHMMSS

Inglês não é minha língua nativa, então se há algo que você não pode entender, por favor me diga. Obrigado.

    
por gloaiza 14.10.2016 / 19:23

6 respostas

8
echo "tSA_15_20161014_11-12-50" | awk -F'_' '{print $3$4}' | tr -d -

echo a var na qual a string é armazenada

Explicação:

awk -F'_' '{print $3$4}' altera o separador de campo para _ e imprime a terceira e a quarta coluna

A saída é 2016101411-12-50

tr -d - exclui - do resultado anterior.

    
por 14.10.2016 / 19:28
10

Com a expansão do parâmetro bash :

$ var='tSA_15_20161014_11-12-50'

$ var="${var#*_}"  ## Extracts the portion after first '_' i.e. 
                      new 'var' will be '15_20161014_11-12-50'

$ var="${var#*_}"  ## again gets the portion after first '_', so in this case
                      after operation 'var' will contain '20161014_11-12-50'

$ echo "${var//[-_]/}"  ## Replaces all '-' and '_' from '$var' with null
20161014111250
    
por 14.10.2016 / 19:34
3

Dado

var='tSA_15_20161014_11-12-50'

então

IFS=_ read -a arr <<< "${var//-/}"
printf '%s%s\n' "${arr[2]}" "${arr[3]}"
20161014111250
    
por 14.10.2016 / 19:36
2

Para completar, algumas sed versões:

echo "tSA_15_20161014_11-12-50" \
| sed -rn 's/^tSA_[0-9]{1,3}_([0-9]{8})_([0-9]{2})-([0-9]{2})-([0-9]{2})$//p'

echo "tSA_15_20161014_11-12-50" \
| sed -r 's/^tSA_[0-9]{1,3}_([0-9]{8})_([0-9]{2})-([0-9]{2})-([0-9]{2})$//'

echo "tSA_15_20161014_11-12-50" \
| sed -r 's/([^_]*_){2}(.*)_(.*)//;s/-//g'

echo "tSA_15_20161014_11-12-50" \
| sed -r 's/(.*_){3}//;s/[-_]//g'

Uma coisa que acho importante é a verificação de erros. Caso a variável não esteja de acordo exatamente com o formato que você forneceu, a primeira versão produzirá uma string vazia, e a segunda versão produzirá a string de entrada, inalterada. A terceira versão é uma versão de sed de @ debal awk resposta e a quarta é tão concisa quanto eu posso obtê-la facilmente, ambas sem o comportamento especificado na entrada incorreta.

    
por 15.10.2016 / 13:37
2

Outra abordagem awk . Como awk pode ter vários caracteres como separadores de campo, isso pode ser feito em uma única etapa:

$ awk -F'[-_]' '{print $3$4$5$6}' <<<"$var"
20161014111250

Como alternativa, em Perl:

$ perl -pe 's/.+?_.+?_//; s/[-_]//g' <<<"$var"
20161014111250

Ou

$ perl -F_ -ane 's/-//g for @F; print @F[2..$#F]' <<<"$var"
20161014111250

Estou usando aqui strings , mas se o seu shell não t suportá-los apenas echo $var | command para cada comando acima.

    
por 15.10.2016 / 12:48
0

Solução Python, usando re.split() com vários tokens. A string de entrada é fornecida como argumento de linha de comando

$ python -c 'import sys,re;print("".join(re.split("[-_]",sys.argv[1])[2:]))' "tSA_15_20161014_11-12-50"
20161014111250

Abordagem semelhante com rubi:

$ ruby -ne 'puts $_.split(/[-_]/)[2..-1].join("")' <<<  "tSA_15_20161014_11-12-50"                                                   
20161014111250
    
por 15.10.2016 / 20:25