나는 다음을 시도하고 있지만 운이 없습니다.
SORT_BY='-k3,3r -k2,2 -k1,1r'
awk 'NR<4{print $0;next}{print $0 | sort '"${SORT_BY}"' -t"~"}'
다양한 인용, 인용 해제 등을 시도했지만 항상 awk에 문제가 있습니다.
awk: illegal statement
연장은 어떻게 하나요 >
답변1
awk는 쉘이 아닙니다. sort
C 프로그램에서 직접 UNIX 도구를 호출할 수 없는 것처럼 awk에서 직접 UNIX 도구를 호출 할 수 없습니다 .
이렇게 하면 원하는 작업이 작동하게 됩니다.
SORT_BY='-k3,3r -k2,2 -k1,1r'
awk 'NR<4{print; next} {print | "sort -t\"~\" '"${SORT_BY}"'"}'
그러나 이것이 좋은 생각인지는 불분명합니다.
정렬되지 않은 헤더 행 3개를 인쇄한 다음 나머지 데이터를 정렬하려는 것이 아마도 가장 좋은 방법일 것입니다. awks 출력 구분 기호를 설정하고 입력 구분 기호를 동일한 문자로 정렬하는 것 외에도 정렬에서 awk를 완전히 분리하고, 쉘을 생성하기 위해 awk가 필요하지 않으며, 입력을 두 번 열 필요가 없기 때문에 입력이 파이프에서 나오든 파일에서 나오든 작동합니다.
sep='~'
awk -v OFS="$sep" '{print (NR>3), NR, $0}' file |
sort -t "$sep" -k1,1n -k2,2n -k5,5r -k4,4 -k3,3r |
cut -d "$sep" -f3-
답변2
변수는 작은따옴표로 묶인 문자열 내에서 확장되지 않습니다. 이 문제를 해결할 수 있는 방법이 없습니다.
이 예에서는 데이터의 처음 세 행을 있는 그대로 출력하고 나머지는 정렬하려고 합니다. 간단하게 유지하기 위해 나는 이것을 할 것입니다
sort_opts=( -k3,3r -k2,2 -k1,1r )
{ head -n 3 file
awk 'NR > 3' file | sort "${sort_opts[@]}" -t '~' } >newfile
내부에서 정렬하고 싶고 공백을 첫 번째 문자로 사용하여 동일하게 유지된다고 awk
가정하는 경우:$IFS
sort_opts=( -k3,3r -k2,2 -k1,1r )
awk -v sort_opts="${sort_opts[*]}" '
BEGIN { sortcmd = sprintf("sort %s -t \"~\"", sort_opts) }
NR <= 3 { print; next } { print | sortcmd }' file >newfile
이는 awk
명령줄에서 사용할 정렬 옵션을 제공하며, 블록은 변수에서 문자열로 사용할 정렬 명령을 생성한 다음 마지막 블록에서 이를 사용합니다(4행에서 시작하여 트리거됨).-v
BEGIN
sortcmd
print
in 에서 파이프와 함께 사용될 때 awk
파이프의 오른쪽은 파이프될 셸 명령을 나타내는 문자열이어야 합니다. 귀하의 코드에서는 그렇지 않으므로 "불법 선언" 오류가 발생합니다.
가져와야 하는 값에 awk
백슬래시가 포함된 경우 대신 환경 변수를 사용할 수 있습니다(각 백슬래시가 두 배로 늘어나는 것을 방지하기 위해).
sort_opts=( -k3,3r -k2,2 -k1,1r )
SORT_OPTS="$sort_opts[*]" awk '
BEGIN { sortcmd = sprintf("sort %s -t \"~\"", ENVIRON["SORT_OPTS"]) }
NR <= 3 { print; next } { print | sortcmd }' file >newfile