"perl -F"가 "perl -F"와 다르게 작동하는 이유'

"perl -F"가 "perl -F"와 다르게 작동하는 이유'

이것은 내가 예상한 대로 수행됩니다(column2의 값이 변경될 때).

$ (echo 'a,,b';echo 'b,,a';echo 'c,a,b') |
    perl -a '-F,' -pe 'BEGIN{$last="---\n";}{local$_=$F[1];if(($last)ne$_){print"---\n";$last=$_;}}'
---
a,,b
b,,a
---
c,a,b

다음은 수행되지 않습니다.

$ (echo 'a  b';echo 'b  a';echo 'c a b') |
    perl -a '-F ' -pe 'BEGIN{$last="---\n";}{local$_=$F[1];if(($last)ne$_){print"---\n";$last=$_;}}'
---
a  b
b  a
c a b

답변1

-a를 사용하여 문서화되었으며 split()perlfunc 매뉴얼 페이지에서 이에 대해 설명합니다.

또 다른 특수한 경우로, "split"은 PATTERN이 생략되거나 단일 공백 ​​문자(예 : ' 'or "\x20"와 같지만 예는 아님 )로 구성된 문자열일 때 "/ /"명령줄 도구 awk의 기본 동작을 에뮬레이트합니다 . 이 경우 분할이 발생하기 전에 EXPR의 선행 공백이 제거되고 "/\s+/"특히 PATTERN이 고려됩니다. 이는 단일 공백 ​​문자가 아닌 연속 공백이 구분 기호로 사용됨을 의미합니다.

-F\040그래서 그게 다인 것 같아요 . 어떤 이유에서든 [\040]마찬가지인 것 같습니다. (추측해야 한다면 고정 문자열에 최적화된 다음 특수한 경우로 처리된다고 가정하겠습니다.)

$ echo 'a b  c' | perl -a -F'\040'  -le 'print join(":", @F)'
a:b:c
$ echo 'a b  c' | perl -a -F'[\040]'  -le 'print join(":", @F)'
a:b:c

반면에 \040{1}원하는 작업을 수행하고 탭 문자를 구분 기호로 인식하지 못하는 것 같습니다.

$ echo 'a b  c' | perl -a -F'\040{1}'  -le 'print join(":", @F)'
a:b::c
$ printf 'a b\t c' | perl -a -F'\040{1}'  -le 'print join(":", @F)'
a:b     :c

split아니면 문자열 대신 패턴을 사용하여 명시적으로 수동으로 호출 할 수도 있을 것 같습니다 .

$ printf 'a b\t c' | perl -n -le '@F = split(/ /); print join(":", @F)'
a:b     :c

(Perl v5.24.1 및 v5.28.1로 테스트했습니다.)

답변2

에서 man perlrun:

-Fpattern [...] 리터럴 공백 또는 NUL 문자는 패턴에 사용할 수 없습니다.

하지만 당신은할 수 있는\040 사용:

$ (echo 'a  b';echo 'b  a';echo 'c a b') |   perl -a '-F\040' -pe 'BEGIN{$last="---\n";}{local$_=$F[1];if(($last)ne$_){print"---\n";$last=$_;}}'
---
a  b
---
b  a
c a b

불행히도 그것은 다음과 같이 해석되는 것 같습니다.이상공백(-F의 기본값이기도 함)은 내가 원하는 것이 아닙니다.

\s 더 잘 작동하지만 \t다음과도 일치합니다.

$ (printf 'a\t b\n';echo 'b  a';echo 'c a b') |   perl -a '-F\s' -pe 'BEGIN{$last="---\n";}{local$_=$F[1];if(($last)ne$_){print"---\n";$last=$_;}}'
---
a        b
b  a
---
c a b

관련 정보