나는 항상 다음과 같이 필드 구분을 위해 작은따옴표를 사용했습니다.awk -F';' ...
나에게 상당히 새로운 점은 다음과 같이 백슬래시를 사용하는 방법입니다.awk -F\; ...
둘 사이에 기술적 차이가 있습니까, 아니면 단지 선호의 문제입니까?
답변1
이것은 셸이 아니라 쉘과 관련이 있습니다 awk
.
Bourne과 같은 쉘에서 , \
및 '...'
는 "..."
모두 참조 연산자입니다.
인용은 쉘 구문에서 문자가 가질 수 있는 특별한 의미를 제거합니다. \
단일 문자를 인용하고(제거되는 개행 문자 제외) 여러 문자를 인용할 수 있습니다( '...'
개행 문자 제외)."..."
"..."
인용하다문자별로).
;
쉘 구문의 특수 문자입니다. 명령을 구분하는 데 사용됩니다. 명령에 그대로 전달하려면 이를 인용해야 합니다. \;
, ';'
할 것입니다.
";"
;
큰 따옴표 안에 여전히 특수한 문자 중 하나가 아니지만 "\\"
리터럴 백슬래시를 명령에 전달 해야 합니다 \
. 큰 따옴표 안에 여전히 특수한 문자 중 하나도 마찬가지입니다 "..."
(뒤에 오는 경우에만 해당). 특수)는 "..."
자신과 마찬가지로 다른 특수 문자로 구성됩니다 "
.
다시 말하지만, 이는 인클로저에 따라 많이 달라집니다. 예를 들어, 및 는 따옴표 문자는 물론이고 rc
쉘에서 특별하지 않으며 명령이 및 -구분된 명령으로 구문 분석되므로 아무런 효과가 없습니다 .\
"
-F\;
awk -F\
...
;
바라보다일반 문자처럼 특수 문자를 사용하는 방법은 무엇입니까?자세한 내용은.
상황을 더 복잡하게 만들려면 인수 -F
자체 에 주목하세요.반품하나 또는 두 개의 백슬래시로 처리됨awk를 통해.
awk
먼저 수신한 인수를 처리하여 그 안에 있는 ANSI C 이스케이프 시퀀스를 확장합니다. awk -F '\t'
또는 awk -F \\t
또는 을 awk -F "\\t"
사용 하면 포함된 인수가 수신되어 awk -F "\t"
탭 문자로 확장됩니다. awk 변수에는 대신 TAB 문자가 포함됩니다 .awk
\t
FS
\t
awk -F '\\'
, 를 사용하여 매개변수를 awk
전달받아 문자 로 \\
설정합니다 . 엄밀히 말하면 이스케이프 시퀀스가 아직 완료되지 않았기 때문에 will이 지정되지 않았지만 실제로는 busybox를 제외하고 내가 아는 모든 구현에서 이를 .FS
\
awk -F '\'
awk
awk
awk -F '\\'
에서 단일 문자가 포함 awk
되면 FS
해당 문자가 필드 구분 기호입니다. awk -F .
점 문자로 레코드를 분할합니다.
그러나 FS
여러 문자를 포함하는 경우 정규식으로 해석됩니다. awk -F ..
두 개의 점 시퀀스에서는 오버플로되지 않지만 .
단일 문자와 일치하는 정규식 연산자와 마찬가지로 두 문자의 시퀀스에서는 오버플로됩니다. 두 개의 점으로 나누려면 awk -F '[.][.]'
또는 가 필요합니다 awk -F '\\.\\.'
.
의 경우 awk -F '\\\\'
쉘은 \\\\
리터럴을 에 전달하여 이 둘을 각각 확장하여 awk
정규식 으로 처리 되는 가 됩니다 . 이는 정규식 구문에서도 특별하며 문자의 특별한 의미를 제거하는 데 사용됩니다.awk
\\
\
FS
\\
\
정규식 연산자로이 시간. 다시 말하지만, 이번에는 정규식이지만 백슬래시 문자로 분할됩니다.
따라서 실제로는 \
Bourne과 같은 쉘에서 이 모든 것이 작동합니다.
awk -F '\' # FS becomes a single \ except in busybox where it's empty
awk -F "\\" # instead so it's a one-character split on backslash
awk -F \\ # and a one-field-by-character split in busybox
awk -F '\\' # FS becomes a single \ in every awk implementation
awk -F \\\\ # so one-character split on backslash
awk -F "\\\\"
awk -F '\\\' # FS is \ on busybox and \\ in other implementations
awk -F \\\\\\ # so one-character split on backslash in busybox and
awk -F "\\\\\\" # \\ regex split in other implementations, to the same effect
awk -F '\\\\' # FS is \\ in all implementations so
awk -F \\\\\\\\ # \\ regex split
awk -F "\\\\\\\"
작은 따옴표는 가장 직접적이고 가장 덜 놀라운 따옴표이기 때문에 작은 따옴표를 사용하는 것이 좋습니다. 따라서 백슬래시에서 이식 가능한 분할을 수행하려면 다음을 수행하십시오 awk -F '\\'
.
다음을 수행할 수도 있습니다.
awk -v FS='\\' ...
또는
awk 'BEGIN{FS="\\"} ...'
또는
awk ... 'FS=\\'
또는:
FS='\' awk 'BEGIN{FS = ENVIRON["FS"]} ...'
(추가 백슬래시 확장을 수행하지 마십시오 awk
. 따라서 백슬래시는 하나만 필요합니다.)
답변2
작은따옴표 안의 모든 문자는 문자 그대로 처리됩니다(즉, 작은따옴표 쌍 사이에 특수 문자가 없습니다). 작은따옴표 없이 리터럴 문자를 사용하려면 특별한 의미를 지닌 백슬래시 이스케이프 문자를 사용해야 합니다.
이는 쉘의 인용 규칙이며 awk와는 아무 관련이 없습니다.