bash - 마치 원인 것처럼 시작점을 설정하여 배열을 재정렬합니다.

bash - 마치 원인 것처럼 시작점을 설정하여 배열을 재정렬합니다.

내 스크립트에서는 다음 설정을 사용합니다.

#!/bin/bash

array=(C G D A E B)

if [[ "$1" = "--setstart" ]] || [[ "$1" = "-s" ]]; then
    if [ -n "$2" ]; then

        array=($(sed "s/.*$2 /$2 /" <<< "${array[@]}"))

    else
        printf "\nno argument...!\n"
    fi
fi

for a in "${array[@]}"; do
    printf "%s " "$a"
done    
echo

--setstart옵션을 사용하면 배열 읽기를 시작할 위치를 선택할 수 있습니다(이 sed명령은 현재 이 문제를 해결하기 위해 제가 생각할 수 있는 유일한 방법입니다).

스크립트 자체는 prints: 옵션 없이 실행되며 C G D A E B 값을 설정하면 --setstart해당 지점에서 배열을 인쇄하므로 --setstart Dprint: does 입니다 D A E B.

array처음에 잘린 부분이 끝까지 들어가도록 이것을 루프로 인쇄하는 옵션을 어떻게 도입합니까? 설정이 D인쇄된다고 가정하면: D A E B C G?

답변1

Bash 하위 문자열(하위 배열) 확장 사용(예: ${parameter:offset:length})...

array=(A B C D E F)

start=$1
# handle negative offsets
[[ $start -lt 0 ]] && start=$((${#array[@]} + start))

# the star of the show, create array2 from two sub-arrays of array
array2=("${array[@]:$start}" "${array[@]:0:$start}")

echo "${array2[@]}" 

여기서는 설명을 위해 원본 배열을 새로 정렬된 배열에 넣습니다. (몇 가지 명백한 경계 검사 등을 생략했습니다.)

$ ./rotate.sh 3
D E F A B C

고쳐 쓰다:음수 오프셋을 처리하기 위해 위 스크립트를 수정했습니다.이카츄의 대답)...

$ ./rotate.sh -2
E F A B C D

업데이트 2:"A"부터 "F"까지의 문자 중 하나(질문의 예와 더 밀접하게 일치)를 허용하는 스크립트의 경우 다음 start=$1으로 바꾸세요.

# Convert [A-F] to ASCII code then normalize to [0-5]
LC_CTYPE=C start=$(( $(printf %d "'$1") - 65 ))

물론, 정렬된 문자 배열이 없다면 임의의 배열 요소를 처리하기 위해 다음과 같은 것이 더 필요할 것입니다.

idx=0
for elem in "${array[@]}"; do
    [[ $elem = $1 ]] && break
    ((idx++))
done
start=$idx

답변2

모듈러스를 사용합니다. 쿵/크쉬:

$ cat rotate.sh
#!/bin/bash
array=(A B C D E F)
n=${#array[@]}
start=${1-0}
i=0;
while (( i < n )) ; do
    printf "%s " "${array[(start + i) % n]}"
    (( i++ ))
done
echo

Zsh는 1에서 배열 인덱싱을 시작하므로 약간의 조정이 필요합니다. 첫 번째 명령줄 매개변수는 시작 위치를 설정하며 start음수일 수 있습니다.

$ ./rotate.sh 2
C D E F A B 

값별로 시작점을 찾으려면 수정이 간단해야 합니다.

관련 정보