ストリーミング (あと switch 文)
カレントディレクトリに以下の内容の aaa.txt があったとして、
hoge piyo foo bar
このコマンドを実行するとどういう結果が得られるでしょう?
$line = 0; cat 'aaa.txt' | ?{ $line++; $_ -match 'o$' } | %{ "$line $_" }
分かりにくい場合はこちらをどぞ。
$line = 0 cat 'aaa.txt' | where { $line++; $_ -match 'o$' } | foreach { "$line $_" }
・・・って、変らないか。
1.
4 piyo 4 foo
2.
2 piyo 3 foo
回答はまだだよ!
つまり、文に書き換えた場合、出力が
$line = 0 $cat = @() foreach ($lineStr in cat 'aaa.txt') { $line++ if ($lineStr -match 'o$') { $cat += $lineStr } } foreach ($lineStr in $cat) { "$line $lineStr" }
と同じになるか、
$line = 0 foreach ($lineStr in cat 'aaa.txt') { $line++ if ($lineStr -match 'o$') { "$line $lineStr" } }
と同じになるか、という問題です。
?{ $line++; $_ -match 'o$' }
の部分が行数分実行された後で、正規表現にマッチした行が %{ "$name $line $_" }
に渡されると考えると 1. になりそうなものだけど、実際には 2. になる。
これがストリーミングで、cat が一行返すごとにパイプラインを最後まで*1流れていく。
この部分が理解できれば、一つの壁を越えたことになる・・・のかな?
おまけ
PowerShell 最強の (?) switch 文を使った方法。
$line = 0 switch -regex -file 'aaa.txt' { 'o$' { $line++; "$line $_" } default { $line++ } }
switch 文・・・恐ろしい子!