필수 코드:
echo "$var" | sort -t/ -k 1,1n -k2,2n -k3,3n
사례 시나리오: 조건에 따라 동적으로 생성되어 변수에 저장된 arr을 정렬하는 옵션입니다. 어떻게 통과시킬 수 있나요?
option='-k 1,1n -k2,2n'
echo "$var" | sort -t/ "$option"
또는
echo "$var" | sort -t/ "$(eval echo "$option")
그러나 아무것도 작동하지 않습니다. 길잃은 문자 오류가 발생합니다.
sort: stray character in field spec: invalid field specification ‘ 1,1n -k 2,2n -k 3,3n’
답변1
다음은 귀하의 질문과 명령줄 매개변수를 실제로 사용하기 전에 변수에 저장하려는 기타 상황에 구체적으로 적용되는 일반적인 대답입니다.
코드의 문제점은 "$option"
명령줄에서 코드를 사용할 때 sort
다음과 같다는 것입니다.하나의토론. 이 경우 간단히 따옴표를 제거하고 쉘이 $option
문자열을 공백, 탭 및 줄 바꿈으로 분할하도록 한 다음 sort
결과 목록 일치를 호출하기 전에 이러한 결과 단어에 대해 파일 이름 전달을 수행하여 이 문제를 해결할 수 있습니다. 이는 귀하의 상황에 적합하지만 문제를 해결하는 데 있어 덜 우아한 방법입니다.
$option
파일 이름 글로빙 패턴을 포함하지 않고 공백에서 문자열을 올바르게 분할하는 데 의존하기 때문에 덜 우아합니다 .
보다 일반적인 솔루션을 위해서는 옵션과 옵션 인수를 배열에 넣어야 합니다. 이렇게 하면 필요한 각 인수를 참조할 수 있습니다. 다음 코드에서는 배열을 지원하는 셸(예: )을 사용한다고 가정합니다 bash
.
options=( -k 1,1n -k 2,2n -k 3,3n )
sort -t '/' "${options[@]}" <<<"$var"
인용 확장을 사용하면 ${options[@]}
배열의 각 요소가 options
단일 필드로 확장됩니다. 즉, options
명령줄에서 모든 요소가 개별적으로 인수로 인용된 것처럼 셸이 배열을 확장합니다 sort
.
배열이 없는 쉘에서는 대신 위치 인수 목록을 사용하십시오.
set -- -k 1,1n -k 2,2n -k 3,3n
printf '%s\n' "$var" | sort -t '/' "$@"
잘린 첫 번째 코드와 마찬가지로 인용은 $@
위치 인수 목록의 모든 요소가 완전히 확장되도록 보장하기 때문에 필수적입니다. 여기에서도 쉘은 "$@"
필드 목록으로 확장되고 이러한 필드를 유틸리티에 대한 인수로 제공합니다 sort
.
어쨌든 echo
출력에 값을 사용하는 것은 피하고 싶습니다. 쉘의 구성과 변수의 내용을 기반으로 데이터를 수정하기 $var
때문입니다 .echo
또한보십시오:
답변2
명령 은 sort
별도의 인수 문자열(예: )로 옵션을 받아야 합니다 sort
-t/
-k
1,1n
-k2,2n
-k3,3n
.
예를 들어 큰따옴표 확장을 사용하면 "$option"
모든 옵션이 단일 문자열로 전달됩니다 sort
-t/
-k 1,1n -k2,2n -k3,3n
.
이를 방지하려면그냥 따옴표를 사용하지 마세요에 대한 $option
:
option='-k 1,1n -k2,2n'
echo "$var" | sort -t/ $option
정렬에 사용되는 옵션은 -k
동일한 매개변수 문자열( )의 일부로 또는 -k2,2n
옵션( ) 다음의 다음 매개변수 문자열로 필드 지정을 허용할 수 있습니다. 필드 사양이 옵션 지정자와 동일한 매개변수 문자열의 일부인 경우 공백도 허용할 수 있습니다.-k
-k
1,1n
echo works | sort -t/ "-k 1,1n" -k2,2n -k3,3n
works
그러나 필드 지정 후 동일한 매개변수 문자열에 단일 공백 문자가 있어도 허용되지 않습니다.
echo fails | sort -t/ "-k 1,1n " -k2,2n -k3,3n
sort: stray character in field spec: invalid field specification ‘ 1,1n ’