Bash에서 캡처를 사용하여 변수로 출력할 때 $(...)
성가신 개행 문자가 추가됩니다. 그러나 내 출력은 개행 문자로 끝나는 경우도 있고 그렇지 않은 경우도 있습니다. 출력을 있는 그대로 캡처하고 싶습니다.
실제 문제에서는 문자열에 여러 줄이 포함될 수 있지만 마지막 줄은 개행 문자로 끝나거나 끝나지 않을 수 있으므로 이 속성은 유지되어야 합니다.
스타일은Stack Exchange에 대한 답변입니다., 내 최소 작업 예는 다음과 같습니다.
#!/bin/bash
newlinetest() {
if [ "$1" = 'with' ]; then
printf '%s\n' 'Text with newline'
else
printf '%s' 'Text without newline'
fi
}
s="$(newlinetest with ; printf '%s' 'x')"
s="${s%?}"
printf '%s%s%s\n' '(' "${s}" ')'
s="$(newlinetest without ; printf '%s' 'x')"
s="${s%?}"
printf '%s%s%s\n' '(' "${s}" ')'
해야 할 일을 수행하지만 IMHO 이것은 보기 흉한 해킹처럼 보입니다. 이 문제를 해결하는 다른 우아한 방법이 있습니까? 어쩌면 관련 mapfile
되거나 read
? 외부 도구가 필요하지 않은 솔루션은 매우 환영받을 것입니다.
답변1
실제로 명령 대체는 후행 줄 바꿈을 제거하지만 추가하지는 않습니다. 그러나 나중에 해당 변수를 인쇄하는 데 사용하면 echo
기본적으로 1이 추가됩니다.
후행 x
항목을 추가하는 것은 약간 해킹된 것처럼 보이지만 아마도 가장 쉬운 방법이며 모든 쉘에서 작동합니다. echo x
대체를 사용하여 더 짧게 만들 수 있습니다 printf '%s' 'x'
.
당신이 언급했으므로 read
Bash에서 다음과 같은 것을 사용할 수도 있습니다.
IFS= read -rd '' var < <(newlinetest with)
이것이 이것보다 더 예쁜지 결정하게 할게요:
var=$(newlinetest with; echo x)
var=${var%x}
둘 사이에는 잠재적인 성능 차이가 있지만. 첫 번째 프로세스 대체는 다음을 read
읽는 파이프를 생성합니다.한 번에 1바이트구분 기호 초과를 방지하기 위해(여기서는 중요하지 않지만 쉘은 이를 알지 못합니다.) 명령 대체는 더 큰 청크에서 읽혀지므로 큰 출력의 경우 더 빠를 수 있습니다.