Bash에서 토큰화는 명령줄 처리의 한 단계입니다. Bash 매뉴얼에서
쉘은 $IFS의 각 문자를 구분 기호로 처리하고 이러한 문자를 필드 종결자로 사용하여 다른 확장 결과를 단어로 분할합니다. IFS가 설정되지 않았거나 해당 값이
<space><tab><newline>
기본값 인 경우<space>, <tab>, and <newline>
이전 확장 결과의 시작과 끝 부분에 있는 시퀀스는 무시되고 시작이나 끝 부분에 없는 IFS 문자 시퀀스는 단어를 구분하는 데 사용됩니다. IFS에 기본값이 아닌 값이 있는 경우 공백 문자가 IFS 값(IFS 공백)에 있는 한 단어의 시작과 끝 부분에 있는 공백과 탭 시퀀스는 무시됩니다. IFS 공백이 아닌 IFS의 모든 문자와 인접한 IFS 공백 문자가 함께 필드를 구분합니다. 공백 문자의 IFS 시퀀스도 구분 기호로 간주됩니다. IFS 값이 비어 있으면 단어 분할이 발생하지 않습니다.
space
매개변수 사이의 구분 기호 가 또는 로 대체 되도록 다음 예제를 다시 작성하고 싶습니다 a
.b
c
tab
newline
$ echo a b c
a b c
하지만 버튼을 눌러도 Tab
아무 일도 일어나지 않습니다.
을 클릭하면 \
출력에 , 와 사이에 공백이 없습니다 return
.a
b
c
$ echo a\
> b\
> c
abc
왜 인용문에서 말하는 대로 할 수 없나요?
그런데 아무 결과도 나오지 않습니다 $IFS
.
$ echo $IFS
답변1
bash
개행 문자는 값에 관계없이 특별히 처리됩니다 IFS
. 개행 앞의 백슬래시로 인해 개행이 발생합니다.무시당하다. 이는 단어 분할과 관련이 없으며 IFS
일부 사용자 정의 값으로 설정된 경우에도 발생합니다.
에서 LESS=+/^QUOTING man bash
:
A non-quoted backslash (\) is the escape character. It preserves the literal value of the next character that follows, with the exception of <newline>. If a \<newline> pair appears, and the backslash is not itself quoted, the \<newline> is treated as a line continuation (that is, it is removed from the input stream and effectively ignored).
개행 문자에서 단어 분할이 다른 방식으로 발생하는 것을 볼 수 있습니다. 즉, 개행 문자를 변수에 넣은 다음 echo
변수를 인용하지 않고 참조하는 것입니다.
$ myvar=a$'\n'b$'\n'c
$ echo "$myvar"
a
b
c
$ echo $myvar
a b c
$
답변2
직접적인 대답
이것인용되지 않음명령: , 그것이 무엇이든 간에 echo a b c
(메타 문자 공간)으로 분할됩니다 . : echo가 다음과 같이 정의되므로 분할 매개변수는 공백과 함께 인쇄됩니다 .IFS
echo
a
b
c
LESS=+/'^ *echo \[-neE\] \[arg ...\]' man bash
공백으로 구분된 출력 매개변수와 그 뒤에 개행 문자가 옵니다.
참여도 없습니다 $IFS
.
따라서 귀하가 인용한 내용은 여기서 관련이 없습니다. 주요 부분은 다음과 같습니다.
...다른 확장의 결과를 단어로 분할...
너~ 해야 하다$IFS
사용 전 연장이 있습니다.
에는 확장자가 없습니다 a b c
.
$IFS의 효과를 사용해야 하는 경우 따옴표가 없는 확장을 사용하세요.
$ var='a b c'
$ echo $var
a b c
그러나 이는 여전히 $IFS
출력에는 사용되지 않고 분할에만 사용됩니다.
출력의 IFS.
$IFS
의 상관관계(출력에 대한)는 어디에 있습니까 $*
?
$ set -- a b c
$ IFS=$'\t'
$ printf '%s\n' "$*" | od -An -vtx1c
61 09 62 09 63 0a
a \t b \t c \n
이것이 당신에게 필요한 것입니까?
기타 사항.
키보드 탭
Tab 키를 눌러도 아무 일도 일어나지 않습니다
그런 다음 을 누르고 CtrlV손을 떼고 동시에 을 누릅니다 Tab.
그러나 따옴표가 없으면 변수에 탭 문자를 할당할 수 없습니다. 시험:
$ var=a b ### The space represents a tab as above.
bash: b: command not found
필요할 것이예요:
$ var="a b" ### The space represents a tab as above.
최소한 큰따옴표입니다.
견적IFS
$IFS에 대한 결과가 없습니다.
$ echo $IFS
$IFS
참조가 없기 때문에 아무것도 생성되지 않습니다 $IFS
. 노력하다:
<user>$ echo "$IFS" | sed -n l
\t$
$
<user>$
$IFS
echo 명령의 새 줄 과 echo 명령의 새 줄이 있습니다 .
printf로 변경하는 것이 좋습니다.
<user>$ printf '%s' "$IFS" | sed -n l
\t$
<user>$
그리고 od를 사용하세요:
$ printf '%s' "$IFS" | od -An -vtx1c
20 09 0a
\t \n
문자열에 어떤 문자가 포함되어 있는지 "확인"할 수 있는 방법이 이미 있기 때문입니다.
또한 이를 사용하여 여러 문자열 내의 내용을 "볼" 수도 있습니다.
$ var='a b c'
$ echo "$var" | od -An -vtx1c
61 20 62 20 63 0a
a b c \n
이것은 놀라운 일이 아닙니다. 왜냐하면 이것은 (작은 따옴표로) 다음과 같아서는 안 되기 때문입니다:
$ var='a\
> b\
> c'
$ echo "$var" | od -An -vtx1c
61 5c 0a 62 5c 0a 63 0a
a \ \n b \ \n c \n
정확하게 입력된 내용입니다. var가 올바르게 인용되면 백슬래시가 올바르게 나타납니다.
인용하다
그러나 큰따옴표로 인용하면 일부 문자가 변경될 수 있습니다.
$ var="a\
> b\
> c"
$ echo "$var" | od -An -vtx1c
61 62 63 0a
a b c \n
그러나 당신이 쓴 내용에는 var 설정이나 에코에서 사용하는 것에 대한 인용문이 없습니다.
이것은 쉘에 있어서는 안 되는 일입니다. 제발올바른 인용.
답변3
공백을 탭으로 바꾸려면 $IFS
매개변수 배열을 사용할 수 있습니다.
unset IFS
set a b c
IFS=$(printf \\t)
printf "%s\n" "$*"
이것이 $IFS
분할과 관련이 있다는 것을 이해하십시오. 여기에는 목록 컨텍스트를 분할하기 위해 쉘에서 사용하는 인용되지 않은 확장된 문자 목록이 포함되어 있습니다. 넌 그걸 정말 못 쓰잖아바꾸다특수 쉘 매개변수의 특별한 경우를 제외한 문자입니다 $*
. 다른 모든 경우에는 그 사용이 다음과 동일합니다.유효하지 않은인용되지 않은 쉘 확장의 특정 부분을 명확하게 하고 구분합니다.