bash는“IFS”변수의 값에 따라 동작을 변경합니다


18

IFS변수를 bash공백으로 설정하면 여러 공백을 하나의 공백으로 처리합니다 ( myprogram받은 명령 줄 인수를 인쇄하는 프로그램입니다).

IFS=" "
x="hello   hi   world"
./myprogram $x
argv[1] = hello
argv[2] = hi
argv[3] = world

그러나 IFS변수를 쉼표로 설정하면 bash여러 쉼표를 하나의 쉼표로 취급하지 않습니다.

IFS=","
x="hello,,,hi,,,world"
./myprogram $x
argv[1] = hello
argv[2] = 
argv[3] = 
argv[4] = hi
argv[5] = 
argv[6] = 
argv[7] = world

왜 그런 겁니까?


참고로 "IFS"는 Internal Field Separator를 의미 합니다.
pr1268

답변:


21

이 문서에 설명되어 man bash있습니다. 공백이 아닌 IFS에서 문자의 단일 항목은 필드를 구분합니다.

보낸 사람 man bash:

쉘은 IFS의 각 문자를 분리 문자로 취급하고이 확장 문자를 필드 종결 자로 사용하여 다른 확장 결과를 단어로 나눕니다. IFS가 설정되지 않은 경우, 또는 그 값이 정확히 경우 <space><tab><newline>다음의 순서 기본 <space>, <tab><newline>시작과 이전 확장의 결과의 끝에서 무시되고 IFS 문자의 순서가 아니라 시작 부분이나 끝 구분하는 역할을 말. IFS에 기본값 이외의 값이있는 경우 공백 문자가 IFS 값 (ISF 공백 문자)에있는 한 공백 문자 공백, 탭 및 개행 문자는 단어의 시작과 끝에서 무시됩니다. ). 인접한 IFS 공백 문자와 함께 IFS 공백이 아닌 IFS의 문자는 필드를 구분합니다. 일련의 IFS 공백 문자도 분리 문자로 처리됩니다. IFS 값이 널이면 단어 분할이 발생하지 않습니다. [공포도 추가]

예 : 필드 분할

IFS에 공백 문자가 없으면 공백이 필드에 포함됩니다.

$ ( IFS=',' x='one , two,three'; printf "<%s>\n" $x )
<one >
< two>
<three>

IFS에 공백과 쉼표가 모두 있으면 공백 순서와 쉼표, 공백 순서가 단일 구분 기호로 처리됩니다.

$ ( IFS=' ,' x='one , two,three'; printf "<%s>\n" $x )
<one>
<two>
<three>

쉼표 시퀀스는 빈 필드 시퀀스로 해석됩니다.

$ ( IFS=' ,' x='one,,,two,three'; printf "<%s>\n" $x )
<one>
<>
<>
<two>
<three>

예 : 선행 및 후행 공백

IFS에 공백이없는 경우 선행 및 후행 공백이 필드에 유지됩니다.

$ ( IFS=',' x='  one , two,three  ,'; printf "<%s>\n" $x )
<  one >
< two>
<three  >

IFS에 공백이 있으면 선행 또는 후행 공백이 제거됩니다.

$ ( IFS=' ,' x='  one , two,three  ,'; printf "<%s>\n" $x )
<one>
<two>
<three>

"공백 문자가 IFS의 값에있는 한, 공백 문자, 탭 및 개행 문자의 시퀀스는 단어의 시작과 끝에서 무시됩니다"
Jeff Schaller

@JeffSchaller 훌륭한 아이디어 : 방금 섹션을 추가했습니다.
John1024


누락 된 값이있는 탭으로 구분 된 파일이 있으면 어떻게합니까? 즉, 일련의 탭이 단일 탭으로 취급되는 것을 원하지 않습니다. 또한 필드에는 쉼표가 포함되어 있으므로 구분 기호로 사용할 수 없습니다. 탭이 아닌 다른 구분 기호를 사용하는 유일한 솔루션입니까?
다 보스

@Davos 각 필드가 단일 탭으로 구분 된 데이터의 awk경우 -F'\t'또는 옵션 과 같이 쉽게 처리 할 수있는 다른 도구를 사용하는 것이 더 자연 스러울 수 있습니다 cut. 또는 최신 버전이 있는 경우 옵션을 bash사용하여 필드를 구문 분석 할 수 있습니다 . readarray-d$'\t'
John1024
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.