이것이 내가 bash 쉘 스크립트에서 얻으려고 하는 것입니다:
for a in "1" "2 3" "4 5 6"
do
echo "a: $a"
done
a: 1
a: 2 3
a: 4 5 6
그러나 변수를 사용하면 따옴표가 다르게 처리됩니다.
echo "\"1\" \"2 3\" \"4 5 6\"" > a.txt
cat a.txt
"1" "2 3" "4 5 6"
read aline < a.txt
변수를 큰따옴표로 인용하면 다음과 같은 결과가 나타납니다.
for b in "$aline"
do
echo "b: $b"
done
b: "1" "2 3" "4 5 6"
따옴표가 없으면 다음과 같은 결과를 얻습니다.
for b in $aline
do
echo "b: $b"
done
b: "1"
b: "2
b: 3"
b: "4
b: 5
b: 6"
첫 번째 예와 같이 변수의 내용을 처리할 수 있는 방법이 있습니까?
답변1
견적 처리 외에 전체 패키지(변수/산술/명령 확장, 와일드카드 등)를 사용하는 데 동의하는 경우 다음을 수행할 수 있습니다.
echo '"a b" "x y"' >a.txt
eval "set -- $(<a.txt)"
for b do
printf 'b: %s\n' "$b"
done
b: a b
b: x y
(또는 또는 같은 다른 고급 쉘)이 아닌 일반 쉘에서 작동하도록 하려면 $(<a.txt)
로 변경하십시오. 무엇을 제어할 수 있는지 확신하는 경우에만 이 옵션을 사용하십시오. 그렇지 않으면 분할, 명령 확장 등을 통해 스크립트를 활용하는 것이 쉽지 않습니다.$(cat a.txt)
bash
zsh
ksh
a.txt
;
그러나 이러한 매개변수를 명령에 전달하려는 경우 xargs
확장 없이 따옴표만 처리하는 를 사용할 수 있습니다.
xargs <a.txt printf 'b: %s\n'
그러나 xargs
이는 쉘 함수가 아닌 외부 명령에만 작동하며 큰따옴표 안의 백슬래시는 작은따옴표 안의 백슬래시처럼 무시되며 여러 줄 문자열은 구문 분석할 수 없습니다.
후자의 제한이 문제가 되지 않으면 xargs
래퍼나 배열을 통해 인용 구문 분석기로 사용할 수 있습니다.
mapfile -t args < <(xargs <a.txt printf '%s\n')
for b in "${args[@]}"; do
printf 'b: %s\n' "$b"
done
답변2
bash
그렇지 않은 경우 ksh93
( ksh93
쉘이 bash
어쨌든 모방하려고 시도함) 내장 옵션을 사용하여 csv를 읽을 수 있습니다 -S
( read
그래서 csv 스타일 인용을 이해합니다).
IFS=" " read -rSA array < a.txt
printf 'a: %s\n' "${array[@]}"
이를 사용하면 변수의 내용을 코드인 것처럼 표시하는 매개변수 확장 플래그 (참조는 이해되지만 코드는 평가되지 않음 )와 매개변수 확장 플래그를 zsh
사용 하여 1레벨 참조를 제거할 수 있습니다.z
zsh
zsh
eval
Q
IFS= read -r line < a.txt
printf 'a: %s\n' "${(Q@)${(z)line}}"
( @
매개변수 확장 플래그는 동작을 연상시키는 빈 요소를 보존하기 위한 것입니다 ksh
. ${array[@]}
)
a.txt
여러 줄이 포함된 경우 zsh
명령을 및 루프로 바꿀 수 있습니다 read
. 인용된 문자열이 여러 줄에 걸쳐 있으면 각 호출이 여러 줄을 읽을 수 있습니다.content=$(<a.txt)
ksh93
read
while
read