한 줄로 구분된 항목을 숫자로 정렬하는 방법은 무엇입니까?

한 줄로 구분된 항목을 숫자로 정렬하는 방법은 무엇입니까?

임의의 문자로 구분된 숫자 행이 있습니다. 구분 기호를 유지하면서 각 줄의 항목을 숫자로 정렬하는 데 사용할 수 있는 UNIX 도구는 무엇입니까?

예는 다음과 같습니다:

  • 숫자 목록 입력: 10 50 23 42;정렬:10 23 42 50
  • IP 주소;입력: 10.1.200.42;정렬:1.10.42.200
  • CSV;입력: 1,100,330,42;정렬:1,42,100,330
  • 수직 막대로 구분됨: 입력: 400|500|404;400|404|500

구분 기호는 임의적이므로 원하는 단일 문자 구분 기호를 사용하여 자유롭게 답변을 제공(또는 확장)하세요.

답변1

그리고 gawk(암소 비슷한 일종의 영양 awk) 을 위한asort()기능:

gawk -v SEP='*' '{ i=0; split($0, arr, SEP); len=asort(arr);
    while ( ++i<=len ){ printf("%s%s", i>1?SEP:"", arr[i]) }; 
        print "" 
}' infile

*필드 구분 기호를 SEP='*'귀하의 것으로 바꾸십시오.구분 기호.



한 줄인 경우 다음 명령을 사용할 수도 있습니다(텍스트 처리에 쉘 루프를 사용하지 않는 것이 더 좋기 때문입니다.)

tr '.' '\n' <<<"$aline" | sort -n | paste -sd'.' -

바꾸다가리키다 .구분 기호로. 중복을 제거하기 위해 위 명령 에
추가되었습니다 .-usort

노트:
모든 종류의 숫자(정수, 부동 소수점, 공학용, 16진수 등)를 처리하기 위해 대신 -g, --general-numeric-sort옵션을 사용할 수 있습니다 .sort-n, --numeric-sort

$ aline='2e-18,6.01e-17,1.4,-4,0xB000,0xB001,23,-3.e+11'
$ tr ',' '\n' <<<"$aline" |sort -g | paste -sd',' -
-3.e+11,-4,2e-18,6.01e-17,1.4,23,0xB000,0xB001

변경이 필요 하지 않으며 awk계속 처리됩니다.

답변2

사용할 수 있는 perl확실한 버전이 있습니다 . 데이터를 분할하고, 정렬하고, 다시 결합합니다.

구분 기호는 두 번 나열되어야 합니다( 에 한 번 split, 에 한 번 join).

예를 들어,

perl -lpi -e '$_=join(",",sort {$a <=> $b} split(/,/))'

그래서

echo 1,100,330,42 | perl -lpi -e '$_=join(",",sort {$a <=> $b} split(/,/))'
1,42,100,330

split정규식 이므로 이 문자를 따옴표로 묶어야 할 수도 있습니다.

echo 10.1.200.42 | perl -lpi -e '$_=join(".",sort {$a <=> $b} split(/\./))'
1.10.42.200

-a및 옵션을 사용하면 -F분할을 제거할 수 있습니다. 이전과 같이 루프를 사용 -p하고 결과를 로 설정하면 $_자동으로 인쇄됩니다.

perl -F'/\./' -aple '$_=join(".", sort {$a <=> $b} @F)'

답변3

Python 및 유사한 아이디어 사용스티븐 해리스의 답변:

python3 -c 'import sys; c = sys.argv[1]; sys.stdout.writelines(map(lambda x: c.join(sorted(x.strip().split(c), key=int)) + "\n", sys.stdin))' <delmiter>

그래서 이렇게 :

$ cat foo
10.129.3.4
1.1.1.1
4.3.2.1
$ python3 -c 'import sys; c = sys.argv[1]; sys.stdout.writelines(map(lambda x: c.join(sorted(x.strip().split(c), key=int)) + "\n", sys.stdin))' . < foo
3.4.10.129
1.1.1.1
1.2.3.4

불행하게도 I/O를 수동으로 수행해야 하는 것은 Perl 버전보다 훨씬 덜 우아합니다.

답변4

쿵쿵 스크립트:

#!/usr/bin/env bash

join_by(){ local IFS="$1"; shift; echo "$*"; }

IFS="$1" read -r -a tokens_array <<< "$2"
IFS=$'\n' sorted=($(sort -n <<<"${tokens_array[*]}"))
join_by "$1" "${sorted[@]}"

예:

$ ./sort_delimited_string.sh "." "192.168.0.1"
0.1.168.192

기반으로

관련 정보