「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

関連情報