X



PowerShell -Part 4

■ このスレッドは過去ログ倉庫に格納されています
0611デフォルトの名無しさん
垢版 |
2020/10/01(木) 21:05:38.94ID:NSqrZd61
>>610
>New-Item -type HardLink -Name linktest\hardlink -Target linktest\target

5.1と7.0.3で試したけどエラーにならなかったぞ
0612デフォルトの名無しさん
垢版 |
2020/10/01(木) 21:26:37.01ID:tnCBqate
これでどう? (長すぎて切れるかも)

$origCurDir = [System.Environment]::CurrentDirectory
New-Item -ItemType Directory -Path linktest

Push-Location linktest
New-Item -ItemType Directory -Path dir

Push-Location dir # linktest/dir
New-Item -ItemType Directory -Path subdir
Set-Content -Path file -Value "hello"
New-Item -ItemType HardLink -Path hardlink_1 -Value file
New-Item -ItemType SymbolicLink -Path symlink_1 -Value subdir

Pop-Location # linktest
New-Item -ItemType HardLink -Path dir/hardlink_2 -Value dir/file
New-Item -ItemType SymbolicLink -Path dir/symlink_2 -Value subdir

Push-Location dir # linktest/dir
[System.Environment]::CurrentDirectory = $PWD
New-Item -ItemType HardLink -Path hardlink_3 -Value file
New-Item -ItemType SymbolicLink -Path symlink_3 -Value subdir

Pop-Location # linktest
[System.Environment]::CurrentDirectory = $PWD
New-Item -ItemType HardLink -Path dir/hardlink_4 -Value dir/file
New-Item -ItemType SymbolicLink -Path dir/symlink_4 -Value subdir

Pop-Location
[System.Environment]::CurrentDirectory = $origCurDir

Get-ChildItem -Path linktest/dir | Sort-Object -Property CreationTime | Format-Table Attributes,LinkType,Target,Length,Name
0614デフォルトの名無しさん
垢版 |
2020/10/02(金) 13:57:48.64ID:w3BWfVBY
>>613
これを思い出した
********
アメリカのNASAは、宇宙飛行士を最初に宇宙に送り込んだとき、
無重力状態ではボールペンで文字を書くことができないのを発見した。
これではボールペンを持って行っても役に立たない!
NASAの科学者たちはこの問題に立ち向かうべく、10年の歳月と120億ドルの開発費をかけて研究を重ねた。
その結果ついに、無重力でも上下逆にしても水の中でも氷点下でも摂氏300度でも、
どんな状況下でもどんな表面にでも書けるボールペンを開発した!!

一方、ソ連は鉛筆を使った。
0615デフォルトの名無しさん
垢版 |
2020/10/02(金) 14:35:00.30ID:Ck+HovvX
リンクを張ることが目的なのではない
PowerShellの不具合を見つけることが目的なのだ
0616デフォルトの名無しさん
垢版 |
2020/10/02(金) 21:34:24.75ID:ljpWPhwK
誰か英語ができる人 >>612 のテストを添えて「New-Itemでのhardlink/symlink作成に
[Environment]::CurrentDirectoryが影響する」ってタイトルでイシューを立てて欲しい
0619デフォルトの名無しさん
垢版 |
2020/10/03(土) 22:48:38.93ID:7NrhvCrT
バージョン上がって使いやすくなってきたねpowershell
Shellより扱いやすいからmacにもインスコしたわ

コンソールに貼り付けて実行した時に右クリックの貼り付けとctlvの貼り付けで動きが違うのは何で?
0621デフォルトの名無しさん
垢版 |
2020/10/07(水) 01:28:53.25ID:OLUeUK9d
あるファイルを消そうとしたら「このファイルは開かれているため〜」と表示されて消せなかった。
こういう場合、自分はリソースモニターでファイルを開いているアプリを探すんだけど
最近入った現場では管理者以外はリソースモニターを使えないように設定されていて困った。

それで質問なのですが、powershellのコマンドでファイルを開いているアプリを探す方法はあるのでしょうか?
0623621
垢版 |
2020/10/08(木) 03:04:42.09ID:daaVvwfY
>>622
めっちゃ参考になります。っていうかこれでやります。
サンクス!
0624デフォルトの名無しさん
垢版 |
2020/10/08(木) 19:15:35.07ID:zkqa7tbj
試せば判るけど >>622 はプロセスがロードしてるDLLとかのモジュールしか得られないよ
開いてるファイルはプロセスに紐付いてるハンドル取得して一個一個チェックするしかないよ
実装はpowershellじゃかなり大変だからhandle.exeっていうMSが公開してるツール使ったらいいよ
0626デフォルトの名無しさん
垢版 |
2020/10/14(水) 11:09:36.08ID:s64A8YK8
うちの会社は「キッコーマン」のHPが見れません、”コーマン”がフィルターに引っかかるのですw
0628デフォルトの名無しさん
垢版 |
2020/10/17(土) 17:51:59.12ID:2b9DYeQb
職場で「さすがパワーシェラー!」って言われたんだけど
パワーシェルを使う人のことをそう呼ぶものなの?
0633デフォルトの名無しさん
垢版 |
2020/10/24(土) 21:41:19.65ID:1s91cR1z
多次元配列(ジャグ配列ではなく)を1次元配列に平坦化する高速な方法ありませんか?
データ数は100万個くらいです。

@($a | % {$_})

検索したら↑のカッコいい方法が出てきましたが、
私の環境で6秒ほどかかり速度に不満があります。
0634デフォルトの名無しさん
垢版 |
2020/10/24(土) 23:22:07.28ID:ZaC2aARH
パイプとForeach-Object自体が遅いからね
データがオンメモリにあるならforeach文のが速い
0635デフォルトの名無しさん
垢版 |
2020/10/24(土) 23:28:40.40ID:ZaC2aARH
あとは万個の繰り返し処理になるわけだからpowershellで書いたら全体的には当然遅い
対策としては繰り返し部分だけC#に渡すとかだね
0637633
垢版 |
2020/10/25(日) 00:13:47.38ID:orpbcY2p
foreach文にすると0.8秒まで速くなりました!
とりあえずこの方法でやってみます

$b = foreach($x in $a){$x}
0639デフォルトの名無しさん
垢版 |
2020/10/25(日) 20:51:17.25ID:Bltg1B/v
>>633
>多次元配列(ジャグ配列ではなく)を1次元配列に平坦化する高速な方法ありませんか?

なんでジャグ配列ではなく多次元配列なんだろう
0641デフォルトの名無しさん
垢版 |
2020/10/25(日) 23:57:20.55ID:sGr6+tXm
多次元配列のほうがメモリ上で綺麗に配置されている分、高速化の選択肢が多いかもしれないって発想じゃね
0642633
垢版 |
2020/10/26(月) 00:00:33.37ID:R7zaLxag
>>639
ExcelファイルからCOM経由で範囲データを取ってくるとobject[,]になるためです
0646デフォルトの名無しさん
垢版 |
2020/10/26(月) 14:41:24.14ID:RInXL5ja
PowerShellというか.NETの仕様

.NETには1次元配列の要素にアクセスするための専用命令があるので速い
多次元配列の要素にアクセスするにはプロパティみたいなアクセサメソッドを使わなきゃいけないので遅い
0651デフォルトの名無しさん
垢版 |
2020/10/26(月) 17:46:52.74ID:l+r11Fp5
要は根拠もなしに
> 実際には多次元配列の方が遅い
と妄想をほざいてただけって話かよw
0657633
垢版 |
2020/10/26(月) 20:09:14.97ID:5qWbLIDu
>>643
Excelファイルから取得したデータを更に別の処理に使うのですが、その際に1次元で渡す必要があるためです
0658デフォルトの名無しさん
垢版 |
2020/10/26(月) 20:09:30.70ID:/TCFG/M1
実装としては添え字でメモリの位置を計算して参照するだけだから
一次元でも多次元でも原理的には速さは変わらないぞ
0659デフォルトの名無しさん
垢版 |
2020/10/26(月) 20:13:28.15ID:jItJ//Mq
>>656
きみが絶対的に正しいことはスレ住人の総意で共通認識なのだから、もう十分だろう?
そのへんで勘弁してもらないかな。なんなら土下座して謝るよ。
0660デフォルトの名無しさん
垢版 |
2020/10/26(月) 20:17:45.03ID:mujdTIU3
ちゃんとアンカー追えよ
ジャグ配列vs多次元配列が1次元vs多次元配列に化けてるぞ

>>647
>多次元だと倍以上遅いと言う根拠あるの?

「倍以上遅い」なんてどこから来たんだろう
0661デフォルトの名無しさん
垢版 |
2020/10/26(月) 20:28:30.59ID:l+r11Fp5
>>658
>>646によると専用命令があるらしいけど、嘘なのかね?

>>660
ああすまん、脳内で二次元配列 ⇔ ジャグ配列 って思ってたわ
まあ3次元以上なら専用命令とやらがもっと速くないとダメだけど
0664デフォルトの名無しさん
垢版 |
2020/10/26(月) 21:49:29.23ID:AmD6br2D
#2次元配列初期化
Measure-Command {
$i = 0; $array = New-Object "object[,]" 1000,1000
for ($x = 0; $x -lt $array.GetLength(0); $x++) {
for ($y = 0; $y -lt $array.GetLength(1); $y++) {
$array[$x,$y] = $i++
}
}
}

#ジャグ配列初期化
Measure-Command {
$i = 0; $array = New-Object "object[]" 1000
for ($x = 0; $x -lt $array.length; $x++) {
$array[$x] = New-Object "object[]" 1000
for ($y = 0; $y -lt $array[$x].length; $y++) {
$array[$x][$y] = $i++
}
}
}

たしかに初期化の段階でジャグ配列のが速いね
0665デフォルトの名無しさん
垢版 |
2020/10/26(月) 22:09:49.38ID:l+r11Fp5
>>662
ジャグ配列知らんの?
二次元相当のジャグ配列だと2回辿らないとダメだから倍は速くないとトータルで遅くなるでしょ
0671デフォルトの名無しさん
垢版 |
2020/10/27(火) 15:37:54.18ID:az6RTKF7
処理系の実装に寄るけど、うまくインデックスを張れば
速度的には同等になるはずだけどな
0672デフォルトの名無しさん
垢版 |
2020/10/27(火) 19:29:05.55ID:k9DNZwa6
>>671
どういう理論なんだ?
ランダムアクセスだとジャグ配列は次元毎にメモリーアクセスして辿らないとダメだけど多次元配列ならインデックスの計算してその場所にアクセスするだけだから多次元配列の方が速い
シーケンシャルアクセスだとアクセスの多くは最後の次元のアクセスだから毎回インデックスを計算する多次元配列よりジャグ配列の方が速いと思う
まあめっちゃ最適化して多次元配列を1次元配列に展開するようなコードにまで落とせたら多次元配列の方が微妙に速くなるかも
0673デフォルトの名無しさん
垢版 |
2020/10/27(火) 19:52:31.91ID:Sd8akiyh
なんにせよ多次元配列を1次元配列に高速に平坦化する方法分からないんだろ
グダグダスレ引き延ばしておきながらなw
0677デフォルトの名無しさん
垢版 |
2020/10/28(水) 19:54:09.10ID:RpzUgl/d
>>674
>@($a)
PSってこんなオチが多いね
$aって打てば全部列挙されて出てくるんだからあれれとは思うんだけどさ
0678633
垢版 |
2020/10/29(木) 21:32:08.09ID:/oXwNFXj
>>674
返信遅れてすみません。
0.2秒まで速くなりました。

シンプルかつナンバーワンですね
目からウロコでした。
0679デフォルトの名無しさん
垢版 |
2020/10/29(木) 23:08:28.85ID:u3CTd5OP
>>677
こういうトリッキー系?は趣味PGならいいんだけど
業務PGに実装するには躊躇するんだよなあw
0681デフォルトの名無しさん
垢版 |
2020/10/30(金) 08:08:54.65ID:xvehW8+X
PowerShell使うならほぼ常識、てか知らないと辛いレベル
そもそもPowerShell自体が色々トリッキーな動作するし、特に配列周り
0682デフォルトの名無しさん
垢版 |
2020/11/02(月) 13:12:42.29ID:cgiVh2xg
$a = [Object[,]]::new(3,3); $a.Rank は 2

$b = $a; $b.Rank は 2
$b = & { $a }; $b.Rank だと 1
$b = $a + @(); $b.Rank でも 1
もちろん $b.Length はどれも 9

$b = $a が特例のように思えてきた
どうしてこうなるのかきちんと理屈が知りたい
0683デフォルトの名無しさん
垢版 |
2020/11/02(月) 14:39:03.01ID:Q6ZeZ8N8
配列での foreach の使用 (C# プログラミング ガイド)
https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/arrays/using-foreach-with-arrays

多次元配列の場合、右端の次元のインデックスが最初に加算されていき、次にその左の次元、またその左、というような方法で各要素がトラバースされます。

int[,] numbers2D = new int[3, 2] { { 9, 99 }, { 3, 33 }, { 5, 55 } };
// Or use the short form:
// int[,] numbers2D = { { 9, 99 }, { 3, 33 }, { 5, 55 } };

foreach (int i in numbers2D)
{
System.Console.Write("{0} ", i);
}
// Output: 9 99 3 33 5 55
0684682
垢版 |
2020/11/02(月) 17:29:09.65ID:cgiVh2xg
明示的な foreach の使用は興味がないなあ
$b = $a も $b = & { $a } も $a を $b に代入するのに
なんで結果が違うのかが知りたい
0685デフォルトの名無しさん
垢版 |
2020/11/02(月) 17:46:27.91ID:O692h/lZ
最初のやつ以外はシンプルな代入じゃなくて演算してるから、演算の結果が一次元配列になっただけじゃないの
0686682
垢版 |
2020/11/02(月) 17:50:23.99ID:cgiVh2xg
$b = & { $a } も演算?
具体的にどういう演算になるのかわからない
0687デフォルトの名無しさん
垢版 |
2020/11/02(月) 17:54:46.38ID:Razdsa9H
>>682
>$b = & { $a }; $b.Rank だと 1
>$b = $a + @(); $b.Rank でも 1
この2つは$aがそれぞれ評価されて1次元になって$bに代入されてる
$b = & { $a }
の場合$aの前にカンマを入れれば型は保たれる
$b = & { ,$a }
PowerShellの謎仕様
0688デフォルトの名無しさん
垢版 |
2020/11/02(月) 18:05:40.51ID:Razdsa9H
おそらくスクリプトブロックを通過するときと
右辺や左辺に置いて演算するとき
それぞれ1次元に変換されてしまう仕様みたい
0689デフォルトの名無しさん
垢版 |
2020/11/02(月) 18:07:36.92ID:O692h/lZ
>>686
起動演算子にスクリプトブロックを渡してるんだから演算でしょ
スクリプトで
$a
とだけ書くと$aが評価されて左上から順に9行分の出力が得られる
$b=&{$a}はその出力の代入になってる
0690682
垢版 |
2020/11/02(月) 18:14:48.39ID:cgiVh2xg
じゃあやっぱり単純な代入 $b = $a だけが特別で
それ以外は配列が展開されるってことか
理解した

>>687
& { $a } だと配列 $a が展開される
& { ,$a } にすれば配列の配列 ,$a が展開されて配列 $a がそのまま渡される
0691682
垢版 |
2020/11/02(月) 18:50:05.02ID:cgiVh2xg
あれ違うな
単純な代入だけでなく Comma operator も特例になるのか
0692デフォルトの名無しさん
垢版 |
2020/11/02(月) 18:58:29.51ID:WQUINiFK
>>691
特例だとか自分勝手な解釈をする癖を直さないと、他人とのコミュニケーションで苦労するぞ(主に周囲の人間の方が...)。
自分が既に頭の中に描いているイメージに合わせて無理に解釈方法を寄せていくのではなくて、本来理解すべき仕様の方に自分の中の理解を修正して近づけていく方がいいぞ。
0694デフォルトの名無しさん
垢版 |
2020/11/02(月) 19:59:31.61ID:D4NZ1UY1
>>692
TPO をわきまえられずトンチンカンな御高説垂れる人も、他人とのコミュニケーションで苦労するぞ(主に周囲の人間の方が...)。
0695デフォルトの名無しさん
垢版 |
2020/11/02(月) 20:30:51.76ID:Razdsa9H
>>690
原理的にはジャグ配列にして空評価させて返すで合ってると思う
恐らく処理系のソース読み込まないと判らないよ
配列返す関数作る時も同じ方法
0696682
垢版 |
2020/11/02(月) 20:44:58.19ID:cgiVh2xg
,$a は Comma operator で1要素の配列を返すけれど
その時に $a は展開されずに2次元配列のまま
これは単純な代入と同じ扱いだよね
0698デフォルトの名無しさん
垢版 |
2020/11/02(月) 22:48:01.97ID:O692h/lZ
ウザかろうと思って特例云々につっこむのやめたけどやっぱり書くわ
代入は代入でしかなく特例も何もない
いつだって右辺の値をありのままの型と値で代入するだけ
$b=&{$a} というのを代入として認識するからおかしくなる
$b=$a.Rank と書いたら$bは数値になるわけだけど、代入したから数値になった!とは思わないでしょ
あくまで.Rankを評価した結果が数値になって、その数値を$bに代入したに過ぎない
$b=&{$a} も &{$a} の評価結果が一次元配列になる仕様なだけで、代入が何かの法則性に寄与している訳ではないし、一次元配列になるという一貫したルールや思想があるわけでもない
0699682
垢版 |
2020/11/03(火) 00:15:03.20ID:Da50zhuo
operand を展開してから operator にわたすんじゃなくて
operand をそのままわたして operator が展開したりしなかったりする
たぶん理解した
0700デフォルトの名無しさん
垢版 |
2020/11/03(火) 08:59:33.05ID:HUEo3Cdu
>>682 の$b = $a は$aの参照を$bに代入している

$a = [Object[,]]::new(3,3)
$b = $a
$b[0,0] = 1
echo $a[0,0] #=> 1

$b = & { $a } は { $a }というスクリプトブロックを実行して戻り値を代入する
{ $a } の意味は >>697 を見ろ
0701デフォルトの名無しさん
垢版 |
2020/11/04(水) 10:50:57.08ID:ZJcGuVz6
>>694
初学者が変な誤解すると二度と修正する機会ないからな
みんな巡り巡って自分が被る迷惑を未然に防ごうと必死なわけよ
0703デフォルトの名無しさん
垢版 |
2020/11/07(土) 21:29:59.64ID:AAgSLehy
こんなシェルを書きました。

function get_stop_code {
$hoge=(Get-Content stop_code.txt)
}

while ($true) {
get_stop_code
Write-Output $hoge

}

シェル実行中に、stop_code.txtの中身を書き換えても
get_stop_codeがファイルの中身を拾ってくれません

いろいろ試したら、こうしたらうまくいきました。がすっきりしません。

function get_stop_code {
$hoge=(Get-Content stop_code.txt)
Write-Output $hoge
}


while ($true) {

$stop_code=(get_stop_code)
write-output $stop_code
}


get_stop_codeがファイルの中身を、while ($true)の中でうまく拾ってくれる
書き方を教えてください。
0705デフォルトの名無しさん
垢版 |
2020/11/08(日) 02:53:16.74ID:mlfH60EQ
スコープの話だと思うよ
関数の内側で変数を書き換えてもローカルスコープ内の変数の更新にしかならないので、関数から戻ったら値は書き換わってない
関数を次のように書き換えて明示的にスクリプトスコープの変数を更新してやればいい

function get_stop_code {
$script:hoge=(Get-Content stop_code.txt)
}

PSのスコープって特殊で悩ましい
特にループの初回、ほかの言語みたいに未宣言の変数だぞとエラーになってくれればまだいいんだけど、変数が作られて親からも見えちゃうから混乱する
0706デフォルトの名無しさん
垢版 |
2020/11/08(日) 08:09:56.71ID:0BM2Z5Uf
おれも一瞬ではなく数分、>>703の問題がわからなかった
とりあえず頭にSet-StrictMode -Version Latestを付けとけばエラーにはなる
0707デフォルトの名無しさん
垢版 |
2020/11/08(日) 10:11:33.41ID:vf10kFcr
>>705
ありがとうございます。
>関数の内側で変数を書き換えてもローカルスコープ内の変数の更新にしかならないので、関数から戻ったら値は書き換わってない
というのは、

>>703だと、
同じシェル内にある$hogeであっても、

 @get_stop_code関数内の$hoge
 Awhile ($true)内にある$hoge

の2種類があり、
while ($true)内で、get_stop_code関数を実行しても、
@の$hogeしか書き換わらないから、求める結果が得られない。

って事でしょうか。
0708デフォルトの名無しさん
垢版 |
2020/11/08(日) 12:20:50.04ID:mlfH60EQ
そんな感じ
関数はローカルスコープを作る
whileの方はその外側にあたるから親スコープになる
ちなみにPSではwhileブロックはローカルスコープを作らないのでスクリプト全体のスコープと同じ
0709デフォルトの名無しさん
垢版 |
2020/11/08(日) 14:40:55.27ID:vf10kFcr
>>708
ありがとうございます。
スコープですね、勉強になりました。

きっと、しっかり理解すれば便利な仕様なんでしょうが、
初学者にとっては罠でしかありませんね・・・こういうの・・・。
■ このスレッドは過去ログ倉庫に格納されています

ニューススポーツなんでも実況