필드 구분을 위해 백슬래시 또는 작은따옴표 사용

필드 구분을 위해 백슬래시 또는 작은따옴표 사용

나는 항상 다음과 같이 필드 구분을 위해 작은따옴표를 사용했습니다.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\tFS\t

awk -F '\\', 를 사용하여 매개변수를 awk전달받아 문자 로 \\설정합니다 . 엄밀히 말하면 이스케이프 시퀀스가 ​​아직 완료되지 않았기 때문에 will이 지정되지 않았지만 실제로는 busybox를 제외하고 내가 아는 모든 구현에서 이를 .FS\awk -F '\'awkawkawk -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와는 아무 관련이 없습니다.

관련 정보