배열을 매개변수로 받아 정렬할 수 있는 함수를 만드는 방법을 알아내려고 합니다. 위치 변수를 통해 수행되는 것 같지만 확실하지 않습니다.
답변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
, 옵션을 사용하세요 .-r
sort
sort
함수를 구현하려면 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[@]}