bash: 읽기 명령은 IFS를 지원하지 않습니다.

bash: 읽기 명령은 IFS를 지원하지 않습니다.

이 명령에 대한 bash 매뉴얼 페이지에서 read:

표준 입력 또는 -u 옵션의 인수로 제공된 파일 설명자 fd에서 한 줄을 읽고, 위의 단어 분할에 설명된 대로 단어로 분할하고, 첫 번째 단어를 이름에 할당합니다.

이제 다음을 시도했습니다.

IFS=,
echo ' a b,c d'|read -n 4 x y
echo ".$x. .$y."

내 예상 결과는

. a b. .c d.

변경으로 인해 토큰화는 공백 대신 쉼표로 이루어져야 하지만 실제 출력은 다음과 같습니다.

.a. ..

이것은 나를 혼란스럽게 한다. 공백에서는 단어 분리가 여전히 수행되는 것처럼 보이지만 .a.적어도 공백이 아닌 y로 설정되어야 합니다 b.

read나는 매뉴얼 페이지에서 이 명령에 대한 설명을 잘못 이해했다는 느낌을 지울 수 없습니다 .

그런데 저는 bash 4.4.12를 사용하고 있습니다.

답변1

잘 작동합니다:

$ IFS=,; echo ' a b,c d' | { read x y; declare -p x y;}
declare -- x=" a b"
declare -- y="c d"

노트

  1. 명령문 은 파이프에 있으므로 read명령문은 서브셸에 있습니다. 변수 xsum 의 범위는 y이 서브셸로 제한됩니다. 위에서는 declare명령문이 동일한 하위 쉘에 있도록 중괄호를 추가했습니다 read. 이렇게 하면 명령문 출력에 읽은 x 및 y 값이 표시됩니다.

    중괄호를 제거하면 declare명령문은 더 이상 동일한 하위 쉘에 있지 않으며 및 x값은 y유지되지 않습니다. 관찰하다:

    $ x=hot; y=cold; IFS=,; echo ' a b,c d' | read -n 4 x y; declare -p x y
    declare -- x="hot"
    declare -- y="cold"
    
  2. 서브쉘 제한을 피하기 위해 here-string을 사용할 수 있습니다.

    $ IFS=,; read x y <<<' a b,c d'; declare -p x y
    declare -- x=" a b"
    declare -- y="c d"
    

    here-string을 사용하면 명령문이 기본 셸에 있고 및 read값이 손실되지 않습니다.xy

  3. -n 4제한 read은 4자입니다. 이것은 당신이 원하는 것이 아닐 수도 있습니다. 관찰하다:

    $ IFS=,; echo ' a b,c d' | { read -n 4 x y; declare -p x y;}
    declare -- x=" a b"
    declare -- y=""
    

    여기서는 x4개의 문자가 모두 사용되고(공백은 문자로 간주됨) 문자는 읽혀지지 않습니다 y.

  4. ~처럼페사, 또는 명령 실행을 위해 로컬로 쉘 변수를 할당할 수도 있습니다. IFS를 변경하면 후속 명령에서 원치 않는 부작용이 발생할 수 있으므로 이는 좋은 생각입니다. 그러므로:

    $ IFS=, read x y <<<' a b,c d'; declare -p x y
    declare -- x=" a b"
    declare -- y="c d"
    

    위 명령이 실행되면 IFS이전 값으로 돌아갑니다.

관련 정보