Perl

為什麼“perl -F”與“perl -F<space>”的工作方式不同

  • December 8, 2020

這符合我的預期(當 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

-a記錄到 using split(),並且 perlfunc 手冊頁對此進行了說明:

作為另一種特殊情況,“split”模擬命令行工具 awk 的預設行為,當 PATTERN 被省略或由單個空格字元組成的字元串(例如 ' 'or "\x20",但不是 eg "/ /")時。在這種情況下,EXPR 中的任何前導空格在拆分發生之前都會被刪除,而 PATTERN 則被視為"/\s+/"; 特別是,這意味著任何連續的空格(不僅僅是單個空格字元)都用作分隔符。

所以我想-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 進行了測試。)

引用自:https://unix.stackexchange.com/questions/623388