bash 변수의 줄 바꿈


9

bash 변수에 여러 줄을 저장하려고하는데 작동하지 않는 것 같습니다.

예를 들어 /bin한 줄에 하나의 파일을 나열 하고에 저장하면 stdin으로 $LS전달 하면 항상 1을 반환합니다.$LSwc

$ ls -1 /bin | wc -l
134
$ LS=$(ls -1 /bin); wc -l <<< $LS
1

화면에 출력하려고하면 다양한 결과가 나타납니다. echo한 줄에 모든 줄을 printf인쇄하고 첫 번째 줄만 인쇄합니다.

#!/bin/bash
LS=$(ls -1 /bin)
echo $LS
printf $LS

bash 변수는 여러 줄을 포함 할 수 있습니까?

답변:


15

당신은 (당신이 따옴표 그것을 필요로 한다 인용 변수를 두 배로 대부분의 경우)를 :

echo "$LS"

그러나 echo 대신 printf를 사용하여 변수 내용을 인쇄 하지 마십시오 .

printf '%s\n' "$LS"

1
전반적인 대답을 더 잘 설명하기 위해 printf는 형식 문자열이 첫 번째 매개 변수가 될 것으로 예상하므로 예상했던 것을 보지 못했습니다. printf의 출력에서 ​​줄 바꿈을보고 싶다면 공백으로 분할 printf "%s\n" $LS하십시오.
Jeff Schaller

% LS는 $ LS, btw 여야합니다 (짧은 편집을 할 수 없었습니다)
Jeff Schaller

감사! 물론 wc다른 명령 들 과 도 작동 합니다 :wc -l <<< "$LS"
Wizard79

1
@ JeffSchaller : 아니요,이 경우 변수를 인용 부호로 묶지 말고 printf '%s\n' "$LS"개행을보고 싶을 때만 사용 하십시오. 잘못 입력 한 것입니다.
cuonglm

왜 echo를 사용하여 변수를 인쇄해서는 안됩니까?
123

9

개행은 변수에 있습니다. LS=$(ls -1)변수 LS를 출력으로 설정합니다 ls -1( ls출력이 터미널로 갈 때를 제외하고 와 동일한 출력을 생성합니다 ). 마지막 줄 바꿈.

문제는 값을 인쇄 할 때 줄 바꿈을 제거한다는 것입니다. 쉘 스크립트에서 $LS"변수의 값"을 의미하는 것이 아니라 "의 값을 LS취하여 LS이를 IFS단어로 나누고 각 단어를 글로브 패턴으로 해석"을 의미합니다. 의 값을 얻으려면 LS을 쓰거나 "$LS"더 일반적으로 $LS큰 따옴표 를 넣으 십시오.

echo "$LS"의 값을 출력 LS백 슬래시 문자를 해석하고,로 시작하는 몇 가지 값을 제외하고 어떤 조개를 제외하고 -.

printf "$LS"LS퍼센트 나 백 슬래시 문자를 포함하지 않고 (대부분의 구현에서)로 시작하지 않는 한 값을 인쇄합니다 -.

값을 LS정확하게 인쇄하려면을 사용하십시오 printf %s "$LS". 끝에 줄 바꿈을 원하면을 사용하십시오 printf '%s\n' "$LS".

참고 $(ls)일반적으로하지 않습니다, 현재 디렉토리에있는 파일의 목록입니다. 파일 이름을 충분히 길들인 경우에만 작동합니다. 파일 이름 목록 (점 파일 제외)을 가져 오려면 와일드 카드를 사용해야합니다 *. 결과는 문자열이 아닌 문자열 목록이므로 문자열 변수에 할당 할 수 없습니다. files=(*)쉘을 지원하는 쉘에서 배열 변수 를 사용할 수 있습니다 (ksh93, bash, zsh).

자세한 내용 은 쉘 스크립트가 공백 또는 기타 특수 문자에서 질식하는 이유는 무엇입니까?를 참조하십시오 .


printf "$ LS"는 또한 echo와 비슷한 문자 파싱에 굴복 할 것입니다
cnst

0

전술 한

printf '%s\n' "$LS"

유일한 해결책입니다.

나에게 다른 제안 된 솔루션을 모두 입증하자 echo하고 printf, 단순히 제대로 작동하지 않습니다 :

$ mkdir t
$ cd t
$ touch \\n
$ LS=$(ls -l)
$ echo "$LS"
total 0
-rw-r--r--  1 domain  domain  0 Nov  5 06:12

$ printf "$LS\n"
total 0
-rw-r--r--  1 domain  domain  0 Nov  5 06:12

$ printf '%s\n' "$LS"
total 0
-rw-r--r--  1 domain  domain  0 Nov  5 06:12 \n
$ ls -l
total 0
-rw-r--r--  1 domain  domain  0 Nov  5 06:12 \n
$ rm \\n
$ cd ..
$ rmdir t
$

(또한 V=$(printf 'line0:\\n\\n\nline1.\n') printf '%s\n' "$V"다양한 변형을 테스트 할 수 있습니다 .)

반면에 \n파일 이름하는 것은, 그 흔한, 저장하지 않을 수 있습니다 git diff변수로, 그리고 문자 발생의 확률이 \n크게 증가.


참고 kshzsh도 지원 print -r -- "$LS"하고 zsh또한이있다 echo -E - $LS. cshecho $LS:q$ LS가 비어 있으며 처음에 $ LS에 여러 값을 점점 csh를 상당히 까다로운 경우 그 출력하지 개행 문자를 수행하지만.을
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.