이 명령은 다음과 같습니다.
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)
read
IFS
개행 문자가 더 이상 포함되지 않기 때문에 추가 후행 개행 문자는 더 이상 제거되지 않습니다 .
하지만 이제 동일한 작업을 수행하지만 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>
IFS
IFS
space
tab
newline
이 예의는 공백이 아닌 문자에는 적용되지 않습니다. 다른 필드 분할 인스턴스를 사용하여 이를 확인할 수 있습니다.
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
제가 자세한 내용을 잘 알지 못해서 누가 더 자세히 설명해주실 수 있겠지만, 이건 제가 이해한 것입니다.