IFS = $ '\ n'의 정확한 의미는 무엇입니까?


124

IFS환경 변수를 줄 바꿈 문자로 설정하는 다음 예의 경우 ...

IFS=$'\n'
  • 뭐라고합니까 달러 기호 의미 정확히 ?
  • 이 특정한 경우에는 무엇을합니까?
  • 이 특정 사용법에 대한 자세한 내용은 어디에서 읽을 수 있습니까 (Google은 검색에서 특수 문자를 허용하지 않으며 다른 방법으로 무엇을 찾아야할지 모르겠습니다)?

IFS환경 변수가 무엇인지, \n문자 (줄 바꿈)가 무엇인지 알고 있지만 다음 형식을 사용하지 않는 이유 IFS="\n"는 무엇입니까? (작동하지 않음)?

예를 들어 파일의 모든 줄을 반복하고 for 루프를 사용하려면 다음과 같이 할 수 있습니다.

for line in (< /path/to/file); do
    echo "Line: $line"
done

그러나를 IFS줄 바꿈 문자로 설정 하지 않으면 제대로 작동하지 않습니다 . 작동하려면 다음을 수행해야합니다.

OLDIFS=$IFS
IFS=$'\n'
for line in (< /path/to/file); do
    echo "Line: $line"
done
IFS=$OLDIFS

참고 : 똑같은 일을하기 위해 다른 방법이 필요하지 않습니다. 이미 많은 것을 알고 있습니다. 단지 그것에 대해 $'\n'궁금해하고 누군가 나에게 설명해 줄 수 있는지 궁금합니다.

답변:


161

일반적으로 bash문자열 리터럴에서 이스케이프 시퀀스를 해석하지 않습니다. 그래서 당신은 작성하는 경우 \n"\n"또는 '\n'LINEBREAK 아니다 즉, - 그것은 편지입니다 n(첫 번째 경우) 또는 문자 뒤에 백 슬래시 n(다른 두 가지의 경우).

$'somestring'이스케이프 시퀀스 가있는 문자열 리터럴구문입니다 . 그래서는 달리 '\n', $'\n'실제로 LINEBREAK이다.


2
정확히 그렇지 \n는 않습니다. (이스케이프 된) 문자 n입니다. 당신이 바로 점이다 '\n'"\n"반발 n으로 따른다.
Roman Cheplyaka 2010

15
참고 $'\n'bash는 특정 - 그것은 POSIX 쉘에서 작동하지 않습니다 ( /bin/sh). POSIX 호환 방식으로 동일한 효과를 얻으려면 IFS='을 입력 한 다음 Return 키를 눌러 실제 개행 문자를 입력 한 다음 닫는 문자를 입력하십시오'
Richard Hansen

23
IFS=$(echo -e '\n')POSIX 호환 방식으로해야합니다.
Vineet 2011 년

12
@Vineet-찬성 댓글에 이의를 제기하기 위해 잠시 멈췄습니다. 이 동안 이다 POSIX와 올바른, 그것은하지 작업을 수행 - bash는 명령 대체 운영자는 모든 후행 개행 문자를 제거합니다. 자세한 내용은 이것을 참조하십시오 .
디지털 외상

9
: @DigitalTrauma 나는 심지어 POSIX하지 생각 -e정의되지 않으며, \n없이 -eXSI의 확장으로 작품 : pubs.opengroup.org/onlinepubs/9699919799/utilities/... . printf '\n'바위)
치로 틸리郝海东冠状病六四事件法轮功

20

구조에 공식적인 이름 을 부여하기 위해 : 형식의 문자열을 ANSI C 인용 문자열$'...' 이라고 합니다 .

즉, [ANSI] C 문자열에서와 같이 백래시 이스케이프 시퀀스 가 인식되고 리터럴 등가로 확장됩니다 (지원되는 이스케이프 시퀀스의 전체 목록은 아래 참조).

이 확장 후에$'...' 문자열은 '...'문자열 과 동일한 방식으로 작동합니다. 즉, [추가] 쉘 확장에 종속되지 않는 리터럴로 처리됩니다.

예를 들어, $'\n'리터럴 개행 문자로 확장됩니다. 이는 일반 bash 문자열 리터럴 ( '...'또는 "...")이 할 수없는 일입니다. [1]

또 다른 흥미로운 기능이다 ANSI C-인용 문자열이 빠져 나갈 수 '로 (작은 따옴표)\' , 이는, '...'(일반 단일 인용 문자열) 할 수 없습니다를 :

echo $'Honey, I\'m home' # OK; this cannot be done with '...'

지원되는 이스케이프 시퀀스 목록 :

백 슬래시 이스케이프 시퀀스 (있는 경우)는 다음과 같이 디코딩됩니다.

\ a 경고 (종)

\ b 백 스페이스

\ e \ E 이스케이프 문자 (ANSI C 아님)

\ f 양식 피드

\ n 개행

\ r 캐리지 리턴

\ t 가로 탭

\ v 세로 탭

\ 백 슬래시

\ '작은 따옴표

\ "큰 따옴표

\ nnn 값이 8 진수 값 nnn (1 ~ 3 자리) 인 8 비트 문자

\ xHH 값이 16 진수 값 HH 인 8 비트 문자 (1 개 또는 2 개의 16 진수)

\ uHHHH 16 진수 값 HHHH (16 진수 1-4 자리) 인 유니 코드 (ISO / IEC 10646) 문자

\ UHHHHHHHH 16 진수 값 HHHHHHHH (16 진수 1-8 자리) 인 유니 코드 (ISO / IEC 10646) 문자

\ cx control-x 문자

확장 된 결과는 달러 기호가없는 것처럼 작은 따옴표로 표시됩니다.


[1] 그러나 '...'및 "..."문자열에 실제 줄 바꿈을 삽입 할 수 있습니다 . 즉, 여러 줄에 걸쳐있는 문자열을 정의 할 수 있습니다.


16

에서 http://www.linuxtopia.org/online_books/bash_guide_for_beginners/sect_03_03.html :

"$ 'STRING'"형식의 단어는 특별한 방식으로 처리됩니다. 이 단어는 ANSI-C 표준에 지정된대로 백 슬래시 이스케이프 문자가 대체 된 문자열로 확장됩니다. 백 슬래시 이스케이프 시퀀스는 Bash 문서에서 찾을 수 있습니다.

스크립트가 줄 바꿈을 적절한 ANSI-C 표준으로 이스케이프하도록 강요하고 있다고 생각합니다.


8

기본 IFS를 다시 복구합니다 OLDIFS=$IFS. 이 작업 은 필요하지 않습니다. 기본 IFS를 대체하지 않으려면 서브 쉘에서 새 IFS를 실행하십시오.

ar=(123 321); ( IFS=$'\n'; echo ${ar[*]} )

게다가 나는 당신이 이전 IFS를 완전히 회복한다고 정말로 믿지 않습니다. 같은 줄 바꿈을 피하기 위해 큰 따옴표를 사용해야합니다 OLDIFS="$IFS".


2
이것은 정말 유용한 기술입니다. 방금 더 깨끗한 쉘 조인 작업에 사용했습니다 args=$(IFS='&'; echo "$*"). Bourne 쉘 친화적 인 방식으로 복원 IFS하는 $' \t\n'것은 결코 의미가 없습니다.
jeberle 2014 년

Besides I don't really believe you recover the old IFS fully: 단어 분할이되어 있지 변수 할당의 RHS에서 수행 (그러나 인용 제거이다), 그래서 OLDIFS=$IFSOLDIFS="$IFS"같은 방식으로 작동합니다.
mklement0

3

ANSI C 인용 문자열이 핵심입니다. @ mklement0 덕분에.

od 명령을 사용하여 ANSI C 인용 문자열을 테스트 할 수 있습니다.

echo -n $'\n' | od -c
echo -n '\n' | od -c
echo -n $"\n" | od -c
echo -n "\n" | od -c

출력 :

0000000  \n  
0000001

0000000   \   n   
0000002

0000000   \   n   
0000002

0000000   \   n   
0000002

출력을 통해 의미를 명확하게 알 수 있습니다.


-7

변수에서 값을 검색하는 것과 같습니다.

VAR='test'
echo VAR
echo $VAR

따라서 달러 기호는 기본적으로 콘텐츠를 평가합니다.


6
이것은 변수와 관련이 없습니다. $'FOO'( $FOO이 질문이 아닌 것과 달리 )는 문자열 리터럴입니다. 실행 echo $'VAR'하면 문자열 VAR이 아니라 문자열을 인쇄하는 것을 볼 수 있습니다 test.
sepp2k
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.