bash 스크립팅에서 IFS = $ '\ n'의 의미는 무엇입니까?


163

bash 쉘 스크립트의 시작 부분에는 다음 행이 있습니다.

IFS=$'\n'

이 기호 모음의 의미는 무엇입니까?


3
unix.stackexchange.com/questions/26784/understanding-ifs 및 인용 된 질문을 참조하십시오 .
Gilles

vim 구문은 이것을 오류로 강조 표시합니다. 고치다?
theonlygusti

IFS=$'\n'bashism입니다 (+ 다른 쉘, ANSI-C Quoting 사용 , 해결 방법은 stackoverflow.com/questions/10748703/…
pevik

답변:


199

IFS"내부 필드 구분 기호"를 나타냅니다. 쉘은 단어 분할을 수행하는 방법, 즉 단어 경계를 인식하는 방법을 결정하기 위해 셸에서 사용합니다.

bash와 같은 쉘에서 이것을 시도하십시오 (다른 쉘은 이것을 다르게 처리 할 수 ​​있습니다 (예 : zsh)).

mystring="foo:bar baz rab"
for word in $mystring; do
  echo "Word: $word"
done

의 기본값 IFS은 공백 문자 (정확히는 공백, 탭 및 줄 바꿈)로 구성됩니다. 각 문자는 단어 경계가 될 수 있습니다. 따라서 기본값 인을 사용하면 IFS위의 루프가 인쇄됩니다.

Word: foo:bar
Word: baz
Word: rab

다시 말해, 쉘은 공백이 단어 경계라고 생각합니다.

이제 IFS=:루프를 실행하기 전에 설정 을 시도 하십시오. 이번 결과는 다음과 같습니다.

Word: foo
Word: bar baz rab

이제 쉘은 mystring단어로도 분리 되지만 이제는 콜론 만 단어 경계로 취급합니다.

의 첫 번째 문자 IFS는 특별합니다. 특수 $*변수를 사용할 때 출력에서 ​​단어를 구분하는 데 사용됩니다 (예 : Advanced Bash Scripting Guide 에서 가져온 예 와 같이 특수 변수에 대한 자세한 정보를 찾을 수 있음).

$ bash -c 'set w x y z; IFS=":-;"; echo "$*"'
w:x:y:z

다음과 비교하십시오 :

$ bash -c 'set w x y z; IFS="-:;"; echo "$*"'
w-x-y-z

두 예제에서, 쉘이 여전히 모든 문자를 취급합니다 :, -그리고 ;단어 경계한다. 변경되는 유일한 것은의 동작입니다 $*.

알아야 할 또 다른 중요한 사항은 소위 "IFS 공백" 이 처리되는 방식 입니다. 기본적으로, 즉시로 IFS선행 및 후행 공백 문자열에서 제거되는 공백 문자를 포함 그것을하고 처리하기 전에 분할하는 순서 연속적인 공백 문자를뿐만 아니라 필드를 구분합니다. 그러나 이것은 실제로 존재하는 공백 문자에만 적용됩니다 IFS.

예를 들어, 문자열을 살펴 보자 "a:b:: c d "(후행 공간과이 개 공간 문자 사이 cd).

  1. IFS=:: 그것은 네 개의 필드로 분할 할 것 "a", "b", ""(빈 문자열) 및 " c d "(다시, 두 공간 사이 cd). 마지막 필드의 선행 및 후행 공백에 유의하십시오.
  2. 으로 IFS=' :', 그것은 5 개 개의 필드로 분할된다 : "a", "b", ""(빈 문자열), "c""d". 앞뒤 공백이 없습니다.

두 번째 예제에서 여러 개의 연속 공백 문자가 두 필드를 구분하는 방법에 유의하십시오. 반면에 여러 개의 연속 콜론은 공백 문자가 아니기 때문에 그렇지 않습니다.

관해서 IFS=$'\n', 즉이며 ksh93또한 지원 구 bash, zsh, mksh와 FreeBSD sh(모든 쉘 사이에 변화로). bash 맨 페이지 인용 :

$ 'string'형식의 단어는 특별히 취급됩니다. ANSI C 표준에서 지정한대로 백 슬래시 이스케이프 문자를 바꾸어 단어를 "문자열"로 확장합니다.

\n개행 문자의 이스케이프 시퀀스이므로 IFS단일 개행 문자로 설정됩니다.


3
이것은 좋지만 제 생각에는 bash스크립팅 가이드 또는 POSIX가 아닌 POSIX 사양을 읽고 이해하는 것이 훨씬 좋습니다 . 기본적으로 이와 같은 링크에서 사용 가능한 정보는 중요한 방식으로 부족합니다. 어쨌든 쉘 분할과 관련된 두 가지 중요한 포인트 인 글 로빙과 IFS 공백이 누락되었습니다.
mikeserv

@ mikeserv 감사합니다. IFS 공백에 대한 정보를 추가했습니다. 그것에 대해 몰랐습니다. :)
Tblue

4
관련성이 없지만 궁금한 unset IFS점이 있다면 쉘이 어떻게 다르게 동작 하는지 살펴보고 싶을 것이다 IFS=. 또한 IFS의 첫 번째 바이트도 특별 "${named_array[*]}"하지만 확장이 인용되지 않은 경우에는 중요하지 않습니다.
mikeserv

몇 가지 더 많은 점 : 1 단어 분할 $IFS은 다음과 같이 목록 컨텍스트에서 인용되지 않은 변수를 확장 할 때 수행되는 두 가지 주요 작업 중 하나입니다 ( 연산자 의 split일부 임 split+glob). 다른 하나는 globbing입니다. 작업 분할 set -f을 사용하는 경우 일반적으로 glob부품 을 비활성화 하기 위해 발행해야합니다 .
Stéphane Chazelas

3
3- $IFSread내장 명령으로 도 사용됩니다
Stéphane Chazelas

22

달러로 묶은 작은 따옴표 안에는 일부 문자가 특별히 평가됩니다. 예를 들어, \n새 줄로 변환됩니다.

따라서이 특정 행은 변수 IFS에 개행을 지정합니다. IFS는 bash의 특수 변수 인 Internal Field Separator입니다. 말했듯 man bash

확장 후 단어 분할 및 read내장 명령을 사용하여 행을 단어로 분할하는 데 사용됩니다 . 기본값은 <space><tab><newline>입니다.


5
dollared single quotes간단한 작은 따옴표와 다른 것을 언급하면 +1입니다 .
Snowcrash

2
간단한 작은 따옴표와 다른 달러로 묶은 작은 따옴표 에 대해 +1을 말하면 @Snowcrash +1입니다 . 죄송합니다. 도움이되지 못했습니다.)하지만 실제로 중요하기 때문에 지적하는 것이 좋습니다.
Pryftan

1
@Pryftan +1 +1 +1 ... 알다시피 ... 정말 중요합니다.
0xc0de

@ 0xc0de 확실히 동의합니다! 고마워요! :)
Pryftan

15

간단히 말해, IFS=$'\n'개행 \n을 variable에 지정 하십시오 IFS.

$'string'construct는 ANSI C와 같은 이스케이프 시퀀스를 디코딩하는 데 사용되는 인용 메커니즘입니다. 이 구문에서 온다 ksh93, 그리고 같은 현대 쉘에 이식했다 bash, zsh, pdksh, busybox sh.

이 구문은 POSIX에 의해 정의되지 않았지만 SUS 문제 7에 대해 허용되었습니다 .


-1

내가 설명을 선호 $IFS예를 통해 :
Suppsoe 당신이 CP 또는 MV 또는 다른 파일 proccessing 원하는, IFS가 만들면 기본적으로 비어있는 파일이 메타 문자 나 공간 등이있을 때, :
Linux Administration.pdf또는 Free Software Fundation.ogg리눅스는 고려 : 물론을, 때문에 당신은 probelm을해야합니다 별도의 매개 변수와 Administartion은 별도의 매개 변수를 고려하므로 bash에는 built-in variable다음으로 초기화 할 수 있습니다 IFS==$(echo -en "\n\b"). 그런 다음 bash는 파일 이름 사이의 메타 문자와 공백을 버립니다. 예 :

#!/bin/bash
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
mymusicdir=~/test/dd
find $mymusicdir -name "*" -execdir rename 's/ /_/g' "{}" +
IFS=$SAVEIFS
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.