숫자 정렬을 사용하여 문자를 무시하는 방법

숫자 정렬을 사용하여 문자를 무시하는 방법

특정 필드에서 숫자를 사용하여 정렬할 때 sort문자를 생성하거나 무시하는 방법은 무엇입니까? awk내 텍스트 파일에 다음 데이터가 있습니다.

name name space 2018
name2 name2 space (active 2020)
name1 name1 space (c. 2019)

명령에서 "(", ")", "c." 및 "active"를 무시하여 연도만 사용하여 데이터를 정렬할 수 있기를 원합니다.

나는 다음 출력을 찾고 있습니다 :

name  name    space   2018
name1 name1   space   (c. 2019)
name2 name2   space   (active 2020)

답변1

마지막 필드의 해당 부분을 추출하여 별도의 정렬 가능한 필드로 추가합니다. 이 필드를 정렬합니다. 원래 데이터가 남도록 임시로 추가된 필드를 제거하세요.

awk '{y = $NF; gsub("[^[:digit:]]", "", y); printf "%s\t%s\n", y, $0}' file |
    sort -k1,1n |
    cut -f2-

gsub공백으로 구분된 마지막 필드에서 숫자가 아닌 문자를 모두 제거하는 RE를 포함합니다 . 후행 파이프 문자 없이 명령 을 실행하면 awk입력 데이터에 어떤 작업이 수행되는지 확인할 수 있습니다. 그런 다음 추가 sort하고 무슨 일이 일어나는지 확인하십시오.

답변2

각 행에서 가장 오른쪽의 십진수 시퀀스를 정렬하려면 이를 추출하여 맨 앞으로 가져온 다음 정렬하고 제거하면 됩니다.

<file LC_ALL=C sed '
  h;                    # save pattern space (current line) onto hold space
  s/[^0123456789]*$//;  # remove non-digit characters from the end
  s/^.*[^0123456789]//; # remove everything up to the last non-digit
  G;                    # append \n and hold space to pattern space
  s/\n/:/;              # replace that \n with :' |
  sort -n |
  cut -d: -f2-

답변3

옵션 적용 -V(자연 정렬) 및 첫 번째 필드 기준 정렬

sort -Vk1,1 file

name name space 2018
name1 name1 space (c. 2019)
name2 name2 space (active 2020)

까다로운 상황의 경우:

sort -Vk1,1 -k5 file

의견을 듣고 다음을 추가하기로 결정했습니다.

awk 'BEGIN {PROCINFO["sorted_in"]="@val_num_asc"} {a=$0; gsub(/[^0-9]/, ""); D[a]=$0}; END {for(i in D)print i}' file

모든 숫자를 문자열 형식의 키가 있는 배열 값으로 전송하고 정렬 순서를 지정합니다. PROCINFO["sorted_in"]="@val_num_asc"

답변4

Raku(이전 Perl 6) 사용

이것은 보이는 것보다 더 어렵습니다. 나는 테스트 파일의 줄 수를 두 배로 늘리는 것부터 시작하여 이 문제를 해결하는 가장 좋은 방법을 생각했습니다. 한 가지 접근 방식은 공백으로 분할하는 것뿐만 아니라 대괄호 안의 공백으로도 분할할 수 있으므로 일부 행에는 4개의 열이 있고 다른 행에는 5개의 열이 있습니다.

아래 코드는 열(OP 용어로 "텍스트 필드")을 무시하고 4자리 "연도" 정규식을 정렬합니다. 이 코드는 각 행에 1년만 있는 한 작동합니다.

raku -e 'my $a = lines(); my @b = $a.comb(/ \d**4 /).pairs; my $c = @b.sort(*.values)>>.keys.flat; $a[$c.flat]>>.put;' sort_year.txt
name name space 2018
name0 name space 2018
name1 name1 space (c. 2019)
name4 name1 space (c. 2019)
name2 name2 space (active 2020)
name3 name2 space (active 2020)

위의 코드는 4비트 정규식 패턴( )을 조합하여 ( 에서 ) 파생된 @b인덱스( )를 정렬한 다음 인덱스 "키"( )를 기준으로 행( )을 재정렬합니다 .$c@b$a$c

집에서 시도해 보고 싶은 사람을 위한 입력 파일은 다음과 같습니다.

~$ cat sort_year.txt

name name space 2018
name2 name2 space (active 2020)
name1 name1 space (c. 2019)
name0 name space 2018
name3 name2 space (active 2020)
name4 name1 space (c. 2019)

https://raku.org/

관련 정보