
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))