bash: 읽기: "\n"(개행) 문자를 캡처하는 방법은 무엇입니까?

bash: 읽기: "\n"(개행) 문자를 캡처하는 방법은 무엇입니까?

개행 문자를 read캡처 하거나 끊는 데 사용할 수 있는 것이 있나요?\n \012

테스트 기능을 정의합니다.

f() { read -rd '' -n1 -p "Enter a character: " char &&
      printf "\nYou entered: %q\n" "$char"; }

이 기능을 실행하려면 다음을 누르세요 Enter.

$ f;
Enter a character: 

You entered: ''

음. 이는 빈 문자열입니다.

예상되는 출력을 얻으려면 어떻게 해야 합니까?

$ f;
Enter a character:

You entered: $'\012'
$ 

^D또는 \004.​

할 수 없다면 read해결책은 무엇입니까?

답변1

1개의 문자를 읽으려면 -N항상 1개의 문자를 읽고 $IFS처리를 수행하지 않는 대신 사용하십시오.

read -rN1 var

read -rn1최대 한 문자까지 레코드를 읽고 계속 처리합니다 $IFS(새 줄이 기본값이므로 $IFSNUL로 구분된 레코드를 읽어도 빈 결과가 나오는 이유를 설명합니다). 이를 사용하여 읽는 레코드의 길이를 제한할 수 있습니다.

귀하의 경우 NUL로 구분된 레코드( 사용 -d '')를 사용하면 변수에 NUL 문자를 저장할 수 없는 것과 동일하게 작동하므로 IFS= read -d '' -rn1 var비어 있는 상태로 유지되고 0이 아닌 종료 상태를 반환합니다.bashprintf '\0' | read -rN1 var$var

NUL을 포함한 임의의 문자를 읽으려면 zsh다음 구문을 대신 사용하여 셸을 사용할 수 있습니다.

read -k1 'var?Enter a character: '

(필요없습니다 -r. IFS=하지만 꼭 read -k읽어 주세요.터미널에서( k열쇠; zsh 옵션은 -kbash 또는 심지어 ksh93보다 -N수십 년 더 오래 되었습니다. 표준 입력에서 읽으려면 read -u0 -k1)을 사용하십시오.

예( Ctrl+Space여기서 NUL 문자를 입력하세요):

$ read -k1 'var?Enter a character: '
Enter a character: ^@
$ printf '%q\n' $var
$'\0'

읽을 수 있으니 참고하세요특징, read여러 바이트를 읽어야 할 수도 있습니다. 입력이 멀티바이트 문자의 첫 번째 바이트로 시작하면 적어도 1바이트를 더 읽게 됩니다. 따라서 $var입력에 유효한 시퀀스를 형성하지 않는 바이트 시퀀스가 ​​포함되어 있으면 쉘이 고려하는 내용이 포함될 수 있습니다. 1자보다 길어야 합니다.

예를 들어 UTF-8 로케일에서는 다음과 같습니다.

$ printf '\xfc\x80\x80\x80\x80XYZ' | bash -c 'read -rN1 a; printf "<%q>\n" "$a" "${#a}"; wc -c'
<$'\374\200\200\200\200X'>
<6>
2
$ printf '\xfc\x80\x80\x80\x80XYZ' | zsh -c 'read -u0 -k1 a; printf "<%q>\n" $a $#a; wc -c'
<$'\374'$'\200'$'\200'$'\200'$'\200'X>
<6>
2

UTF-8에서 0xFC는 6바이트 긴 문자의 첫 번째 바이트이고, 나머지 5바이트는 비트 8이 설정되고 비트 7은 설정되지 않았음을 의미하지만 우리는 4만 제공했습니다. 문자의 끝을 찾기 위해 read추가 정보를 계속 읽으면 유효한 문자를 형성하지 않는 5바이트가 되고 각 바이트는 결국 하나의 문자로 계산됩니다.X$var

답변2

bash내장 기능은 read다음을 수행할 수 있습니다.

read -rd $'\0' -p ... -n 1
printf '\nYou typed ASCII %02x\n' "'$REPLY"

(이 코드는 멀티바이트 문자에서는 작동하지 않습니다.)

나는 당신처럼 내가 읽은 내용을 변수에 넣지 않았다는 점에 유의하십시오 char. 이는 IFS 에서 문자를 제거하기 때문입니다 char. 표준 IFS를 사용하면 공백, 탭 및 줄 바꿈을 구별할 수 없습니다.

관련 정보