PowerShell -Part 4
レス数が1000を超えています。これ以上書き込みはできません。
テキストに限った話ではないけど、質問者が正確に把握してるともまた限らない PoweShellのクラスで、C#と同様にインデクサーを定義することはできますか?
例えば、あるクラスのインスタンス$hogeに対して
$hoge[$i] という感じで添字でアクセスしたいです。 C#の演算子オーバーロードがPSで使えるかと同じ無意味な質問 >>898
たぶんテキストストリームのことです
file:stream1
↑これ そのファイルに付属させたい情報を一緒にいれておくということだろう
ソースだったら、開発秘話とか入れとけば? あと自分の写真とか連絡先とかプロフィールを入れとけばいいかもW >>905
>>906
ああREADME.md的なものをですか?
なるほどそれは便利そう >>902
PowerShellでも.Netの
コレクションクラスを使えますので、
インデクサーを使うこと自体はできますよね?
同様のことをユーザー定義クラスで実現できないかと思ったのですが、
無意味でしょうか… >>904
それ代替データストリームに見えるけどどの辺がテキストストリームなんだろ
しかも、NTFSに依存する機能で.mdの代替とか悪手でしかない PowerShellのパイプやリダイレクトは仕様が良くないね。
エンコードせずにバイナリデータのままパイプする従来の方法も選べたほうが良かったね。 cmd /c foo `| bar `> baz
とでもしておけ >>911
これじゃあかんの
[byte[]]$bin = cat -encoding byte >>914
encoding byteがどういう型が返るか示しただけでもちろんパイプにも使えるけど >>912
`| や`>が解説されているマイクロソフト公式ページはどこになりますか?
検索キーワードが記号ばかりなので探し方が分からず困っております。
>>913
私の環境では、以下のエラーが出て動きませんでした。
Get-Content: Cannot process argument transformation on parameter 'Encoding'.
'byte' is not a supported encoding name. For information on defining a custom encoding,
see the documentation for the Encoding.RegisterProvider method. (Parameter 'name') >>917
'|'はパイプ'>'はリダイレクトで調べれば出てくるよ
bashの知識が必要になるな >>918
検索にbashの知識が必要というのは具体的にどういう意味ですか? ひょっとして>>912と>>918は別人なのかな。
もし別人なら>>918への質問はなかったことにしてください。論点がずれてるようだから。 @パターン1
$data = @('red','green','blue')
if ( $data -ne 'green' )
{
'greenはありません'
}
greenはありません
Aパターン2
$data = @('red','green','blue')
if ( $data -ne 'pueple' )
{
'greenはありません'
}
greenはありません
両方とも同じ結果を返してしまいます。
配列と比較して、無かったらtrue、あったらfalseみたいな書き方ってありませんか?
イメージとしては
if ( $data.notContains('green'))
みたいな書き方です。
用としては、if ( $data.Contains('green'))で足りるのですが、
気持ちの問題として、無かったらtrue、あったらfalseという書き方をしたいです。
よろしくお願いいたします。 >>922
> 両方とも同じ結果を返してしまいます。
まず
$data = @('red','green','blue')
$data -ne 'green'
で何が戻ってくるか確認すればなぜそう言うふうに動くかわかると思う
> 気持ちの問題として、無かったらtrue、あったらfalseという書き方をしたいです。
どうしても-eqとか使いたい場合、俺なら($data -eq 'green').Count == 0って書くかな
どう見ても$data.Contains('green')の方がわかりやすいと思うけど $data = @('red','green','blue')
if (not ($data -eq 'green')) {}
if (not ($data.Contains('green'))) {}
if (not ($data -contains 'green')) {}
if ($data -notcontains 'green') {}
if ('green' -notin $data) {}
-eq演算子はフィルタとして働くのでここでの用法は微妙
-in系の演算子は配列が大きいとオーバーヘッドが大きいらしい 否定をtrueにするってどういうことだろ
$colors = @('red','green','blue')
$found = $data -contains 'green'
if ($found) {
} else {
}
なら自然に読み下せる
ここで$notFoundという変数を使われると気になる
if (not $found) {
# 先に書いておきたい処理
} else {
# 長々とした本処理
}
としたいという趣旨ならわかる 変数名を変え忘れたので訂正
$found = $colors -contains 'green' >>923-925
レスありがとうございます。
> 否定をtrueにするってどういうことだろ
> どう見ても$data.Contains('green')の方がわかりやすいと思うけど
$exec_shinai_jikan=@('01','02','03')
$imananji=Get-Date -Format HH
if ($exec_shinai_jikan -notcontains $imananji){
"実行するよ"
} else {
"実行しないよ"
}
実際のコード(一部)はこれです。変数名のセンスが独特ですよね・・(By 開発の人、私は開発じゃないです)といわれているので
出すのが恥ずかしかったんです。混乱を生んだようでして申し訳ない。
>で何が戻ってくるか確認すればなぜそう言うふうに動くかわかると思う
・0か0を超える値か
・nullかnullを除く何らかの値か
でtrue or falseが決まる感じでしょうか?
-notって、-notだけじゃ赤傍線引かれるけどなにがだめなんだと思ったら、-not〜って表現があったんですね。
ありがとうございます。 >>918
bashの知識は不要でしょ
DOSですらパイプやリダイレクト存在するんだし なるほどそういう感じか
-not演算子のハイフン書き忘れてた
ごめんね >>923
($data -eq 'green').Count -eq 0
これってgreenが含まれない場合は最初の-eq演算による絞り込み結果が$nullになって
ぬるぽになるかと思いきや$null.Countの呼び出しは特例的に0を返すんやね
またPowershellの妙な癖を覚えてしまった >>930
> これってgreenが含まれない場合は最初の-eq演算による絞り込み結果が$nullになって
ならないよ、単に空の配列になるだけ
gm -inputobject ($data -eq 'yellow')
とかやればわかる >>931
ありがとう、勘違いしてた
そこは自然な動きなんやね 可変長配列数?的なものの実現方法を教えてください。
CSVを以下の通り加工したいのですが、
1554412,A,B,C,D
2176944,D,C,E,F,G,H,I,J
4887447,F,H,J,A,K
こんな感じのカンマ区切りcsvを
1554412,A
1554412,B
1554412,C
1554412,D
以下同じパターン
で成形したいのです。
csv区切り文字は必ずカンマで、
フィールド数は行により異なります。
行を読み込んで、配列に入れて〜、配列の最初のフィールドを入れて〜
とぼんやり想像しているのですが、「個数が定まっていない行を、配列に入れる方法」が想像つきません。
可変長配列数?的なものの実現方法を教えてください。 2つ目のカンマ or 改行まで読んでから要素数2の固定長配列に入れるのはどうですか。
エレガントな方法ではないと思うので、他の方の意見も参考にしてください あ、A, D, FじゃなくてA, B, Cでしたか。
マルチバリューカラムになっているのを正規化したいんですね。
最初の一つ目だけ取るのと勘違いしてました。
1. 一行読んでstring
2. カンマでstring.splitしてstring[]
3. [1]からstring.lengthまでを、[0]とstring.joinして、string[]
4. 全行ループ
これでどうですか PowerShell っぽくならこんな感じかな
'1554412,A,B,C,D', '2176944,D,C,E,F,G,H,I,J', '4887447,F,H,J,A,K' | %{
$a, $b = $_ -split ',', 2
$b -split ',' | %{ "$a,$_" }
} >>939
$xs[0]としてごらん
5行目"@ -split "`n"で意図通りになると思う >>939
"[Environment]::NewLine"
↓
"$([Environment]::NewLine)" >>937
とりあえず用は足せました。が、多分ご紹介の内容と全然違うことをやってると思います。
レスの内容が半分分かりませんでした。
>3. [1]からstring.lengthまでを
ここが猛烈にヒントになってこんな感じにしました。
foreach ($l in Get-Content C:\temp\test.txt) {
$l=$l.Split(",")
1..(($l.Length) - 1) | % {write-host ($l[0],$l[$_]) }
}
サンプルのコードをいただけると幸いです。
>>938
これも無事動きました。ありがとうございます。
%ってのを知りませんでした。
Powershell難しすぎです。
勉強してるんですが、正直心折れそうです。
bashはそこそこ使えるので行けるだろと思ってたんですが、ナメてました。
死にそうです。 >>942
自己レスすいません。
これも結局、
write-host ($l[0],$l[$_]) }
で間をカンマ区切りにしたかったんですけど、
1時間手を変え品を変えで結局ダメでした。
何が悪いんでしょうか。 何度もすいません。
write-hostで標準で区切り文字が半角スペースになってるという事実がやっとわかりました。
{write-host -Separator "," $l[0]$l[$_]}
で無事に希望の出力を得ることができました。
ありがとうございました。 すっきり書けなくてもどかしい
$csv -split "\r\n" | % { $a = $_ -split ','; $a[1..($a.Count - 1)] } | % { $a[0], $_ -join ',' } $?で直前のコマンドの実行結果を知ることができますが、
直前に実行したコマンドのPIDを知る方法ってありませんか?
Start-Process -FilePath c:\bin\command.exe -ArgumentList 1
$cmd1pid=get-chokuzenn-pid
$cmd1pid
78968
Start-Process -FilePath c:\bin\command.exe -ArgumentList 2
$cmd1pid=get-chokuzenn-pid
$cmd1pid
4292
実際に動かしたいのは、ttpmacro.exe(Teratermのマクロ)です。
Teratemマクロで外部の機器にsshで接続して、ssh接続のログの内容を見て
そのプロセスを終了させるか判断したいと思っております
書こうとしているスクリプトを動かす時点で、1個もTeratermが動いていないなら、
Get-Processでなんとかなると思うのですが、上記スクリプトを実行する時点で
ほかのTeratermが動いている可能性があり、それを間違って死なすわけにはいかず、
Powershellスクリプト内で、Start-Processなりで動かした、直前のプロセスのIDを知る方法があればと思い相談させていただきます
すいません、よろしくお願いいたします。 test.ps1
Start-Process -FilePath c:\bin\command.exe -ArgumentList 1
$cmd1pid=get-chokuzenn-pid
$cmd1pid
78968
Start-Process -FilePath c:\bin\command.exe -ArgumentList 2
$cmd2pid=get-chokuzenn-pid
$cmd2pid
4292
すいません、スクリプトの例に誤りがありました
訂正します 引数に -PassThru を付けて戻り値からidで取れないかな? >>947
プロセスIdなんて取る必要ない(むしろ危険)
>>950が言うように-PassThruオプションつけるとSystem.Diagnostics.Processオブジェクトが返ってくるからKill()メソッド呼ぶだけでいい >>950
>>951
$process = Start-Process -PassThru notepad
$process.Kill()
できました
ありがとうございました 音楽プレーヤーで MP3 ファイルをシャッフル再生させたいので、
dir /n /-b /s *.mp3 > playlist.txt
の結果をランダムに入れ替えるにはどうすればいいでしょうか?
(乱数で再生する行を求めると同じ曲がつづくかもしれないのでシャッフルにしたい。) >>954
テキトーでいいなら
dir /n /-b /s *.mp3 | sort -prop @{Exp={[Guid]::NewGuid()}} > playlist.txt Sort-Object {Get-Random}じゃあかんの? 自分の音楽コレクションのプレイリスト作る要件なら速度は別にと思わなくもない
5分とか掛かるならちょとやだけど プレイリストのランダム再生機能ぐらい大抵のプレイヤーに付いてるだろうに >>957 のリンク先のコードで質問です
勉強のためちょこちょこ編集してみたところ、
「なんでこれで変数の中がランダムにおきかわるの?」と疑問がわきました
$r = @(1,2,3,4,5,6,7,8,9,10)
$r=($r | sort -Property @{Exp={[Guid]::NewGuid()}})
$r
$foo = @(1,2,3,4,5,6,7,8,9,10)
$foo[0] = $foo | sort -prop @{Exp={[Guid]::NewGuid()}}
$foo[0]
前者のように、$rの中身を $r | sort -Prop〜で置き換えるというのなら納得がいくんですが、
なぜ、後者のように、書いてもランダムになるのかが納得いきません
変数定義はパイプの前の話で、どうしてそれがパイプ先の、ランダムにする操作で置き換わるのでしょうか。 >>960
やってることは同じで結果が単に$foo[0]に入ってるだけ
$foo[1]~$foo[9] の内容は変わってないはず
ちなみに置き換えてるわけじゃなくて新しい配列を作ってそれを$rとか$foo[0]に入れてる >>961
ありがとうございます
書き方が違うけど処理が同じというとらえ方でいいですか?
"パターン1"
$foo = @(1,2,3,4,5,6,7,8,9,10)
$foo=($foo | sort -prop @{Exp={[Guid]::NewGuid()}})
$foo
"パターン2"
$foo = @(1,2,3,4,5,6,7,8,9,10)
$foo = $foo | sort -prop @{Exp={[Guid]::NewGuid()}}
$foo
パターン1の書き方違いが、パターン2のようなとらえ方でいいでしょうか? >>962
ああ、すまん ( ) は見落としてた
パターン1は単に式を ( ) で包んでるだけだからパターン2と同じと思っていい Get-ChildItem -path d:\ -filter *.mp3 -recurse | foreach {$_.FullName} | sort {Get-Random}
や、
Get-ChildItem -path d:\ -filter *.mp3 -recurse | foreach {$_.FullName} | sort -prop @{Exp={[Guid]::NewGuid()}}
でうまくいきそうです。 ありがとうございました。 >>963
ありがとうございますよくわかりました
パイプで処理がわかれると思っておりましたが、
=で右辺と左辺に分ててる感じなんですね >>964
上手く行って何より
蛇足だけど
> foreach {$_.FullName}
の所は PowerShell 的には
> Select-Object FullName
でもいいかな >>965
他の言語に似せるためか代入文は最優先で解釈されるようになってるみたい
まあよくわからなかったら多少余分でも ( ) を付けといた方があとから見ても誤解されにくいと思う posh-git と GetChildItemColor
でダイブましになった
他にもおすすめあったらおせーて! GetChildItemColorを入れるとシンボリックリンクのリンク先のパスが表示されなくなるのがクソ #test.ps1
param([array]$foo)
echo ('$ARGS[0]' +':'+ $ARGS[0])
echo ('$foo[0]' +':'+ $foo[0])
echo ('$foo[1]' +':'+ $foo[1])
echo ('$foo[2]' +':'+ $foo[2])
PS> .\test.ps1 aaa -foo bbb,ccc,ddd
$ARGS[0]:aaa
$foo[0]:bbb
$foo[1]:ccc
$foo[2]:ddd
PS> .\test.ps1 aaa -bar bbb,ccc,ddd
$ARGS[0]:-bar
$foo[0]:aaa
$foo[1]:
$foo[2]:
PS C:\script>
PS> \test.ps1 aaa
$ARGS[0]:
$foo[0]:aaa
$foo[1]:
$foo[2]:
@引数やパラメータの数、パラメーター名などのエラーをチェックする方法を教えてください。
Aパラメータの区切りをカンマで無くスペースにする方法があれば教えてください。
ググってみたのですが、ググり方が悪いのか、見つからず苦しんでおります >>971
行数制限に引っかかったので分割します。
@は引数〇個、パラメーター名foo、パラメーターfooの数、fooが1個以上(0はだめ)というのをチェックしたいです。
なにとぞよろしくお願いいたします。 >>973
ありがとうございます。
読み解くのに時間がかかりそうですが、
希望のものが書いてありそうです。 そもそもPowerShellの関数(コマンドレット)は空白区切りで引数渡すんだけどね
>>971はカンマ区切りで引数を渡してるんじゃなくて、カンマで作った配列を渡してるだけ
自動変数の$args(配列)はjavascriptでいう残余引数みたいな物
PS> .\test.ps1 aaa -foo bbb,ccc,ddd
名前付き引数 $foo に配列 bbb,ccc,ddd が渡され、未定義の aaa が $args に渡されてる
PS> .\test.ps1 aaa -bar bbb,ccc,ddd
$foo に先頭の引数 aaa が渡され、未定義の -bar と配列 bbb,ccc,ddd が $args に渡される
特にオプションを指定しなければ、複数の引数を設定すれば空白区切りで渡せる PowerShell起動すると毎回更新しろって出るのがウザくて7入れてみたけど起動時の立ち上がりが遅くなって切れそう
しかも結局help云々が毎回出るし
MS頭おかしいんでねーの | where-objectで、条件に引っかかったら0(True)、引っかからなかったら1(False)を返す方法ってありませんでしょうか。
あるサービスの実行状態を知るために、こういうことをしてるんですが、
(Get-Service | Where-Object -Property Name -Match Adobe | Where-Object -Property Status -Match Running).length
1 ←AdobeがRunnningだった
0 ←AdobeがRunningじゃなかった
他に、もっとPowershellっぽい書き方があったら教えてください Ruby の3項演算子みたいなものは無いの?
真偽値となる条件式 ? 真の時の値 : 偽の時の値 (gsv adobe*).status -contains 'running' >>979
[int][bool](Get-Service | Where-Object {($_.Name -Match 'Adobe') -and ($_.Status -Match 'Running')}) 連想配列の参照渡しで
function f([ref]$h) { $h.value }
$h = @{ a = 0; b = 1}
f([ref]$h)
はうまくいくんだけど、引数もう一個増やして
function f([ref]$h, $s) { $h.value; $s }
$h = @{ a = 0; b = 1}
$s = 2
f([ref]$h, $s)
にすると、
f : パラメーター 'h' の引数変換を処理できません。引数には参照型を指定する必要があります。
何が悪いん?ググっても見つけられなくてさっきから悩んでる(汗 >>988
出来た!ありがとう
でもなぜその書き方になるのかわからない(汗 カッコとカンマで引数渡すのはオブジェクトのメソッドの時だけだね
関数はスペース区切りで渡す
これは文法だから理由はない 1, 2 で配列作っちゃうようにしちゃったからねぇ
記法がシェルスクリプトとプログラム言語のあいの子みたいになってるからちょっと直感に反する所がちらほら見え隠れするのはしょうがない >>985
処理の方法が多いことは、可読性が落ちる原因にもなる。
PythonをもちあげてPerlをくさす時に使われたのと同じ論法だよ。 俺がPowerShellを気に入ったのはPerlと同じ匂いを感じたからだ Why did you do that? $VAR/ {} / Weak Intellisense
https://docs.microsoft.com/en-us/archive/blogs/monad/why-did-you-do-that-var-weak-intellisense
The $ in front of variables comes from our design center of being an interactive command oriented shell.
Interactive shells are NOT the same thing as Scripting languages with command interpretors.
Interactive shells are case studies in engineering tradeoffs (another way of saying that is that they tend to be a little quirky).
There is a tension between the needs of a great interactive experience and a great scripting/programming experience.
Time and time again during the course of the project, people would try to make us "choose" between one or the other.
We refused.
We believe that if you work hard enough at it, you can solve the puzzle and provide a great solution for both.
We were absolutely subborn on this point. Time and time again, we were able to succeed with this approach if we travailed long enough. interactive性は'標準で'エイリアスが定義されてることで十分満足してる PerlとPythonは文字に対するencode, decodeの意味が逆。まめな レス数が1000を超えています。これ以上書き込みはできません。