这符合我的预期(当 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
记录到 using split()
,并且 perlfunc 手册页对此进行了说明:
作为另一个特殊情况,当 PATTERN 被省略或由单个空格字符(例如
' '
or"\x20"
,但不是 eg"/ /"
)组成的字符串时,“split”模拟命令行工具 awk 的默认行为。在这种情况下,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 进行了测试。)
答案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