Bash에서 배열을 정렬할 수 있는 함수를 만드는 방법은 무엇입니까?

Bash에서 배열을 정렬할 수 있는 함수를 만드는 방법은 무엇입니까?

배열을 매개변수로 받아 정렬할 수 있는 함수를 만드는 방법을 알아내려고 합니다. 위치 변수를 통해 수행되는 것 같지만 확실하지 않습니다.

답변1

세게 때리다

bash아직은 내장된 지원이 없는 것 같아요 . 옵션은 정렬 알고리즘을 수동으로 구현하거나 sort정렬 알고리즘을 호출하는 것입니다.

배열 요소에 0을 제외한 모든 바이트 값이 포함될 수 있다고 생각하는 경우 bash이를 안정적으로 수행하려면 NUL로 구분된 요소 목록을 전달하고 옵션 -z( sort비표준이지만 GNU 정렬 또는 FreeBSD 정렬에서 사용 가능)을 사용해야 합니다.

bash-4.4(2016년 9월 출시)는 구분 기호를 지정하는 -d옵션을 내장에 도입하여 작업을 더욱 쉽게 만듭니다.readarray

배열을 a배열로 정렬합니다 b.

readarray -td '' b < <(printf '%s\0' "${a[@]}" | sort -z)

배열은 안정적으로 정렬됩니다. 숫자순 또는 역순(또는 지원되는 정렬 조건 ) 으로 정렬하려면 -n, 옵션을 사용하세요 .-rsortsort

함수를 구현하려면 sortarray(인수로 전달된 모든 배열을 이름별로 정렬):

sortarray() for array do
  eval '((${#'"$array"'[@]} <= 1))' || readarray -td '' "$array" < <(
    eval "printf '%s\0' \"\${$array[@]}\" | sort -z")
done

이전 버전의 경우 루프 내에서 동일한 작업을 수행 bash할 수 있습니다 .read -d

b=()
while IFS= read -rd '' item; do b+=("$item"); done < <(
  printf '%s\0' "${a[@]}" | sort -z)

기능 의 경우 sortarray:

sortarray() for array do eval '
  tmp=()
  while IFS= read -rd "" item; do tmp+=("$item"); done < <(
    printf "%s\0" "${'"$array"'[@]}" | sort -z)
  '"$array"'=("${tmp[@]}")'
done

다루기 힘든

Zsh에는 배열 정렬 기능이 내장되어 있습니다.

o매개변수 확장 플래그를 사용하여 어휘적으로( O역순으로) 정렬 할 수 있습니다 . n숫자순으로 정렬하기 위해 플래그를 추가할 수 있습니다 .

$ a=('' 12 2 d é f $'a\nb')
$ printf '<%s>\n' "${(@o)a}"
<>
<12>
<2>
<a
b>
<d>
<é>
<f>
$ printf '<%s>\n' "${(@no)a}"
<>
<2>
<12>
<a
b>
<d>
<é>
<f>

아직 대소문자 구분 정렬 기능이 없는 로케일에서는 i이에 대한 플래그를 추가할 수도 있습니다.

배열에 할당:

b=("${(@o)a}")

따라서 sortarray함수는 다음과 같습니다.

sortarray() for array do eval "$array=(\"\${(@o)$array}\")"; done

AT&T ksh(ksh88 또는 ksh93, 둘 다 일부 시스템에서는 sh로 찾을 수 있음)

set -s -- "${a[@]}"
b=("$@")

set -s매개변수 목록을 정렬하여 위치 매개변수에 저장합니다. 순서는 어휘적입니다.

기능은 sortarray다음과 같습니다.

sortarray() for array do
  eval 'set -s -- "${'"$array"'[@]}"; '"$array"'=("$@")'
done

답변2

간단한 정렬을 위해 다음을 사용하세요 sort.tr

arr=($(for i in {0..9}; do echo $((RANDOM%100)); done))
echo ${arr[*]}| tr " " "\n" | sort -n | tr "\n" " "

새로운 배열로:

arr2=($(echo ${arr[*]}| tr " " "\n" | sort -n))

tr/ 의 도움 없이 sort, 예를 들어 버블 정렬:

#!/bin/bash    
sort () {
    for ((i=0; i <= $((${#arr[@]} - 2)); ++i))
    do
        for ((j=((i + 1)); j <= ((${#arr[@]} - 1)); ++j))
        do
            if [[ ${arr[i]} -gt ${arr[j]} ]]
            then
                # echo $i $j ${arr[i]} ${arr[j]}
                tmp=${arr[i]}
                arr[i]=${arr[j]}
                arr[j]=$tmp         
            fi
        done
    done
}
# arr=(6 5 68 43 82 60 45 19 78 95)
arr=($(for i in {0..9}; do echo $((RANDOM%100)); done))
echo ${arr[@]}
sort ${arr[@]}
echo ${arr[@]}

20개 숫자의 경우 버블 정렬로 충분할 수 있습니다.

답변3

sortnums(){
    local OLDPWD IFS=' /'
    cd -- "$(mktemp -d)" || return
    touch -- $*;  ls -A
    cd - >/dev/null &&
    rm -rf -- "$OLDPWD"
}

다음은 약간 더 복잡하고 느린 버전이지만 중복 항목을 압축하지 않고 정렬을 수행합니다.(적절한 크기)숫자순으로 소수 - 단(공간 분할)다른 문자열은 여전히 ​​문자열 길이를 먼저 고려하여 정렬됩니다. 일반 문자열을 처리하려면 거의 확실히 g=[0-9]glob을 다르게 설정하고 싶을 것입니다 .

나는 진실을 말할 것이다 - 나는 말할 것이다(아마도)목록 정렬을 고려해보세요.성격또는숫자이렇지만 적어도 문단에 맞지 않는 이름으로 파일을 만들 생각은 하지 않을 것입니다. 그래서 공간적으로 나누어집니다. 대부분의 경우 이것이 옳은 일입니다. 그러나 /이를 null처럼 처리해야 한다는 건전한 요구 사항으로 인해 방해를 받기도 합니다. 그러나 어쨌든 그것은 단지 재미를 위한 것입니다.

fs_sort(){
        local OLDPWD IFS=' /' opt="$-" g
        cd -- "$(mktemp -d)" || return
        set     -C                         ### noClobber for testable >
        for     g in    $*                 ### disallow any / reference
        do      until   command >" $g"     ### who needs dot glob?
                do      g=" $g"            ### '   1' lex== ' 1'
        done;   done    2>&1               ### -C is bitchy
                g=[0-9]                    ### now glob the array
        while   set -f *\ $g   &&          ### set it  &&
                <"$1" g+=? arr+=( $* )     ### <chk && (clean) it
        do      set +f;    done 2>&1       ### clear it
        set +fC "-${opts:--}"              ### put stuff where we found it
        cd - && rm  -rf -- "$OLDPWD"       ### don't leave our trash out
}       >/dev/null                         ### cd - is chatty

여기에 교훈이 있다면 아마도 먼저 bash 배열이 얼마나 더러운지 이해해야 한다는 것일 것입니다. 데이터가 방금 저장되었다면문서sort우리는 애초에 아무런 문제가 없을 것입니다. 로그인 쉘이 작은 부분만 크롤링한다면 필요할 때 중요한 쉘 상태를 유지하는 것이 훨씬 쉬울 것입니다.임시 파일 시스템시작 시 ~/.sh디렉터리를 여기에 복사한 다음 종료 이후 고정된 것으로 표시된 모든 파일을 다시 복사합니다.모두당신의 주이름간단히 정렬되며 set *다른 파일과 마찬가지로 호출하려는 유틸리티에서 해당 내용에 액세스할 수 있습니다.

답변4

#! /bin/bash

array=('2' '7' '5' '9' '0')
sort=0
echo ${array[@]}
len=${#array[@]}
echo $len


for ((i=0; i<$len; i++))
do
    for((j=i+1; j<$len; j++))
    do
        if [ ${array[i]} -le ${array[j]} ]
        then
            continue
        else
            sort=${array[i]}
            array[i]=${array[j]}
            array[j]=$sort
        fi
    done
done
echo ${array[@]}

관련 정보