Ubuntu 14.04.1 64ビットLTSのBashから「hsli」で始まり、「.h5」で終わるファイル名の数値部分を抽出したいと思います。私のls -l hsli*
結果は次のとおりです。
-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
それらはすでに昇順になっており、少し操作した後に次のコマンドを使用して最初のファイルのファイル名を取得できます。コマンドと出力は次のとおりです。
$ ls -l hsli* | head -1 | rev | cut -f 1 -d " " | rev
hsli0.03.h5
今私の目標はここから抽出することです0.03
。どうすればいいですか?正規表現に慣れておらず、ファイル名に2つの点があり、難しい状況のようです。
答え1
そうでない場合は、ls
とにかくリストをシェルグローブで埋めることになるので、次のようにブローカーを削除できます。
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!}"
)
引数なしで呼び出すと、ファイルがグローバル化され、hsli*
現在のディレクトリ結果の中央部分の最初の部分のみが印刷されます。それ以外の場合はエラーを返し、stderrに意味のあるエラーメッセージを出力します。*.string.h5
答え2
Bashを使用すると、このような変換を比較的簡単に適用できます。ストリッププレフィックスとサフィックス配列の要素に。
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
バージョン(この場合)はアルファベット順にソートされます。たとえば、数字の0.9
順序0.10
が必要で、十分な新しいGNU coreutilsバージョンがある場合を使用してbefore 。ファイル名にスペースやワイルドカードが含まれていない場合は、次のようにファイル名を並べ替えることができます。sort -V
0.9
0.10
versions=($(printf '%s\n' "$versions[@]" | sort -V))