내용이 다음과 같은 테스트 파일을 받았습니다.
a -*- b
사용했는데 awk 'BEGIN {FS="*"} {print $2}' test
인쇄가 되네요
- b
옳은! 하지만 을 사용하면 다음과 같은 awk 'BEGIN {FS="-*-"} {print $2}' test
결과를 얻습니다.
*
나는 FS
정규 표현식이 지원된다는 것을 알고 있으므로 \
이전에 이를 추가 했고 여전히 이 작업을 *
수행 awk 'BEGIN {FS="-\*-"} {print $2}' test
하여 다음을 얻었습니다.
*
다행히 저는 반년 전에 블로그를 시작했습니다. awk 'BEGIN {FS="-[*]-"} {print $2}' test
이 경우에 사용해야 한다고 언급되어 있습니다 . 그러므로 나는 다음을 얻는다:
b
다시 정답!
*
그런데 왜 FS가 그것을 이해할 수 있는지 , 이해할 수 없는지 -*-
, -\*-
그리고 마침내 이해할 수 있게 되었는지 정말 혼란스럽습니다 -[*]-
.
메커니즘은 무엇입니까?
답변1
한 문자보다 길면 FS
정규식으로 처리됩니다. of는 FS
단지 *
고정된 문자열로 취급되지만 FS
of는 (one or more ) 와 동등한 -*-
정규식입니다 . 그러므로 자신을 평범한 인물로 볼 수 있도록 허용해야 합니다 . 그리고 둘 다 이것을 할 수 있습니다. 그러나 문자열은 구문 분석됩니다.-*-
-+
-
*
-\*-
-[*]-
FS
두 배- 할당할 때 한 번, 분할할 때 한 번 FS
. 그렇기 때문에 이스케이프 문자 \
도 이스케이프되어야 합니다.\
$ awk -F '-\\*-' '{print $2,FS}' test.txt
b -\*-
$ awk -F '-\*-' '{print $2,FS}' test.txt
awk: warning: escape sequence `\*' treated as plain `*'
* -*-
답변2
muru의 답변에서 중요한 점 중 하나는 정규식에 백슬래시를 추가하려면 FS
이중 백슬래시를 작성해야 한다는 것입니다 \\
. 이는 백슬래시가 두 가지 다른 수준에서 이스케이프 문자로 사용되기 때문입니다.
문자열의 단일 백슬래시는 다음 문자를 이스케이프하는 것으로 처리되므로 정규식에서 단일 백슬래시를 얻으려면 백슬래시 자체를 이스케이프해야 합니다. 그런 다음저것백슬래시는 정규식에서 다음 문자를 이스케이프합니다.
FS='ax\*'
댓글에서 말했듯이 as 와 as 사이에는 차이가 없지만 awk FS='ax*'
는 경고를 인쇄합니다. 텍스트를 입력 하려면 will Split on 처럼 이중 백슬래시를 사용해야 합니다 .\*
*
*
FS
FS='ax\\*'
ax*
아마도 몇 가지 예를 통해 이를 좀 더 명확하게 이해할 수 있을 것입니다.
#!/usr/bin/env bash
s='123abcd
123axbcd
123axxbcd
123ax*bcd
123ax**bcd'
printf "%s\n\n" "$s"
awk -F 'ax*' 'BEGIN{printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
awk 'BEGIN{FS="ax*"; printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
awk -F 'ax\*' 'BEGIN{printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
awk 'BEGIN{FS="ax\*"; printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
awk -F 'ax\\*' 'BEGIN{printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
awk 'BEGIN{FS="ax\\*"; printf "FS=[%s]\n", FS};{printf "[%s] [%s]\n", $1, $2}' <<< "$s"
echo
산출
123abcd
123axbcd
123axxbcd
123ax*bcd
123ax**bcd
FS=[ax*]
[123] [bcd]
[123] [bcd]
[123] [bcd]
[123] [*bcd]
[123] [**bcd]
FS=[ax*]
[123] [bcd]
[123] [bcd]
[123] [bcd]
[123] [*bcd]
[123] [**bcd]
awk: warning: escape sequence `\*' treated as plain `*'
FS=[ax*]
[123] [bcd]
[123] [bcd]
[123] [bcd]
[123] [*bcd]
[123] [**bcd]
awk: warning: escape sequence `\*' treated as plain `*'
FS=[ax*]
[123] [bcd]
[123] [bcd]
[123] [bcd]
[123] [*bcd]
[123] [**bcd]
FS=[ax\*]
[123abcd] []
[123axbcd] []
[123axxbcd] []
[123] [bcd]
[123] [*bcd]
FS=[ax\*]
[123abcd] []
[123axbcd] []
[123axxbcd] []
[123] [bcd]
[123] [*bcd]
답변3
구분 기호 내부에서 "
백슬래시를 다시 이스케이프 처리해야 합니다.
$ echo 'a -*- b' | awk 'BEGIN {FS="-\\*-"} {print $2}'
b
정규식을 FS 변수에 전달하므로 \\
큰따옴표 안의 큰따옴표는 단일 백슬래시로 구문 분석되고 결과 정규식은 입력 문자열에 적용됩니다.