bash 읽기가 추가 후행 IFS 문자를 제거하지 않는 이유는 무엇입니까?

bash 읽기가 추가 후행 IFS 문자를 제거하지 않는 이유는 무엇입니까?

이 명령은 다음과 같습니다.

read -d 'z' a < <(printf 'a\n\n\n'); printf "$a"

산출:

a

bash는 read예상되는 추가 후행 줄 바꿈을 제거했습니다.

그리고 null 문자 IFS로 변경 .

IFS= read -d 'z' a < <(printf 'a\n\n\n'); printf "$a"

다음과 같이 출력됩니다.

a 
(blank line)
(blank line)

readIFS개행 문자가 더 이상 포함되지 않기 때문에 추가 후행 개행 문자는 더 이상 제거되지 않습니다 .

하지만 이제 동일한 작업을 수행하지만 m대신 개행 문자를 사용하면 다음과 같습니다.

IFS=m read -d 'z' a < <(printf 'ammm'); printf "$a"

출력은 다음과 같습니다.

a

그러나 실제 출력은 다음과 같습니다.

ammm

read즉, 추가 후행 IFS문자(이 경우 m문자) 는 이제 제거되지 않습니다.

왜?

답변1

필드 분할은 특히 선행 및 후행 IFS 공백을 무시합니다. ~에서GNU Bash 매뉴얼, 3.5.7 토큰화:

설정 되지 IFS않거나 해당 값이 기본값인 경우 <space><tab><newline>이전 확장 결과의 시작과 끝 부분에 있는 , 및 의 시퀀스는 무시되고 <space>시작 <tab>이나 끝이 아닌 문자 시퀀스는 단어를 구분하는 데 사용됩니다. 기본값이 아닌 값을 사용하면 공백 문자가 IFS 값(IFS 공백 문자)에 있는 한 단어의 시작과 끝 부분에 있는 공백 문자 시퀀스, , 및 가 무시됩니다.<newline>IFSIFSspacetabnewline

이 예의는 공백이 아닌 문자에는 적용되지 않습니다. 다른 필드 분할 인스턴스를 사용하여 이를 확인할 수 있습니다.

bash-5.0$ printf "|%s|\n" $(printf '\n\na\nb\n\n')
|a|
|b|
bash-5.0$ IFS=' '; printf "|%s|\n" $(printf '  a b  ')
|a|
|b|
bash-5.0$ IFS=z; printf "|%s|\n" $(printf 'zzazbzz')
||
||
|a|
|b|
||

답변2

기본적으로 읽기에서는 선행/학습 공백과 개행 문자가 제거됩니다. IFS를 추가하면 기본값이 있으므로 읽기 시 해당 값이 제거되지 않습니다.

귀하의 예에서

IFS=m read -d 'z' a < <(printf 'ammm'); printf "$a"

값을 제공했으므로 IFS이제 2개의 필드/열이 있지만 읽을 변수는 하나만 제공했습니다. 즉, 두 번째 필드를 보유하기 위해 다른 변수를 제공한 경우입니다.

IFS=m read -d 'z' a b < <(printf 'ammm'); printf '%s %s' "$b" "$a"

mmm a

제가 자세한 내용을 잘 알지 못해서 누가 더 자세히 설명해주실 수 있겠지만, 이건 제가 이해한 것입니다.

관련 정보