Extraindo números com um ponto decimal da saída ls no Bash

1

Eu gostaria de extrair a parte numérica dos nomes de arquivos que começam com "hsli" e terminam com ".h5" no Bash no Ubuntu 14.04.1 LTS de 64 bits. Minha saída ls -l hsli* é a seguinte:

-rwxrwxrwx 1 ongun ongun 31392 Feb 26 13:04 hsli0.03.h5
-rwxrwxrwx 1 ongun ongun 31392 Feb 26 13:44 hsli0.042.h5
-rwxrwxrwx 1 ongun ongun 31392 Feb 26 14:24 hsli0.054.h5
-rwxrwxrwx 1 ongun ongun 31392 Feb 26 15:03 hsli0.066.h5
-rwxrwxrwx 1 ongun ongun 31392 Feb 26 15:42 hsli0.078.h5
-rwxrwxrwx 1 ongun ongun 31392 Feb 26 16:22 hsli0.09.h5
-rwxrwxrwx 1 ongun ongun 31392 Feb 26 17:02 hsli0.102.h5
-rwxrwxrwx 1 ongun ongun 31392 Feb 26 17:36 hsli0.114.h5
-rwxrwxrwx 1 ongun ongun 31392 Feb 26 17:58 hsli0.126.h5
-rwxrwxrwx 1 ongun ongun 31392 Feb 26 18:20 hsli0.138.h5
-rwxrwxrwx 1 ongun ongun 31392 Feb 26 18:42 hsli0.15.h5

Eles já estão em ordem crescente e depois de um pouco de manipulação, eu posso obter o nome do arquivo para o primeiro arquivo com o seguinte comando. O comando e a saída seguem abaixo:

$ ls -l hsli* | head -1 | rev | cut -f 1 -d " " | rev 
hsli0.03.h5

Agora, meu objetivo é extrair 0.03 daqui, como posso fazer isso? Eu não estou familiarizado com expressões regulares e isso parece um caso difícil, pois há dois pontos no nome do arquivo.

    
por Vesnog 26.02.2015 / 20:50

2 respostas

2

Sem ls , já que você está apenas preenchendo sua lista com shell globs, você pode cortar o intermediário como:

glob_hsli()(IFS=.;set +f
    set -f -- '' hsli*.*.h5
    for h5 do case ${h5#*.}  in
        (*[!0-9]*.*|.*|'') : ;;
        (*) set $h5 "${1:-0}";
        shift $((3>>($2>$4)));;
    esac;done
    printf "0.%d\n" "${1:?No Match Found!}"
)

Chame-o sem argumentos e ele irá glob seus arquivos hsli* e somente imprima a primeira parte *.string.h5 do meio nos resultados para o diretório atual, ou ele retornará com erro e uma mensagem de erro significativa será impressa para stderr se não pode fazê-lo.

    
por 26.02.2015 / 21:24
1

O Bash torna relativamente fácil aplicar uma transformação como removendo prefixos e sufixos para elementos de um array.

shopt -s nullglob                  # if there are no matches, produce an empty list
versions=(hsli*.h5)                # list matches
versions=("${versions[@]#hsli}")   # strip prefix
versions=("${versions[@]%.h5}")    # strip suffix
printf '%s\n' "${versions[@]}"     # print one version per line
for v in "${versions[@]}"; do      # execute a command on each version
  somecommand "$v"
done

Observe que as versões (se é isso que elas são) são classificadas em ordem lexicográfica, portanto, por exemplo, 0.9 vem depois de 0.10 . Se você quiser uma ordem numérica e tiver versões recentes de GNU coreutils suficientes, use sort -V para classificar 0.9 antes de 0.10 . Dado que os nomes dos seus arquivos não contêm espaços em branco ou caracteres globbing, você pode classificá-los com

versions=($(printf '%s\n' "$versions[@]" | sort -V))
    
por 27.02.2015 / 00:14