PowerShell -Part 5
レス数が1000を超えています。これ以上書き込みはできません。
パイプやリダイレクトが微妙
結局 cmd /C を使うはめに 未経験新卒で入社してからLinux関連の開発しかしてこなかった俺がふとpowershellの勉強始めてるんだが、なかなか慣れんわ
まあ出来ることから地道に使い込んでいくしかないか… あるオブジェクトのプロパティ(数や名前は不明)を全て取得して
別に新規作成するPScustomObjectのプロパティとして設定したいのですか
どのようにすれば実現出来ますでしょうか? 補足です。
あるオブジェクトのプロパティの値は必要ありません。
新しいPScustomObjectのプロパティの値は別のものをセットします。 get-memberでプロパティでフィルタしてadd-memberかな? アナル。
後からオブジェクト追加ですね。
初心者なのでPScustomObject作成時にプロパティ指定しか頭になかったです。
サンクソ。 >>7
linuxだけど俺も周りもPowerShellしか使ってねえわ まあ部署で統一図ったってだけだけどな
linuxのログインシェルにPowerShellはまだまだマイノリティ Select-Objectでプロパティを取り出す際に@{name=〜;expession={〜}}
って指定方法があると思いますが、
@data=@{"key1"=@(1,2);"key2"=@(3,4)}
という配列を値に持つハッシュ@dataから
1,3;2,4
と言う風にデータを取り出したいのですが
(各配列の要素0から順番に)
@data|Select-Object @{name="out";expession={ ($_.key1 + "," + $_.key2) -join ";"}}
だと
1;2;,;3;4
になってしまいます。
1,3;2,4
と取り出すにはどうすれば良いでしょうか? >>16
う〜ん。これだと
1,2;3,4
と出力されてしまいます。
説明が悪かったです。
配列毎に順番に出力ではなく、
全配列の若い要素から順番に出力です。
配列Aの要素0,配列Bの要素0;
配列Aの要素1,配列Bの要素1;
配列Aの要素2,配列Bの要素2;
・
・
と言うふうに、
$dataの場合は
1,3;2,4
と出力したいのです。 スクリプト内の、Start-Processで起動したプロセスが、「別の」プロセスを起動します。
この「別の」プロセスのPIDを取るに、確実性のある方法ってありますでしょうか。
具体的に申し上げますと、TeratTermマクロの実行ファイル(以下、ttpmacro.exe)を、Start-Processで呼び出すと
ttpmacro.exeが、Teraterm本体を呼び出します。
以下の、@でttpmacro.exeのPIDは取れるのですが、ttpmacro.exeが呼び出した
Teraterm本体のPIDは取れません。
現状Aの方法、ttpmacro.exeをStart-Processで起動→3秒待ち(起動待ち)→Get-Processで最新のTeraterm本体のPIDを取る
で間に合ってはいるのですが、不確実性があります。
これの対処に、確実性のある方法があったら教えてください。
Get-ProcessのStart-Timeが〇秒以内の場合〜というのも考えたんですが、
やっぱり不確実があるのでまだ導入はしてません。
よろしくお願いいたします。
以下ソースコード一部抜粋しました。ご参照ください。
$ttl_macro=Teratemマクロのファイルパス
$ttpm_bin="C:\Program Files (x86)\teraterm\ttpmacro.exe"
@$ttl_pid=(Start-Process -PassThru -FilePath $ttpm_bin -ArgumentList "/V $ttl_macro $log_full_path")
sleep 3 #Teraterm本体の起動待ち用。
A$ttp_pid=((Get-Process -name "ttermpro") | Select-Object id,StartTime,name | Sort-Object -Property Starttime | Select-Object -Last 1) >>17
Keyは固定でいいのね
なら
($data.Key1.GetLowerBound(0) .. $data.Key1.GetUpperBound(0) | %{ $data.Key1[$_], $data.Key2[$_] -join ',' }) -join ';'
でいいかと >>19
て、天才か…!?
ありがとうございます。m(_ _)m
しかし、書いてる内容がわからん過ぎて自分で応用出来そうにないな… >>20
要するに配列の添字を0, 1, 2, ...のように変えながら
$data.Key1[添字], $data.Key2[添字] -join ','
を実行してそれらを ';' で繋いでるだけ >>18
そういう場合小プロセスのppidを調べる
下のコードは未確認
Get-CimInstance Win32_Process -Filter "ParentProcessId = $pid" >>22
ありがとうございます。
超絶ばっちり拾えました。
Get-CimInstance
これいろいろ拾えるみたいですんごい便利そうですね。
ありがとうございました。 Windows Terminal について質問、コンソールウィンドウをキーボード操作で編集モードにする方法ってある?
PowerShellでできそうかな? >>14
Ruby で作った
hash = { 1 => [ 11, 12, 13 ], 2 => [ 21, 22, 23 ] }
# zip で、行列の転置・transpose で、
# 2次元配列・[[11, 21], [12, 22], [13, 23]]
result = hash[ 1 ].zip( hash[ 2 ] ).
map{ |ary| ary.join( "," ) }.join( ";" )
puts result #=> 11,21;12,22;13,23 サーバ運用などにpowershellのおすすめの参考書教えてください
プログラムの基礎的な内容はおさえていて、vbsで簡単なスクリプトは作れるレベルです。 今のPowerShellって実は既に非推奨なんで、MSの方針に従うなら今出ている参考書はほとんどお勧めできないってことになる
最新のPowerShell Coreについてはまあ参考書はほとんどなくて、ググってみりゃわかるがお勧め以前に参考書は国内では一つしか出ていないから選択の余地はない pwsh(core)ってやつ
チュートリアルならMSのサイト、get-helpでunix系のman相当のマニュアル読める
結構快適だよ でもわざわざpsの最新版入れ直す所なんて希だから知ってて損はない ありがとうございます
今過渡期なんですね
Windows Server2012R2とかまだ使っているので
coreはまだ早い気がしました。 基本知識はPowerShell7系とWindows PowerShell(Ver5.1)は一緒だから若干古い書籍でも役に立つ
PowerShell6以降の機能は別で勉強すればいい
それにPowerShell7で5系との互換性はかなり良いから上記資料で役に立ちそう
過渡期でも勉強しといて損は無い >>34
他人の作ってくれた関数をコピペして、少しずつ変えながら色々試せばいい Get-ChildItemで得た音声ファイルのオブジェクトに
Get-ChildItemが返したオブジェクト
├Name(ファイル名)
├FullName(フルパス名)
:
└Audio(追加の音声プロパティオブジェクト)
├Channels(2とか6とか)
├SampleRate(44100とか96000とか)
:
って感じで音声プロパティを追加して
Get-ChildItem audio.flac | Add-AudioProp | Format-Table -Property Name や
(Get-ChildItem audio.flac | Add-AudioProp).Audio | Format-Table -Property SampleRate,Channels
なんかはうまく行くんだけど
Get-ChildItem audio.flac | Add-AudioProp | Format-Table -Property Name,SampleRate
みたいにオブジェクトをまたがる表示ができない。どうすりゃいいん(´・ω・`)
追加の音声プロパティをName,FullNameなんかとベタに並べるしかないんですかね Get-ChildItem audio.flac | Add-AudioProp | Format-Table -Property Name,@{n="SampleRate";e={$_.Audio.SampleRate}} >>38
バッチリです!ヘルプにある
> 集計プロパティを作成するには、ハッシュ テーブルを使用します。有効なキーは次のとおりです。
ってこれの事だったのかぁ。nとかeってNameやExpressionの頭文字ですよね。頭1文字でもいいのか…
力技で一オブジェクトに集めるパイプ関数挟んでしのいでたけど取り外す事ができました About calculated properties
https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_calculated_properties
The hashtable keys need not be spelled out as long as the specified name prefix is unambiguous.
For example, n can be used in lieu of Name and e can be used in lieu of Expression. >>38
それって最後は
ft Name,Audio.SampleRate
じゃだめなの?
省略表現て意味じゃなくてAudio.SampleRateプロパティでなら取得出来るって意味で >>41
Audio.SampleRate ←値が空。"Audio.SampleRate"って名前のプロパティ探そうとして失敗か
Audio[SampleRate]やAudio["SampleRate"] ←値どころか項目名すら表に出てこない
$_下にないプロパティはハッシュテーブルで名前(任意のラベル名)と値を定義しないとダメっぽい 外部コマンドの標準入力にバイナリファイル渡したいけどPowerShell直接はムリ? コマンドは対応してるけどPowerShellが受け付けてくれない
PowerShell> sox --info - < .\audio.flac
演算子 '<' は、今後の使用のために予約されています。
PowerShell> Invoke-Expression "sox --info - < .\audio.flac"
Invoke-Expression : 演算子 '<' は、今後の使用のために予約されています。
PowerShell> Get-Content .\audio.flac | sox --info -
(返ってこない。メモリ消費が物凄い事に。Ctrl+Cでは終われる。)
PowerShell> cmd /c sox --info - < .\audio.flac
演算子 '<' は、今後の使用のために予約されています。
PowerShell> sox --info - `< .\audio.flac
(外部コマンドから見たら"<"と".\audio.flac"の引数2つで標準入力にならない)
PowerShell> cmd /c sox --info - `< .\audio.flac
PowerShell> cmd /c "sox --info - < .\audio.flac"
→OK PowerShell関係なく、そもそも標準入出力ってバイナリデータ扱えるものなの? Start-Process -RedirectStandardInputでなんとかなんじゃね こんな感じか?試せる環境がないので分からん
Start-Process sox -ArgumentList "--info" -RedirectStandardInput ".\audio.flac" >>46
たまには頑張って調べてみた。
Get-Content .\0321.wav | sox --info -
soxコマンドはパス通してから、これで行けた。 >>50
ダメだ、イケてない・・・
正しくわたってない、無かったことにしてください。
ごめんなさい。調子ぶっこきました。 >>49
Start-Process sox -ArgumentList "--info","-" -RedirectStandardInput .\audio.flac
で実行できた。ただ、これだと別ウィンドウで実行されて(-Waitを付けても)すぐ消える
-NoNewWindow付けるとコンソール出力されて直接実行の目的は果たせた。ありがとう
ただ、別プロセスのせいか$capture = Start-Process .(ryで出力キャプチャできない
-RedirectStandardOutputでファイル出力はできるけど
出力キャプチャは今んとこcmd経由しか思いつかないな・・・
>>51
Get-Contentはファイル読んでPSオブジェクト作るからwavみたいな巨大ファイル喰わせると
消費メモリがとんでもない事になってよろしくないみたい。
command1 | comannd2でパイプで繋ぐのもそうなのかも(?)
PowerShell使い始めたばかりでまだ仕組みわかってないのでアレですが パワーシェルとWindowsバッチってどう違うの? PowerShellはシェル
バッチはコマンドを連続して実行すること
PowerShell上でバッチを動かすことも可能 powershellは起動時のロードがクソ遅いからログインスクリプトとかで迂闊に使えない
vbsとバッチは相変わらず超速 1000台規模のネットブートシステムでスタートアップ・ログオンスクリプト共々PowerShellで組んでるけど遅いときなんて一度も無いな
PowerShellの起動が遅いと感じたのはWindows7の頃が最後だな そりゃそんなんじゃ起動の遅さなんて気にならんだろ。 >>53
PowerShell Teamのブログに今月こんなのが出た
PowerShell Team 2021 Investments
https://devblogs.microsoft.com/powershell/powershell-team-2021-investments/
この中に
Improve native command experience
One of the goals of PowerShell 7.1 was to improve the shell experience. This includes using native commands within PowerShell more intuitively like other shells.
って節があるのだけど、そこで挙げてる3項目の一つが
PowerShell currently treats all output from native commands as text. This means that binary output from commands is converted to text, resulting in data loss, even if the intent is to redirect that output to a file or another command that accepts the binary output.
バイナリ出力が扱えるようになればバイナリ入力もできるようになるだろう
もしかすると年内に実現するかもしれない
やっと他のシェルを経由しなくてもすむようになる
それにしても今頃こんなところに手を入れるなんて遅すぎるとしか言いようがない カレントディレクトリにあるスクリプトファイルを
フルパスでなくファイル名だけ指定しても実行できないのはどうしてでしょうか? セキュリティ上の配慮だと初期バージョンの頃から明言されていた linuxやって検索パスにカレントディレクトリ"."を入れてないと実行出来へんので違和感無し。
検索パスにカレントディレクトリを含めるのはセキュリティ上非推奨やしな。 ありがとう
なんとかマイクロソフトのページ検索できた
確かにセキュリティの機能としてそうなってるって書いてた >>58
> 1000台規模のネットブートシステム
これってWindowsをディスクレスでネットワークブートできるってこと? #!/usr/bin/env ruby
puts RUBY_VERSION #=> 2.6.6
Linux でも、こういう内容の、a.rb ファイルを作って、
a.rb と実行してもエラー。
そもそも、bash で入力補完もできないし
./a.rb なら実行できるし、
./a と打っても、入力補完も働く
シバンに、/usr/bin/ruby ではなく、env を使っているのは、
anyenv/rbenv で、複数のバージョンを切り替えているため、
/usr/bin/ruby は存在しない PowerShellだろうがbashだろうがzshだろうがtcshだろうが
コマンドの検索パスに . が入っているかどうかだけの問題
入っていればカレントディレクトリの実行ファイルがパスなしで動く
PowerShellの場合でも$env:PATHに入れてやれば動く
入ってなくても動くcmd.exeとかcommand.comが特殊なだけ $ping_result=(Test-Connection -count 2 8.8.8.8)
$ping_result #@
Source Destination IPV4Address IPV6Address Bytes Time(ms)
------ ----------- ----------- ----------- ----- --------
DESKTOP-E1... 8.8.8.8 8.8.4.4 32 3
DESKTOP-E1... 8.8.8.8 8.8.4.4 32 3
$proc_result=(Get-Process)
$proc_result #A
Handles NPM(K) PM(K) WS(K) CPU(s) Id SI ProcessName
------- ------ ----- ----- ------ -- -- -----------
547 32 19840 10308 2.72 11144 1 ApplicationFrameHost
123 8 1564 1552 3404 0 armsvc
@とAの後ろに、| select-objectを付けると
@は、TAB補完で IPV4Address、 IPV6Address だけが出てきます。
Aは、Handles〜ProcessNameまで全部出てきます。
Get-memberしても、列タイトルと名前が一致しません。
例えば、$ping_resultのTime(ms) はReplyTimesという名前で値が入ってます
ほかのコマンドでもちらちらこういう、「コマンドレット実行したときに表示されるタイトルと、実際に.プロパティ名で取る際の名前が違う」
というのがあります。こういう違いって何か明確な区分けがあるんでしょうか?よろしくお願いいたします。 出力の仕様は書式設定ファイルで定義されている
ファイルの中では表示したいプロパティの名前を指定してもいいし、結果を計算するスクリプトブロックを指定してもいい
about_Format.ps1xml
https://docs.microsoft.com/ja-jp/previous-versions/windows/powershell-scripting/hh847831(v=wps.640) 無限ループにして走らせておきたいスクリプトがあって
コマンドプロンプトの画面で実行させてるけど邪魔
見えないようにして、かつ終了もさせられるようにするにはどうしたらいい? >>72
タスクで別ユーザで実行させとけばいいんじゃね ウィンドウの位置とサイズを固定させる用途だから、ユーザが自分でないと タスクトレイに常駐させるのがスマートだけど
それのイベント拾う非表示のウィンドウが必要なんだよな
作り方は他の言語と同じだから全省略するね pwsh --helpで出てくる公知なことを隠す必要なんてないと思うが…
スクリプトの実行ポリシーはガッチガチだし、ドキュメントどころか--helpすら読まない奴はスクリプトキディにもなれんだろうから安心 [System.DateTime]::Now.kind
@これを読むとすると
system.date.timeクラスの、nowメソッドのkindプロパティでいいでしょうか。
違ってたら読み方?教えてください
Aこういうのってどっかに一覧があるんでしょうか
Bこういうのを使うとPowershellらしい、新しい書き方になると思ってるんですが
実際の所はどうなんでしょうか?使う人のほうが少ないんしょうか。
例えば、[System.DateTime]::Nowであれば、Get-Date と同じものなので、
わざわざこういう書き方をしないで、コマンドレットの読みやすい表記を使う人のほうが多いんでしょうか >>80
System名前空間のDateTime構造体の静的Nowプロパティが返す(System.DateTime型の)オブジェクトのKindプロパティかな
https://docs.microsoft.com/ja-jp/dotnet/api/system.datetime >>82
プロパティのみのクラスオブジェクトなんじゃね powershellのタブ補完はディレクトリ末尾にバックスラッシュを付与するので、多くのWin32アプリが引数をうまく受け取れないってのは既知? スラッシュならともかくバックスラッシュなら処理できるんじゃね ディレクトリの場合は末尾にバックスラッシュ補完してくれるほうがありがたいが、
アプリは引数のディレクトリ末尾にバックスラッシュあるとうまく受け取れないん? あってもなくても正しく動くように全員が実装している必要がある 職場でPowerShell書いたらバッチでいいと言われたよ 新しく作るスクリプトに関してはもうバッチ使わないで欲しいよな 標準ではps1の実行権限ついてないから配布する場合はちょっと面倒なんだよね 1行batとの2ファイル構成が楽でいい
先人はよくもbatなんかを使い続けてきたものよな インストールマニュアルとセットにして、正攻法で使って貰うのが一番だな ネット経由で持ってきたファイルだと、batファイルも実行不可能なのな
よくできてる むしろガチガチに管理してくれれば個別にスクリプト実行なんてしなくて済むのに batで済む事はbatが無難
済まない事はps1よりもexeが無難 >>101
ZoneIDのセキュリティブロックのことなら、イントラネットや信頼されたサイトだと問題ない 自分の別のPCからteamsのファイル共有で持ってきただけなんだけどね -Scope CurrentUser なら権限いらないんじゃね PwerShell はファイル行数を取得しようとうっかり wc -l ファイルパス を呼ぶと延々と戻ってこない > Get-Command wc
Get-Command : 用語 'wc' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されま
せん。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してく
ださい。 >>109,110
失礼。 書き間違えた。wc はGit for Windowsに付属のwc.exeのこと。
正しくは以下のとおり。
cat ファイルパス | wc -l
catが遅いのかパイプが遅いのか両方なのか。 cygwinやmsysだとか、c:直下に入りたがるintel系のコンパイラとか、あちこちにパス通してると遅くなった気がする
ハッシュとかしてないんだろうか?する方法あったら知りたい とりあえずパスの先の方に移してみたら、win/unix-likeで同名コマンド結構あるので衝突気にしないならだが >>112
cat はcat.exeじゃなくてGet-Contentのaliasでした
wc -l ファイルパス は普通に速いからwc.exeの問題でもない
よって Get-Contentまたはパイプの問題ってことになりそう Get-Contentのcatだけじゃなくて cat.exe も遅いのか判断しようにもリダイレクトやパイプが関係してきて計時できない concatenateの略だということはもう忘れられている >>114
gcは何も言わなければStringのObject[]を返すと思うので、ストリームを期待しているだろうwcの移植に渡すのは気持ち悪い感じがするぞ(そのwc.exeを持ってないので推測だが
-bytestreamやら-rawやら色々オプションあるので、適切なのを探そう
パイプのバッファリングもstdbufに頼るlinuxよりは柔軟なので、もし駄目ならそっち方面調べてみて catは猫被ってるからな
(cat .profile)[-1] >>120
一部のシェルではコマンドとコマンドパスの対応をハッシュテーブルで管理して高速化を図ってるものがある
なのでサーチパスを追加したりコマンドを追加したらrehashコマンドでハッシュテーブルを再構築する必要がある
って話じゃね? うちは6885行のtxtでGet-Contentもcat.exeも体感差はないな。しかしPSのパイプは遅い
PS> foreach ($i in (1..5)) {(Measure-Command { Get-Content hoge.txt | wc -l }).TotalMilliseconds}
2959.9704
3016.5222
3007.6643
3010.2928
3009.264
PS> foreach ($i in (1..5)) {(Measure-Command { cat.exe hoge.txt | wc -l }).TotalMilliseconds}
2908.5588
2900.6436
2905.2317
2962.6119
2895.1269
PS> foreach ($i in (1..5)) {(Measure-Command { wc -l hoge.txt }).TotalMilliseconds}
62.3373
61.1564
78.0376
62.6787
61.2903 bash> time (cat hoge.txt | wc -l)
6885
real 0m0.047s
user 0m0.060s
sys 0m0.030s
bash> time wc -l hoge.txt
6885 hoge.txt
real 0m0.016s
user 0m0.030s
sys 0m0.031s そもそもそのwc.exeってファイル引数とか取ってくれないの? PowerShellでファイルの行数を知りたいなら
Get-Content ファイルパス | Measure-Object -Line
Measure-Object
https://docs.microsoft.com/ja-jp/previous-versions/dd315251(v=technet.10)
-Line
入力オブジェクトの行数をカウントします。 まさか行数を数えたいだけってオチ?
>>126
行数だけなら単に.count属性見ればいいのではないかと
(cat file).count あと一行毎に読み込んで処理するような作業でなければ、-readcount を大きく取れば比例して速くなるかと 完全に同じ物かは分からんが、一般的なwcコマンドはファイル引数取るね
わざわざgcでメモリに読み込んで渡すという奇怪なことはしなくていいと思う
行じゃなくて単語を数えるなら-Delimiterでよしなに分割してCount 属性見るとか
ただ、生gcで全部メモリに載せて属性見るのはスケーラブルでない事に注意 -Delimiterに空白扱いしたい文字を渡すだけではちゃんと連続スペースを圧縮してくれるかとか怪しいので、やめといたほうがいいか
せっかくwc.exeがあるんだから任せるのが無難 オワコン利用者が宗教がかってくるのはどんな分野でも似た感じだね HTMLファイルを[xml]に変換して $obj.html.bodyとか参照したいんですが、
↓のサイトで紹介されてる方法
https://win.just4fun.biz/?PowerShell/HTMLのtableタグをスクレイピング
$obj = [xml](Get-Content ファイル名)
この方法ではタグが対応してないとエラーが出てしまいます。素のHTMLなので当然なのですが。
タグが対応してないHTML前提で何か良い方法ありますか。 Powershellで時間だけの計算の方法を教えてください。
$s=((New-TimeSpan -Hours 50 -Minutes 35) + (New-TimeSpan -Hours 1 -Minutes 25)).TotalSeconds
$ts =[timespan]::FromSeconds($s)
("{0:hh\:mm\:ss}" -f $ts)
ググった結果ここまではいきついたのですが、24時間を超えると、桁が日に上がってしまいます。
24時間を超えた場合でも、25:00や、123:35のようにする方法を教えてください。
また、もう少し楽な書き方Excelライクに、10:15 + 20:45 = 31:00、みたいな楽な書き方があったら教えて下さい。 >>129
7z -e -so 2021-04-01.log.zip | wc -l
みたいな事もやりたいのかも。わざわざパイプにしてるって事は
それにしてもPowerShellは数字で始まるコマンドはそのままじゃダメなのか
&7zだとイケるけど…癖のあるシェルですな >>134
MSDNのTimeSpan構造体を調べてみるといいですよ
時単位の出力はTotalHoursプロパティです $ts = [timespan]'10:15' + [timespan]'20:45'
'{0:00}:{1:00}' -f $ts.TotalHours, $ts.Minutes
こんな感じ >>136
>>137
ありがとうございました。
最終的にこんな感じになりました。
$TimeSpan = [timespan]::new(10,15,0) + [timespan]::new(24,45,0)
'{0:00}:{1:00}' -f $TimeSpan.TotalHours, $TimeSpan.Minutes 質問したいんだけど、だれか教えて下さい。
外部アプリによるリネームの追跡をしたいんです。
リネームをする外部アプリで、リネームされたファイル名を拾いたいんです。
詳細
https://qiita.com/mtujikawa/questions/a0b4b36bc91585388cf2
だれか教えて下さい。 >>139
windows 名前の変更 監査
でぐぐるといくつか出てくるよ vbs速いって言うけどUTF8扱うようになる(ADODBでゴニョゴニョ)と
powershellが逆転するね $ts = [timespan]'0:15' + [timespan]'0:40' ; '{0:00}:{1:00}' -f $ts.TotalHours, $ts.Minutes
01:55 数値を強制的に2桁にする方法ですが、
3桁以上は上位2桁、1桁の場合は右詰めで0追加
とするためにはどうすればいいでしょうか?
整数以外の入力は考えなくて大丈夫です
(例)
12345 → 12
67 → 67
8 → 80 if文で分岐して10をかけたり割ったりするだけじゃだめなんですか? 12345,67,8|%{[math]::floor($_/[math]::pow(10,[math]::floor([math]::log10($_))-1))} 無条件に最後に0を付けて左から2桁取ればいいのでは その方が簡単だな。146は数値計算で済ませる思いつき #/bin/sh
result=21
result2=3.1415
echo "$result * 10" | bc | cut -c 1-2 # 実行結果:21
echo "scale=5; $result2 * 10" | bc | cut -c 1-2 # 実行結果:31 中古シェルだとたかが数値計算すらbcなんてコマンドをわざわざ使わなきゃいけないのか
しかも結果が文字列ってアホすぎ bashって外部コマンド使わずに純粋にシェルの機能だけだとまともな事出来ないの? 12345,67,8|% {($_ * 10).ToString().SubString(0,2).ToInt32($null)} テキストファイルを読み込んで置換したりしているのですが、改行コードがマッチしません
function test($file){
$content = Get-Content -Encoding UTF8 $file
$content = $content -replace "`n", "HOGE"
$content
}
これで改行をHOGEにしようとしてもできません
`n を `r`n や \n や \r\n にしてもだめです(テキストエディタで見るとエンコードはUTF8、改行はCR+LFとなっています)
タブ文字は `t でできています
どのような理由が考えられるでしょうか? 改行コードと文字コードは、もう一度地球をやり直すしか ちなみに同じテキストファイルは
秀丸エディタだと普通に \n で検索、置換ができています >>155
この程度はbashでできるけど外部コマンドの橋渡しが基本。プログラム言語じゃないしな
for i in 12345 67 8; do y=${i}0; y=${y:0:2}; echo $y; done
変数は$(())で数値計算できる
PowerShell
12345,67,8 | %{[int]([string]$_+0).substring(0,2)}
156は古いPowerShellだとエラーになる([System.String]にToInt32がない) >>158
$content = Get-Content $file -Raw -Encoding UTF8 >>144は、結果の数値に応じて場合分けするのに
最初の2桁を使いたいからその方法を聞いてるの? 148が言ってるみたいに文字列で処理した方が簡単かなぁ
PS C:\> $x = 1..5 |% { Get-Random -min 1 -max 20 }
PS C:\> $x
4
10
6
17
12
PS C:\> $x |% { -join ('{0}0' -f $_)[0..1] }
40
10
60
17
12 bash/linux使っててpwsh初めましただけど
env:とかalias:とか疑似ファイルシステムみたいに潜れるの楽しい
-からの補完でロングオプション(パラメータ?)出てヘルプすら見ずとも取り敢えず動くのが素敵
もちろんオンラインヘルプもman以上に充実で素晴らしい
困った方も挙げとく
折角両方のコマンド使えるのでcatだけ本物に置き換えてる、pwshのgcとwinのtypeはそのまま
ただcdはbashビルトインで実体が無いので困った
子bashでglobal宣言しても$env:CDPATHに反映されてない?
何かワークアラウンドはないでしょうか?ヘビーユーザなので寂しい
勉強も兼ねてcdをpwshで書くのもいいかもしれないけど 行/列(オブジェクト/プロパティ)をピボットテーブルみたいにグリグリ出来るのも楽しいね
そういうインタラクティブデータ分析はpython/pandasでやってたけど、pwshの方が楽かもしれない 他の言語で書いたらかなりの分量になるところを、psだと異様に短くなる
というケースが楽しい echoしなくていいとか、?、%、&(call operator)、$_とか使いたくなりますね
perl臭がしてくるけど かっちり書けばほぼC#なのもいいところ
前からネットでサンプルコードちらほら見かけてたけど、そういうのはエイリアス無し&キャメルケースの厳つい見た目なので敬遠してしまってた
小文字でも構わないし、標準エイリアス&短縮規約(Get-Verb)あるんだって入れるまで知らなかった pwsh慣れた後にbash勉強したら面倒なんだけどみんなどう思ってる? >>172
C#だと思って使うとドツボにはまる
パイプラインをちゃんと使ってPowerShellらしく書くか、それが嫌ならインラインでC#書いたほうがマシだ
まあいずれ分かる >>173
bashから入ってPS勉強中の俺には
ログインシェルとしては面倒
スクリプトとしては便利
と思ってる。本気で使おうと思ってないから効率的な使い方知らんだけだと思うが、メンバ確認でgm叩くのが面倒lessがないのも辛い
この時点でかなり億劫
スクリプトはどーせvscode使うからあまり気にならないんだが… 何でもpsでやろう、という気にはならないかな
psが向いてる用途にぴったりはまると気持ちいい 非表示オプションにしてもコンソールが一瞬表示される問題さえ解決すればそのまま納品物にできるんだがなあ
今はPS2EXEでEXEにして納品してる >>175
lessはbashの一部ではなくてコマンドではあるけど気持ちは分かるかな
自分はlinux環境でもbatやfd-find、ripgrepに切り替えててwindowsでもchocolateyで導入してるんで、同じ環境になってきました Powershell(でなくてもいいがwindowsで)で「tail -f」したい。。 あとはget-contentにwaitオプションつけるとか
baretailは大きなサイズのファイルでもサクサク開けるのでビュワーとしても使える ちょっと昔まではバッチとの比較がほとんどだったのに
時代の流れを感じる Git for Windows入れたらtail.exeとかも使えるようになる param()と書くだけで
自分で書いたスクリプトもちゃんとパラメータ補完してくれるの偉い
自分の書いたの程覚えられない()
先頭複数行コメントがget-helpできるのも便利そう、思うだけでやってないが
bash/readlineもコマンド補完に力入れてる方だけど、コマンド毎のデータは誰かが手打ちしなきゃならないし、ちょっと仕様が複雑すぎる
まあpwshもpsとcmdlet以外はそうだけど、#!/usr/bin/pwsh、param、startするだけのラッパ書けばよい
ところでwslの人はポータブルにps1書けるの?シバンを認識するかとか、認識にps1拡張子必要かとか
まだ配布できる完成度じゃないけど、折角ならポータブルなスクリプトを書きたい >>184
そこまでするならWSL2の方がいいんでは?
git for windows SDKならpacmanでいろいろ入れられるから便利かとは思いますが >>176
向いてる用途ってどういうのですか?
逆に向いてないのは? windowsの内臓に手を突っ込むようなのが向いてる windowsにプリインストールされてる対話環境もあるスクリプト言語っていう意味では向いてる、のかな??? 正直wikdows周りの事には使ってない唐突にcosとか呼べるので(i)pythonから移行した
オブジェクトを置き去りにするとテーブル表示になって、ピボットテーブルみたいにグリグリできるのでデータ分析にもオッケー、パイプで書けるのも素直
csv, json, xmlもそのまま読み書きできる
高度な関数や重い行列計算はさすがにOctaveとかに投げるが
学習コスト下げたい人はR, Python, Octaveで自己完結した方がいいかも Out-GridView(ogv)が個人的にキラーcmdlet
あとシェルとしても使える() 偏った見方なのは承知してるけど、インタラクティブにエクセル職人的な事やりたいなら、現状で最適なソフトかなと PC起動したら、起動時刻と前回立ち下げ時刻をサーバのエクセルに追記させる
みたいなことを、他の言語でやろうとしたら大変 >>191
たしかにogvはお手軽に結果一覧するには超便利ですね お知恵をお貸し頂きたく…。
Excnange Online に接続して Get で出力したんですが、
波括弧{}でくくられた情報が wrap しても out-file してもどうしても省略されます。
これを全部表示する方法をどなたかご存じでしょうか…。 言葉足らずでした。
{192.168.0.1,192.168.0.2,192.168.0.3,192.168.0.4,...}
みたいに途中で切れてしまうアレです…。 Out-GridVewもいいけどfzfをPowerShellで使えるようにしたほうが一貫性があっていいと思うけど >>197
exchange onlineを触ったことが無いのでお困りの内容が正確にはわかってないのですが、対象のコレクションに対してforeach-objectするのはうまくいかないんでしょうか?
cmdletを記載してくれればもう少し分かるかも テキストファイルの空白行を連番で
[1]
[2]
のように置換するにはどうするといいでしょうか??? >>201
$i=1
foreach ($l in Get-Content test.txt) {
if ($l.Length -eq 0){
Write-Output ("[" + $i.ToString() + "]")
$i=$i+1
}else{
$l
}
}
こういう感じでいかがでしょうか。
あんまりうまくないと思いますが・・・。 >>201
下手だけどワンライナーだとこんな感じ
$i=0;Get-Content test.txt|ForEach-Object {if($_ -eq ""){$i++;"[$i]"}else{$_}} >>196
Exchenge Online使ってないから入力や出力したい形式が分からないけど
$var | Out-File var.txt
だと表形式で長い値は省略されて
$var | Format-Table -Wrap | Out-File var.txt
だと省略されずに保存される Get-Contetは何で標準入力を受け取らないんだろう?
wshはできたのにな >>206
イメージ湧かないんですが、どういった使い方を想定されてるんでしょう? catみたいに標準入力の結果を吐いてほしいんじゃないの
PowerShellはシェルとしての使いやすさよりも直行性を重視してるところがあるので、単に設計思想の違いだろう 標準入力を受け取らない理由なんてないし、実際受け取るんだけども…
get-contentという名前から、何を入力として期待しているのか考えてみなよ PoweShellはWSLが普及したらオワコン化するってホント? >>211
「内容を取得せよ」という名前なんだからcatみたいに標準入力があれば標準入力の内容も出力してくれても別におかしくはないでしょ
PowerShellのget-contentに同様の機能があれば君も普通に使ってると思うぞ
とはいえ、あれば便利だからといって何でも入れたら神コマンド化するから、そこは直行性とのバランスで取捨選択した結果なんだろう その反応はアドバイスに対して論理が微妙じゃね
「『内容を取得せよ』という名前なんだから標準入力から受け取ったファイル名を元に内容を取り出す仕様でも別におかしくはないでしょ」っていうのもまんま成り立つよな
二通りの仕様が考えられるときにcatと同じじゃないのはおかしいというのは先入観に引きずられすぎ
ゼロベースで考えたらGet-Contentの今の仕様は妥当だと思う
Poweshellで標準入力を標準出力にパイプしたいときにcatじゃなきゃいけない理由ってあるの? catは echo abc | cat x.txt - y.txt で x.txt と文字列 "abc" と y.txt を順に結合できる
同じことをpwshでやろうとすると少し頭使うだろう
pwshにはエイリアスにlsとかあったりするのに、MSがget-contentを設計する際にcatを全く意識せずゼロベースで考えたというのはさすがに普通に考えてありえない
意思を持ってcatと同じにしなかったのだろうし、別にそれが間違っているとは思わない あー、concatinateとして使いたいってことか
普通のcatもその使い方しないから全然気づけなかった なるほどね、208の質問にそう答えてくれてればスムーズに話が進んでたと思うよ
直行性という意味ではjoinなどの結合操作だね
書き方に悩むのはどっちに慣れてるかってことでしかないと思う
歴史的経緯でこんがらがった過去のシェル環境達を負の遺産ごと継承するよりも改めて再整理したいって話と、わかりやすいエイリアスを付けてあげたいってのもまた別の話 >>166
単項の-join -splitあるなんて知らなかった… get-contentで検索文字列をテキストから取得し変数に入れているのですが、
*検索文字1*,*検索文字2*
と変数に入れると何も返ってこなくなります。検索文字列が一つだけなら問題なにのですが…
変数 = テキストファイル
get-content パス $変数
です。カンマをエスケープさせるのかアスタリスクをエスケープさせるのかこんがらがってきました…
知見を下さい… >>220
変数使う所はget-childitemでした。 >>220
分かりにくいですね…
要はget-childitemで複数のファイルを検索するためにテキストファイルを使いたいって事です。 テキストの中身をカンマじゃなくて改行で区切ればそんな苦労しなくて済むぞ
あと余計なお世話だけどGet-ChildItemが手打ちで動くことは確認した?
パラメーターがちょい怪しい気がするんだが… >>220
リテラルではカンマで渡してるから配列にしないとダメみたいね
test.txtの内容:
*.jpg,*.png
$r = gc test.txt
gci パス\* -Include ($r -split ",")
パスがカレントフォルダなら
gci ($r -split ",")
または
gci .\* -Include ($r -split ",")
または
gci * -Include ($r -split ",") なんかテキストベースの志向してる人多くない?
テキストベースのデータは最低限配列化して扱うもんじゃないの? PowerShellで配列を明示的に使うのはダサいしハマりやすいよ
パイプに任せた方がいい 他のシェルではテキストベースが普通というかむしろpwshが異端だしなぁ
手段を選ばなけりゃpwshでもInvoke-Expression使えるし >>224
現在、環境がないので後日試してみます!ありがとうございます。
>>223
ファイルを使わずコマンド単体なら複数検索でも動くのですが…改行で動くのですか?カンマに捕らわれすぎてたかもしれません。試してみます! 略称としてはpwshが今公式に推されている?
しかしposh呼びしているMSドキュメントも多い
拡張子的にはps
pshとか収まり良いけど既にあったりして紛らわしい系? 推すとかじゃなくPowerShell6から実行ファイル名がpwshになった
コマンドとしてpwshが正式名称 pwshへのリネームはとんでもない破壊的変更なわけだけど、今後どうするんだろうね
powershellをpwshのエイリアスにしたらそれこそ阿鼻叫喚だろうからそれもなさそう
5は凍結して、そのうちWindowsにデフォルトでは入らなくてオプションで入れるようになるんだろうか 実行ファイルの名前以前にwindows由来のモジュールが分離されてインポート必須になってるから、移行するんであればスクリプトの修正は必須ですね 複数バージョンの同居認めてるからその辺は問題にならないと思う
つーかログオンスクリプトで既にガンガン使ってるから5が標準で消えたら死ぬ 6はapt経由で7-preview入れたら塗りつぶされたけど、大体互換だからかな?
とりあえず俺は問題起きてないしよしとしよう 自分のスクリプト用はPowershell7
社内スクリプトやらはWindows Powershell(5系)
MSは互換性維持の為に古いものを限界まで残す所だから当面問題は無いと思う
ただPowershell7系はそろそろ安定して快適だしWindows標準で入れてくれて良いと思う 6→7では||とか&&とか?:とか演算子かなり増えたと思ったけど
6で実行すると将来の拡張に予約的なメッセージが出たはず
後方互換性はちゃっかり確保してるのね >>238
バックエンドの.NETが提供される限り、言語の部分に関してプラットフォームは関係ないからね
(俺は7持ってないから確認は出来ないが)
シス管機能に関わるプロバイダの部分は、VistaくらいからCim規格準拠(WMIとして)に力入れてるので、それも寄与してるかと
まだ公式リリースされてないが、 linuxでは特にUbuntuもCim準拠に力入れてる
近いうちにpwshのプラットフォーム間相互運用性の確保(pwshコードベースのメンテコスト)はかなり楽になるだろう
今はまだ統一的に見えるユーザーエクスペリエンスは、対応するAPIを繋ぎ合わせたアドホック実装されてる
アドホック実装が減ればコードベースが削減されるわけで、伝統シェルに劣るとされるファイルサイズデカい問題も解消されると期待している >>229
そこらの経緯はこの記事にまとまってるよ
PowerShell 6.0からPowerShellのプログラム名がpwshに変わります
https://blog.shibata.tech/entry/2017/10/19/073001
元々、略称はposh呼びが多かったみたい(容易に発音可能だし)
pshはPerl Shellと被るので避けたそうだ マルチプラットフォーム化の為に作り替えて、
違う系統であることが明確になるよう、名前も変えてたね
(.NETと同じく過渡的な措置だったのだろうけど)
Windows PowerShell(5系以前) → PowerShell Core(6系) → PowerShell(7系以降) PowerShell core(6系)の時はWindowsの内部操作系(IP確認やら)はホントまともに動かなかった
それがPowerShell7になったら殆ど動く様になった時は感動したわ、Out-GridViewも復活したし 略称を作る時に母音を飛ばすのは普通なので、poshよりはpwshの方がまとも
posh1が上品とかの意味を持つ既存の英単語だから、わざとそう呼んだ
posh2として軽蔑する時に発する音、という意味もあるのでなおさら >>243
言語の移植はそれほど難しくないけど環境依存のコードを含むコマンドレットとかは地道にやるしかないからIP確認とかが遅れるのはしゃーない 名前にdefine使って、偶然7時点で将来に予約メッセージを受けた
まあこんな一般的な単語をユーザーが使うべきではないというのは置いといて… わりと1の時点から将来的に使いそうなのは予約語に入ってたよ、classとか >>227
WYSIWYGじゃないからなあ
掴めてない人はget-formatdataで標準の表示書式拾ってちょっと手を加えて遊ぶといいかも 標準はちょっとverboseすぎるから、共通パラメータやメンバを無視して表示くらいの設定はしておきたい GetTypeとか存在すると分かりきってて、定義も自明なのはする必要ないね
高度なメタプログラミングしてたら別だけれども PowerShell7のGet-ClipboardにFormatパラメータ的なものないの?
PowerShell5ではそれを指定してクリップボード内の画像だったりを取得できたと思うが >>251
クロスプラットフォーム化でテキスト以外のサポートはなくなった
画像とか取得したければ、面倒だけど自前でSystem.Windows.Forms.Clipboard使ってやるしかないね
こういうやつ↓
https://qiita.com/saggie/items/44cb8b317fe0effa5891 >>252
>>253
ありがとう
取り敢えず>>253の方法を使うことにします >>252-253
この調子でバージョンアップすると機能が劣化していくのか…
変な方向に向かってるな マチルプラットフォーム化すると各プラットフォームの最小公倍数の機能になっちゃうからね Windows PowerShellとか処理は遅いし使えない機能は多いわ文字コードはSJISがデフォルトだったりとか仕様も古くて微妙だしな
一部機能は使えなくてもPowerShell7はかなり進化してるわ それでもWindows PowerShellが好き winのクリップボードはやけに高機能だよな
田+vで履歴、それを再編集、ピン留め等
gui環境ならコマンドヒストリの代わりにもなる、というかより便利
rtfはターミナル民的には興味ないけど、pwsh がコマンドライン上でサポートしなくても、ターミナルアプリの設定あたりで補えるのでは
(wtの設定にはある) プレーンテキストといえど、所詮リッチテキストはマークアップされたプレーンテキストなのだから、適当にエスケープするように*-clipboard cmdletsをラップしてしまえば良いのでは
思い付きなんで上手くいくかはわからんが TCP IPをPowerShellでさわったことある人いたらクライアントで受信する方法について教えてほしい
何から手を付けたらいいかわからん >>262
まずは何をしたいのか書くところからかな
TCP/IP上に独自プロコトルでデータやり取りしたいとか言うならPowerShellよりC#とかの方が楽かもしれないからPowerShellでやりたい理由も書いてくれるといいかも Powershellでやる場合はC#と同じく.NET FrameworkのSystem.Net.Socketsを使うことになるだろうから
他の言語でのやり方を知ってるなら下ののC#(.NET)の箇所を参考にすればいいのでは
https://www.ne.jp/asahi/hishidama/home/tech/lang/socket.html まずは、やりたい事を説明出来るレベルにまではなってからじゃないと無理ゲーじゃね? ワシの日本語なんか変だな。
人の事言えんかったわw 今帰宅した262です。
>>263
やりたいことは限りなくデフォルトのwindowsで動くTCP IPのクライアントを作ること。
お客さんに納品する機械がTCP IPでしか操作できないらしいので出来るだけ環境構築やインストール作業の必要ないクライアントを作る必要があったからなんだ。
>>264のレス見たらなんとなくわかった気がする。今の問題としては、適当に作ったサーバーに送信したものを返させてテストしてるけど数字しか帰ってこなくて困っていた。
とりま今あるスクリプト晒します。
$socket = New-Object System.Net.Sockets.TcpClient("127.0.0.1",40001)
$stream = $socket.GetStream()
$reader = New-Object System.IO.StreamReader($stream)
$writer = New-Object System.IO.StreamWriter($stream)
$writer.AutoFlush = $TRUE
$buffer = New-Object System.Byte[] 1024
while ($TRUE) {
$data = Read-Host("command?>>> ")
if ($data -eq "q") {
break
}elseif ($data) {
$writer.WriteLine($data) | Out-Null
$rawresponse = $reader.Read($buffer,0,1024)
Write-Output $rawresponse.GetType()
$response = [System.Text.Encoding]::Default.GetString($rawresponse)
Write-Output $response
}
}
$socket.Close() >>267
> 数字しか帰ってこなくて困っていた。
> $rawresponse = $reader.Read($buffer,0,1024)
そりゃReadメソッドの戻り値は数値(読み取った文字数)だから当たり前かと
PowerShell は文字列と数値を適宜変換しちゃったりするからC#やC++が使えるならそっちの方がデバッグが楽だと思う >>268
exe形式で渡せるならその2つの言語は選択してたかもなぁ
C#でGUIにしたら、パソコンわからんお客さんでも触れるかもしれんし。今回は規模小さいしPowershell使いたいかな。 Ruby on Rails のテストでは、
HTTP のREST API なら、curl, Postman。
VSCode の拡張機能なら、REST Client, Thunder Client
REST Client では、コマンドパレットのGenerate Code Snippet で、
Ruby, PowerShell など、各言語のコードに変換してくれる!
TCP と言うのは、あまりに原始的過ぎて、よく分からない。
curlで出来るかも知れない
新し目のWindows 10 には、curl.exe も入った。
コマンドプロンプトで、where curl と入力すると、
C:\Windows\System32\curl.exe
なお、PowerShell内でcurlを使うのには注意が必要。
デフォルトで「Invoke-WebRequest」コマンドのエイリアスとして、curlが設定されている。
このため、PowerShell内でcurlコマンドを使うには、
フルパスを指定するか、curl.exeと指定する必要がある
Linux のcurlと区別するため、
漏れは、Invoke-WebRequest は、curlモドキ・なんちゃってcurlなどと呼んでいる C#で書いてAdd-Typeで貼り付ければpowershellとして納品できるよ
下手にC#のコードをpowershellで書き直してもややこしくなるだけと俺は思う
C#のusingとか便利な機能はpowershellじゃ使えないし >>271
同意
pwshから使いやすい様に多少注意して書けば問題なし 例えば、HTTP のREST API で、VSCode の拡張機能・REST Client で、
コマンドパレットのGenerate Code Snippet から、
PowerShell のInvoke-WebRequest に変換すると、
POST http://localhost:8888/ HTTP/1.1
content-type: application/json
[[0,0],[10,20],[10,10]]
変換後は、
$headers=@{}
$headers.Add("user-agent", "vscode-restclient")
$headers.Add("content-type", "application/json")
$response = Invoke-WebRequest -Uri 'http://localhost:8888/'
-Method POST -Headers $headers -ContentType 'application/json'
-Body '[[0,0],[10,20],[10,10]]' >>271
いいこと聞いた!
敷居高そうだけどちょっと手を出してみる。 >>274
rawresponseじゃなくてbufferをencodingしてあげればいいところまでできてるんだから、このままpowershellでいいんでない? >>276
そうなん?
bufferを出力してもゼロの羅列しか帰ってこないから何も入ってないと思ってた readlineしたら解決しました。CUIだめって言われたらC#に手を出そうと思いますありがとうございました xargs -I @に変わるものって何かあります? サーバーのログファイルが24時越えの時刻形式で出力してくるんだけど
これをDateTime型に変換するもっとスマートな方法ありませんか?
$Date = "20210531285930"
# 24時超えなのでDateTime型に変換できない
[DateTime]::ParseExact($Date,"yyyyMMddHHmmss",$null)
# HH部分を-24でDateTime型に変換してからAddDays
[DateTime]::ParseExact(($Date.Insert(8,"{0:D2}" -f ($Date.Substring(8,2) -24))).Remove(10,2),"yyyyMMddHHmmss",$null).AddDays(1)
# 各部を切り出して-24でDateTime型に変換してからAddDays
([DateTime]($Date.SubString(0,4) + "/" + $Date.SubString(4,2) + "/" + $Date.SubString(6,2) + " {0:D2}" -f ($Date.SubString(8,2) -24) + ":" + $Date.SubString(10,2))).AddDays(1) ごく普通のやり方しか思いつかんかった
if ('20210531285931' -match '(\d{8})(\d\d)(\d\d)(\d\d)') {
$date = [datetime]::ParseExact($Matches[1],'yyyyMMdd', $null)
$h = $null
$date = $date.AddDays([math]::DivRem($Matches[2], 24, [ref]$h))
$date += [TimeSpan]::new($h, $Matches[3], $Matches[4])
$date.ToString('yyyyMMddhhmmss')
} >>281
24からいくつまで考慮すればいいですか? 0〜23時は、そのまま
24〜47時は、24 を引いて、0〜23 にして、1日足す Javaだと勝手に繰り上げてむしろ頼んでねーよと思ったけどシェルスクリプトであるPSにはLenientな日付解釈が見当たらないな
ままならないね 整数の24で割って割った値を日付に加算、余りを時間にすればいいんじゃね >>287
コード化するとこんな感じスかねぇ
$Date = "20210531285930"
if ($Date -match '(\d{8})(\d\d)(\d{4})') {
[DateTime]::ParseExact(
$matches[1] + "{0:00}" -f ($matches[2] % 24) + $Matches[3],
"yyyyMMddHHmmss",$null).AddDays([Math]::Truncate($matches[2] / 24))
}
結果
2021年6月1日 4:59:30 短くできたw
if ('20210531285930' -match '(¥d{8})(¥d¥d)(¥d¥d)(¥d¥d)') {
$date = [datetime]::ParseExact($Matches[1],'yyyyMMdd', $null)
$date = $date.AddSeconds(3600 * $Matches[2] + 60 * $Matches[3] + $Matches[4])
} 普通にtimespanを足せば良いのでは
if ('20210531285930' -match '(\d{4})(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)') {
$date = [datetime]::new($Matches[1],$Matches[2],$Matches[3]) + [timespan]::new($Matches[4],$Matches[5],$Matches[6])
} >>291
なぜ最初にコレを思いつかなかったのか… Powershellって無くなるって本当ですか?
ある人が言うには、マイクロソフトが公式で
「Powershellは無くして、Bashに統合するって言ってるからPowershellなんて使えても意味ないよ」<ほぼ原文
という事らしいです。
@そのものズバリの公式案内って出てますか?
A「xxを拡大解釈して、↑のような話と勘違いしてるのではないか」というのがあったら教えてください。 powershell 5.1じゃなくて.Net Coreベースのpowershell 7を学習しようとかじゃなくて、まるっきりbashに置き換わるってなると妄想レベルとしか マイクロソフト公式がそう言ってるならその発言ソースをググって見つければいい
公式→ある人→296→いまここ
なので、しょうもない伝言ゲームだろうね まあ無くなるかはともかく、pscoreでちょっと怪しくなってきたよね
pscoreが今後Windowsにバンドルされることは恐らくないだろうから、PowerShellはWindowsOSの一部から単なるアプリの一つへとある意味格下げされたわけだ
それについてはMSも公式に明言している(https://docs.microsoft.com/ja-jp/powershell/scripting/powershell-support-lifecycle?view=powershell-7.1)
そしてps5の方は既に完全にメンテナンスモード入りしており、今後の進化は無いし、いずれはWindowsにバンドルされなくなるだろう
PowerShellはWindowsプラットフォームにおいて特別な存在ではなくなりつつあり、bashと同じ土俵に降りるんだよ 正直bash標準はイヤだな
PowerShellと比較して仕様が古臭過ぎる bashでwindowsの中身いじるのができなかったからpowershell作る必要があった訳で >>301
.NET 5か6がOSリリースに組み込まれるようになれば一緒に置き換わるでしょ
インタラクティブなシェル機能だけが重要でbashというかreadlineが使いたいなら使えばよいけど、.NETをbashから使える仕組みってできてるんだっけ? bashとかを置き換えるつもりだと思ってたんだけど…
もうちょい野心持っていいのよ?
wsl使ってるけど$profileとか共有できてすごく便利なんだけど
bashもよく使うが、補完が各コマンドにハードコード対応してる仕組みなので、GNU Readlineが生きてないなと
PSReadline/pwshみたいにユーザースクリプトにParam記述できる仕様じゃないとインタラクティブシェルとして将来性が無いと思う
逆に言えば、コメントに#Param記述して読んで補完くれるbsh系があれば便利ね
コメントなら互換性も問題ないでしょ wslスレ覗くとpwsh使ってる人結構多いように思える
まあ変なのいっぱい居てアレ過ぎるスレだが、蛇足 Windows Subsystem for Linux に関してよく寄せられる質問
https://docs.microsoft.com/ja-jp/windows/wsl/faq#powershell-----------------
PowerShell においてこれは何を意味しますか。
OSS プロジェクトでの作業中、PowerShell プロンプトから Bash を実行すると非常に役立つシナリオが多数あります。
Bash のサポートは補完的なものであり、Windows でのそのコマンド ラインの価値を高め、
PowerShell と PowerShell コミュニティでその他の一般的なテクノロジを利用できるようにします。
詳細については、PowerShell チームのブログ「Windows の Bash:それがすばらしい理由と PowerShell における意味」をお読みください
https://devblogs.microsoft.com/powershell/bash-for-windows-why-its-awesome-and-what-it-means-for-powershell/ >>304
.NET5以降がWindowsにバンドルされることはないでしょ
ライフサイクルをWindowsに拘束されたくないから.NET Coreは完全なサイドバイサイドとSCDを実現したのに、そんなことをしたら台無し
.NETを使うならpwshというのはこれからもずっと変わらないだろうし、一貫したコマンドレットの体系でWindowsのサーバー管理ができるという強みもあるけど、後者については案外突然.NET非依存のWindows CLIとか出るかもよ
Azure CLIだってPythonで書かれてるんだし それもしかして、WSHというヤツでは?
まあ好きでもないし新しいのに置き換えてくれるのは歓迎だよ
$wsh = new-object -com w/cscript.shell
みたいにしてたまにメソッドこねこねするけど、COMオブジェクトのインターフェイス備えるなら今まで通り叩けるんじゃない C#越しとかでローレベルAPI叩けたり大丈夫かこれって思ってたらやっぱ消えるのか・・・ .net coreの実装はいっぱいあるからバックエンドは心配ないんじゃない?
MS推奨の.net core, asp core, 使ったことないがMSから少し離れてもmonoとか他にも
.net core(linux)は50MBくらいにまとまってたかと >>308
winへの巨大なpythonランタイムのバンドルが許されるんなら、.net coreもバンドルしていいんじゃないかな(並存で)
.net coreはpythonライブラリとしても便利だし、今時数百MBくらいケチらないで両方入れて欲しい
スマホにすら.net core以上相当のXamarinやmono入ってるだろ(多分ストアから依存経由で) >>313
WindowsにバンドルされてしまうとMSはそれをWindowsの一部としてサポートしなければならなくなり、.NETのモダンライフサイクルポリシーと矛盾する
また、Windowsにバンドルされているバージョン以外はほとんど利用されなくなり、プラットフォームの進化が停滞する
もしpwshをWindowsにバンドルするならSCDにして.NETのライフサイクルから分離してしまうしかないだろうけど、
それはそれで.NETランタイムのバージョンがpwshにバンドルされているものに拘束されることになり、pwshエコシステムの外にある.NET資産との連携がしづらくなるだろうから難しいところだな winはサードパーティの物はバンドルしない方針じゃない?ルールになってるかはしらんが
まあ善き終身独裁者はMS社員なので、pythonがMSサポートになる可能性はあるかも?
最近サポート切れた2.7をバンドルし、ディストリ拡張に汎用してたlinuxは現に大変なことなってるし、止めといた方がいい python作者のことだろ、BDFL(benevolent dictator for life,だっけ)
30年以上歴史あるのに未だにバンバン破壊的変更加えてる姿勢は見習うべき
pwsh core使ってる層にロングタームサポート望んでる人はそんな多くないだろ
堅牢にやりたいならshやwsh、.net framework使え 見てきた
Version サポート終了
7.1 2022 年 2 月中旬 (予定)
7.0 2022 年 12 月 3 日 ☆LTS
意外と短かった、こんなもんでいい
python3はマイナーバージョンでも予告なしでAPI変わるけど誰も気にしてない
3.10にして外部ライブラリ入れたら標準ライブラリcollectionsでNotFound頻発してるけど、その場で名前書き変えて問題なし、ヨシ!
って感じだし .>誰も気にしてない
めっちゃ主語でかいなー
そんなわけないだろ ごめん、エンドユーザーじゃなくてライブラリユーザーレベルの話だね
まあ気にしてる作者は仮想環境で複数バージョンテストしてそのうち直すだろ パッケージマネージャに対してversion≧3.3のような、未来バージョンも含めた指定をするのは普通じゃなかろうか
対象に含まれてるはずなのに対応してないってことはそういう事だろ >>314
そういうことかね
ところで.net(core含む)はwindowsコンポーネントではないけど、windows updateでリンクすることは可能なよう
Automatic patching on Windows operating system
All versions of .NET that are supported can be automatically patched via Microsoft Update. This enables organizations to manage all .NET updates in the same way.
ついでにpwshもランタイム分離版(sdkに付いてるdotnetサブコマンドで起動するやつ)を含めてしまえば、停滞も避けれると思うのだけれど
社内デプロイ想定のようだけど、その場合はWindow Updateはむしろ切っときたいというのは、ツッコミどころ?
https://dotnet.microsoft.com/platform/support/policy/dotnet-core .NET 5のバンドルがありえないならbashのバンドルはもっとありえないだろ WSLはオプションとして既にWindowsにバンドルされていて、Windowsの次期メジャーアップデートではデフォルトで有効化されてコマンド一発でBashが入るようになるよ bashはwindowsには向かないと思うよ…
既にcygwinや派生のmimgwがあるけど、前者は完全にunixっぽい箱庭だし
一応winに適応を試みてる後者も限られた外部コマンド以外は自力移植で苦労ばかり、変に合わせた分むしろunixに慣れたユーザに拒絶されそう
単にunixの資産を活用したいならwslという手段があるので、今更MSが参入するとも思えない (b)sh資産を活用するって言ったって、ファイルシステムやコマンドの振る舞いを決め打ちして書かれた物ばっかりだろ
箱庭にするしかない
一応wslからNTFSにもアクセスできるけど、よりファイル属性の少ないext4想定でlnとか使うとおかしな事になるよ
gnuが対応要請に答えるとも思えんし
シンボリックリンク貼りたいならnew-itemを使おう そもそもwin用シェルとしてbashがマトモに使えるなんて思ってる人なんて居ないだろう
それこそcygwin等の試み見れば明らかなわけで あとは>>296の知り合いが何でこんな盲言を吐いたかだが すいません、もうちっと前後関係書くべきでした、
私→転職者
ボス→ボス
無くなるさん→Powershell無くなるよさん
ボス「私さん、何がスクリプト言語的なものって扱える?」
私「bashと、Powershellはそこそこ使えます」「あと、おまけ程度ですがVBAも少々」
ボスLinuxとWindows両方いけるんだね」「Powershellは使える人少ないから、助かる!」
無くなるさん「Powershellは無くして、Bashに統合するって言ってるからPowershellなんて使えても意味ないよ」
っていう流れがありました事を、ご報告いたします。
今は7系勉強中です。 スクリプト前提の文脈なんで、なおさらスルーでよさげですね
ただのマウンターにしかみえないっす ボスの発言の後でそれ言える勇気は凄いな
詳細thxだけど知り合いにバレないよう気を付けてね wslとか言ってる奴はプロセス制御とかどうする気なのか気になる
winネイティブ実装のbash(msys?)なら原理的には可能とおもうが…
*-Processがそれぞれどのコマンドにマッピングされてるのか気になる 公式win版sh系移植が出るんなら、それはそれで裾野が広がるからいいと思う
ただし新規導入されるであろうcomオブジェクトやレジストリ弄りコマンドを、引数補完の弱いbashでやるのは勘弁してほしい
たぶん古き悪き対話式のwinコマンド叩く事になりそう
もしやるならzshで頼む シェルスクリプトなんて現システムで動けば十分なのに遠い未来になくなること心配しても意味ないような プロバイダを擬似ファイルシステムとしてマウントしすれば補完できないかな
プロパティやメソッドまでそうすべきかは悩むところ、やりすぎ?
同名の環境変数やコマンドをどうマップするか
unix系pwshは割り切って環境変数は倣ってる($env:プロバイダ以下に)
コマンドレットは命名規則上被らない
win標準エイリアスはwriteとかが被るけどこれも尊重
pwsh -nop
gal write # not found
(gcm write) # /usr/bin/write
らしい
マイナーコマンドなのでもちろんset-aliasしてるが
ポータブルなps1書く時には一般的な名前のwin標準エイリアスは避けた方がいいかもね 話が逸れた…
まあ逆移植ではこうなってるという例として Write(-Output)はよく使うからwriteで済ましてしまうな
どうせ俺はPublish-Script/Moduleするようなレベルじゃないけど パイプラインとリダイレクトの解釈フェーズが独立しているbshの文法では、疑似ファイル方式は難しいと思う
"> /dev/null"なんて使ってないスクリプトの方が稀に思うけど、winの変な"NUL"ファイルに適切に読み替えるには| Out-Fileと>file (またはコマンド置換)が可換である必要があるよね?
powershellでも合法なはずの"> NUL"は普通オープンに失敗するはず
だから自動変数を使った"> $null"、コマンドを使った" | Out-Null"と書けるように>と|を同格にしたわけで
shっぽい言語が使いたいなら、ぱっと見似てる新言語作ったほうが早い winの変な仕様に適合する為にpowershellは柔軟な文法になった説 >>335
プロセス制御って?
Windowsの他のプロセスを制御したいならWSLからWindowsのコマンドを呼べばいいし、
Linuxのプロセスなら当然UNIXの世界で管理するだろう
自分自身のプロセスを制御したいなら当然後者だわな
何が問題? プロンプトからのffmpegの実行で引数として -metadata に指定する値に空白とエスケープシーケンスを含めたく
¥"abc`n def¥"
でできましたが、更に " を含めるにはどうすればいいでしょうか?
"" や `" は駄目でした >write-output "abc`n `"`"def `n`""
abc
""def""
ネイティブアプリ例
>gc ~/bin/args
#!/bin/sh
printf "%d args:" $#; printf " <%s>" "$@"
>args "abc`n `"`"def `n`""
1 args: <abc
""def"">
期待通りでは?
cmd用に書かれたものには、独自のパースをするものがあるので(悪名高いのはruby等)、もしかしたらそれでは? もしかして、こういうことか
>args "`"abc`n def"`" sanitycheck
2 args: <"abc
def"> <sanitycheck> ごめんレスを読み違えてたかも
エスケープシーケンスを渡したい、のなら、ffmpegのエスケープシーケンスを調べて渡すべき
上に挙げた例は「生の」空白と改行と"を、pwshのエスケープシーケンスを用いて渡す、という例 winでは所謂c風のargvを使わない、シェルのパースを無視し、コマンドラインを文字列として取得する事、が可能
>>343
コマンドラインの> NULをプログラム側でアドホックに認識して、出力を止める手法が横行した
展開前の環境変数名をエスパーしたりも
cmdで> NULが動く事が多いのもこれ そして\はpwshのエスケープシーケンスではなく、winのエスケープシーケンスだ>>346 \"bc\" 文字列 \ + bc\ = \bc\
a"ba" が文字列abaなのと同じ
a"ba"a" は閉じてない文字列 え、コマンドプロンプトのエスケープシーケンスと、それが解釈された後のPSのエスケープシーケンスを2重に考えて引数を渡しなさいよってオチじゃないの? cmdと直接の関係はないよ
とりあえず
"\abc改行文字 \"
という文字列をpwshは渡すはずだけど
環境も意図した書式も不明だし、フィードバック無しに詮索はやめとこう cmd関係なくwindowsだと\はStartProcessコールのエスケープ文字だしな
システムコール自体やcmdに食われるの想定して、余分に付け足したりするプログラムが多いので複雑怪奇になる
そんなwindowsプロセスにも賢く渡す機能が7.2以降に付きそうだけど、これでまたアドホックな要素がまた一つ増える… >>347
linux/macだとpwshは`のみ特別、システムは何もしない、プログラムは(普通)\のみ特別
この上なく分かりやすいという皮肉な わかりにくいなら配列$argsにまとめて渡したり' 'で括って_などをreplaceがいいかも
クオートが続くと''→'、""→"となるcmdっぽい例外は抹消してほしい
クオートされた文字列とされてない文字列は併置で連接されるけど、例外になってしまう 最後の引数に限るけど、--%で以降のパースを全て止めてしまうのも便利
単語分割もされない >>358
> クオートされた文字列とされてない文字列は併置で連接されるけど、例外になってしまう
何の話? PowerCLIの話ってここでいいのかな
モジュールコマンドレットの引数ってとう調べればいいんだろ すんません自己解決です。
Module内のpsm1ファイルとかにありました。 スクリプト、シェル関数、フィルター、モジュール等々
コメントや引数からのヘルプ生成いいよね、(MSサイトのアヤシイ自動翻訳と比べれば)割と読める
ghできてびっくりした powershellなかったらWindows10嫌いになってた
まあ嫌いだけど スマホでPowerShell使いたい人っているの?
Distribution Support Request: PowerShell for Android
https://github.com/PowerShell/PowerShell/issues/15556
Distribution Support Request: PowerShell for iOS
https://github.com/PowerShell/PowerShell/issues/15563 ぶっちゃけplaystoreで何回も検索してるけど引っかからなくて悲しんでる
about_*をブラウザで読んでた方が百倍マシな紙芝居チュートリアルみたいのは存在してる(検索ノイズ)
アンドロの採用してるmkshへのインターフェイス提供するアプリは、個人投稿ぽいのがいっぱい出てくるんだけども… 携帯端末で特に何がしたいって訳でもないけど、思い付きのアイデアを手軽にインタプリタで検証したい時は割とある
野良でもいいけど、公式から出るんならなおさら嬉しい 色々電卓代わりのインタプリタ試したけど、今のところgforthが最良
ソフトキーボードと喧嘩しないし、pc版と同じヘルプ補完を提供してるいいもの
ただ言語コアが小さいので、そのままでは四則くらいしかできない
一般的な言語は()を行き戻りするのが辛い、数学関数揃ってるRPN/コマンド言語が求められる
[math]::funcとか手軽に引けるだろうことは嬉しい
RPN言語側での候補は数学関数揃ってるpost/ghostscriptだけど、これもrepl移植が見つからない、悲しい 式を置き去り(最初のワードがコマンドでない場合)にしたら勝手に評価して表示してくれるのもいいね
10Kをintと解釈してくれるような、かわいい機能群も生きそう
スマホ関数電卓界のホープになれる (mk?)shへの対話モードはAndroidのネイティブシェルだから、ガワ被せるだけの野良実装が多いのは理解できるんだけど
入力が不便なスマホで一体何に使うのな気になってる、やけにダウンロード数多いし
マゾいexprで電卓したり、まさかスクリプティングするわけでもなかろうに unixの伝統的な外部コマンドはアンドロイドにはあんまり入ってなかったはず
別途入れるかバンドルされてるのを探すかしなければならないけど、bcやimagemagikを(多分)叩けるのは有意義だと思う
まあそれ以外の用途は浮かばないけど、広告まみれの電卓/画像変換アプリ使うよりはずっと良さそう
ちょっと試してみるかな 携帯端末でshを使う需要でとりあえず思いつくのは
httpクライアントでエロ画像根こそぎ落としたり
出先からPCやサーバが仕事してるかsshクライアントで確認&ジョブ投げたり?
とりあえずロートルでも単純なコマンドさえ発行できれば十分なのでは
pwsh(android/ios)にはそれ以上を期待したいけど 携帯デバイス上のsshデフォルトシェルに便利な気がする
動的に画面に合わせたビューが提供できるのが活きそう
確かにソフトキーで一行コマンド送るならshを設定しても大して変わらないけど、
大きいディスプレイ向けにハードコードされたunix/winコマンドの出力なんてスマホやタブで読めたもんじゃない
逆にデフォルトで簡潔なビュー(.ps1xml)が同梱されないなら、多分俺は電卓としてしか使わないわ >>367
PSは.NETやWin32API呼び出しとC#が使えるのが肝だからなあ
スマホじゃ適当なシェルでいいんじゃないか
PSのパイプとか遅いだけだし .netアプリなんてapple/play storeに溢れてるのでは?
と思ってたらこれ、ランタイム方式じゃないのね…
iOS/Androidの.net(monoやxamarin)は、必要なコードだけ抽出し.apk等にコンパイルされているようで
粗末な出来なのに~50MBくらいある奴が典型的
明らかにxamarin, monoのランタイム(~100MB以下)を共有した方が経済的だと思うんだけど、何か大人の事情があるのだろうか 別にスマホのシス管するわけでもなし、xamarinやmonoから必要なAPI引いて自己完結なポートでもいいと思うけどね >>367
5日放置かー、あんまり興味ないのかね
モバイル疎いのでmono, xamarinはよく分からんけど、とりあえず.net coreもiOS, Androidサポートしてるようす
https://github.com/dotnet/core/blob/main/release-notes/6.0/supported-os.md
.net実装少なくなったね
monoもxamarinも買収で半分MS公式だし、コードベースもほぼほぼ共有しちゃってるし
野良実装がわらわら溢れてた時期は、これからは.netという安心感があったなぁ 実用性よりもCore系なら移植性抜群ですよっていうデモ的な意味合いが大きい気がする そうだね、ぶっちゃけ知らなかったし
一応遊んでみようと思う MS公式、準公式で少なくとも4つ実装がある意義とは
野良実装の存在は健全な発展に必須だろうに、なぜ淘汰してしまったのか スマホにドトネトて、既にあるラッパーのラッパーを作ることに相当するよね
スマホのアップデートなんて限定的だし定期的に買い換えても機種が違えば中身もゴッソリ変ってるし
どうせroot化でもしない限り大した事できないしあんま深く知りたいわけでもない
automateみたいな事が普通にできれば十分かな なんでスマホでやらなあかんねん
という部分がまずクリアできない 本当に最低限のサポートだけど
vimの補完関数に外部コマンドとしてpsreadlineの晒してるAPIを指定するだけで、replと同等の編集ができるよ
(about_PSReadlineとかそんな感じの参照) MSのサイトでPowerShellのlsp書式(VSCodeのプラグイン形式)公開してるから、vimのlspサーバ付きビルドなら標準でVSCode同等機能で書けるよ
PSReadlineのバックエンドも多分これだし、間接的には同じことかも?
あくまでライン編集用なので、まだ保存してない定義参照など文脈読むのはvim担当になる
ただしパスにカレントディレクトリを加えておけば、保存した時点でのパラメータ等はPSReadlineが勝手に読んで候補に加えてくれるから、暗黙のうちに候補に加わる
ちょっと複雑だな
もしかするとロースペックだとラグいかも
外部呼び出しはブロックするし、キャッシュの存在し得ないファイル(現在編集中)を読むので…
何もインストールしなくていい手軽さと、自動でget-helpする小窓を常時表示したり、カスタマイズ性の高いvimからPSReadlineを呼びだしを推したい ブラックボックスなプラグインをぶちこむ
うごけばいいんだよ 2exeが仕事で役に立ったわ
exeじゃないとアイコン設定できなかったりするから必須機能だな 7.2に上げたついでにinstall-module PSReadline -AllowPreview -force的な事したらコケたわ(2.2
replに入るとPSReadlineが死ぬ
レポジトリの会話見ると7.2で結構変更あるのでまだ2.2で対応してないと
pwsh -noni -nop -c '&{uninstall-module PSReadline}'的なのをcmdから打ってちゃんと最新が消えて2.1にロールバック、問題なし
迂闊なアップデきよつける >>390
Windows Updateに乗(せられ)るのね、ちょうど上の方で話題になっててタイムリー? >>357
-[not]match, -[e|c]replace の右辺(パターン)も`にして欲しかったわ
winのパスの'path\to\somewhere'がめんどくさい
[regex]::escape メソッドが用意されてるけど、メタ文字っぽいの全部エスケープしちゃうので
先頭アンカーの^をメタ文字にするときは
'^' + escape('path\to\somewhere')
なんか汚い…
.もパスによく出てくるので面倒
いい書き方ないかな? pwshからドトネトも学ぼうとsdk入れたら500MBも吸われてしまった…
F#を恥ずかしながら知らなかったんだかど、MLとC#を悪魔合体したみたいで面白いねこれ
ps1内でおもむろに
Add-Type ... @'
F#スニペット
'@
と書いてすぐ走る利便性すごい
けどやっぱりsdkがでかい…
複数言語の処理系入ってると思えばでかくないかもしれないけど
でかい ヒアストリングはエディタに文字列扱いされてハイライトも補完も効かないので分けてGet-Contentしてる
ソラで書ける程度ならいいけど いいと思うよ
大体の人は1ファイルに収めたいからヒアドキュメント使うわけで >>395
F#登場時に『OCamlを参考にした』ってよく紹介されてて、それで初めてMLの存在を知ったわ
F#走らせるだけならSDKまでいれなくてもF#のランタイムだけで動作するはず
pwshオンリーの環境で試したこと無いから、だめかもしれんけど
でも、add-typeしてF#動かせるならf#スクリプトも動くと思うんでpwsh経由にする必要ないんでわ? F#は見た目キレイなocamlで好きだよ、;で諦めた
インラインは読み込み時に都度メモリ上にコンパイルするので、初読み込み時のオーバーヘッドはあるかと
まあdllやら作り直すより楽なので、困るまではインラインでいい
なんなら@"で文字列補間できるしな 遊ぶくらいだけど困ったらpwshで生やせるメンバをニョキっとできるしな
公式サイト見るとdiscouraged styleだけど
ドマイナー言語だけど入門にはちょうどいいかも function ConvertTo-Hoge($source) {
Write-Output '次のファイルたちに対して処理を実行します。'
Get-ChildItem -Path $source -Recurse
# 外部コマンドによる処理。
hoge.exe $source
}
ConvertTo-Hoge 'c:\data\source.txt'
上記のコード内のGet-ChildItemで取得されるのは、引数として指定した
c:\data\source.txt
だけと想定していましたが、実際は、
c:\data\SUB_FOLDER\source.txt
といったサブディレクトリ内の同名ファイルも取得されてしまいます。
ファイルを指定した場合は-Recurseパラメータが無視されると勝手に思い込んでいたので、
こういうかたちで再帰的な取得をするのは面食らいました。
ファイルを指定した場合に再帰取得を抑制する方法はないでしょうか。
'c:\data\' や 'c:\data\*' といったパスを渡すケースもあるので
-Recurseパラメータを外したり、-Pathを-LiteralPathに換えるわけにはいかないです。 Powershellのコマンドレットにはあまり期待するな >>404
当たり前でしょ
c:\data\source.txt がファイルかどうかは調べるまでわからないんだし
そもそもc:\data\source.txtがなくてc:\data\SUB_FOLDER\source.txtがあるならc:\data\SUB_FOLDER\source.txtは欲しいんでしょ?
> ファイルを指定した場合に再帰取得を抑制する方法はないでしょうか。
指定したのがファイルなら-Recurse外せばいいだけじゃないの? >>405
そんなあ…。
>>406
ありがとうございます。
Get-ChildItemの前に検査するしかないんですね。
なお、c:\data\source.txt も c:\data\SUB_FOLDER\source.txt も両方存在しています。
Get-ChildItem -Recurse で両方を取得してしまいますが
SUB_FOLDERの方は処理から除外したいやつで欲しくないのです。 Get-ChildItemのオプションは沢山あるからよく調べて除外指定すりゃいいし
パイプでWhere-Objectに渡して要らないのをフィルタするという手もある $a = @(Get-ChildItem -Path $source -Recurse)
$target = if ( $a[0].Name -eq $source ) { $a[0] } else { $a }
するぐらいかなぁ
要件満たせてるのかわかんないけど Get-ChildItemのオプションで除外するかWhere-Objectでフィルタか
両者にはどんな得意不得意があるの? >>408
自分が理解できる範囲でオプションを組み合わせてもうまくいかなかったのですが、
そういえばパスに*が含まれる場合は-Path、そうじゃない場合は-LiteralPathにすれば
想定する動作になるのかなと思いました。
コードが手元にないのであとでやってみます。
Where-Objectに渡すのは、すみません今回の場合にどうフィルタするのか想像つきません。
どうもありがとうございます。
>>409
これでうまくいきそうに思います。
*の有無で分岐するのと両方を試してみたいと思います。
どうもありがとうございます。 >>411
こんな感じでよくない?
Get-ChildItem -Path $source -Recurse:(Test-Path $source -PathType Container)
hoge.exe の仕様にもよるけれど、-File とかも指定しないと変かも。 >>412
こういった、パラメータの後ろに:をつけてオンオフを切り替える書き方を知りませんでした。
この方法でもできそうなので試してみます。
勉強になります。
どうもありがとうございます。 >>412
$sourceにワイルドカード含まれてたら意図した動作にならないかと思ったけど、そんなことない? >>411
ワイルドカードが含まれない場合でもフォルダー指定ならrecurseが必要なんじゃない? そもそも >>404 で無条件にgciに渡してるとこからおかしいと思う
1. まず$sourceにワイルドカード文字が入ってるかどうかを判定する $source -match "[\*\?]"
2. 次にディレクトリ指定かを判定する Test-Path $source -PathType Container
3. そうでないならファイル指定かを判定 Test-Path $source -PathType Leaf
4. これ以外はエラーとする
1と2のケースならgciに掛けて除外したいものをWhere-Objectでフィルタしながら処理する
gci $source -recurse | ?{ $_.FullName -notlike "*SUB_FOLDER*" } | %{ hoge.exe $_.FullName }
3ならそのまま処理する hoge.exe $source
自分ならこんな感じで書くかな >>416
そうですね・・・。
*(ワイルドカード)の有無で分岐する場合は、
Get-ChildItem -Path $source -Recurse #ワイルドカードあり
と
Get-ChildItem -LiteralPath $source -Recurse #ワイルドカードなし
というふうに両方に-Recurseをつければいいと思いますが、
-Recurseをオフにしちゃうとたぶん想定と違う挙動になりますね・・・。
実際のコードで検証してみます。
ありがとうございます。 リロードしてませんでした…。
>>416
想定外の文字列が渡されたケースなどを何も想定せずにいました…。
hoge.exeの引数は、ファイル1個でも、スペース区切りの複数ファイルでも、
フォルダでもワイルドカード付きでも受け取ってくれて処理してくれるのですが、
具体的にどのファイルに対して処理されたのか不安な時があるので
gciによりプロンプト上で確認したいというのが>>404のコードの意図なのですが、
よく考えたらgciの結果と、hoge.exeが処理するファイルが同じになるとは限らないので
筋の悪いことをしていたような気がしてきました。 409ので最初のgciにfileオプション付けたらやりたいことできてない? >>419
自宅のPCでやってみたらうまく行かなかったですが(再帰的に取得されてしまう)、
うろ覚えの再現をして何か間違っているかもしれないので、週明けに実際のコードで試してみます。
ありがとうございます。 $sourceがファイル名でなくパス指定だとうまくいかないので
$a = @(Get-ChildItem $source -Recurse -File)
$target = if ( $a[0].Name -eq (Split-Path $source -Leaf) ) { $a[0] } else { $a }
とすべきでした .ps1スクリプトをタスクバーにピン留めして実行たいのですが皆さんどうしてますか >>422
引数付きのpowershell.exeショートカット作ってピン留めしたら? 漏れは、デスクトップにショートカットを作る
例えば、WSL2, Ubuntu 18.04 を起動して、
作業フォルダを、Linux 側にあるプロジェクトフォルダに移動してから、
VSCode で、そこを開く
リンク先
C:\Windows\System32\wsl.exe code .
作業フォルダ
\\wsl$\Ubuntu-18.04\home\ユーザー名\proj01 >>424
「powershell.exe」でショートカット作成
引数を追加
タスクバーにピン留め
でいけました
ありがとうございます! Windows11入れたけど、PowerShellのバージョンが7.0.0-preview.3になってる
5.1も5.1.22000.1として使える おー、やっぱOS同梱するんだ
ライフサイクルの違いをどう吸収するのか興味深々 >>387
想像つかない…どんな書き方なのか教えてもらえませんか? >>428
Powershell7は.Netごと自動更新にするんじゃね
仕様が変わっちゃいけない用途はPowershell5.1で こっちの環境だとPowershell7はインストールされてないな
5.1.22000.1はインストールされてるけど 11出るのかよ
ずっと10でアップデしそうだから安心と思って10のライセンス買ってしまったぞ >>433
サンキュー、出てるの全く知らなかった…
昔は新バージョン出る時アキバの行列報道とかあったけど、テレビも(AFAIK)無反応だな 素人ですいません
デバイスとプリンターの中にあるスマホ「sh-08」をBtのアクセスポイント接続させるのは
コマンドラインではどう書けばいいんでしょうか? Connect-Me sh-08 -Through Bluetooth Windows PowerShellでBluetoothを接続および削除する方法
https://base64.work/so/powershell/1664979 ヒントありがとうございます やっぱちょい難しそうですね 昇格されたアクセス許可が必要って時点でもう何か違うような get-wmiobjectでインスタンス見つけて接続すりゃいいんだろうけど、PC側からスマホに接続するって、どんな用途なのかな?
スマホ側の写真をPCに転送するぐらいでしかBluetooth使ったことないので、なんか便利なこと出来るなら教えて欲しい 普段の回線だと5ch規制で書けないのでBtテザリングのスマホ回線に切り替えるわけですが
いちいちスマホのアイコンを右クリッタするのが面倒なのでバッチファイルで接続できないかなと
メトリック値の書き換えで回線切り替えるのはできてるんですが なるほど
常に接続してるなら静的ルート設定するなりしておけばいいんだろうけど、スマホだとそうもいかないから、書き込むときだけモバイル回線使うようにしたいってことね スマホのアイコンの右クリックとかの操作をするだけならシェル名前空間の範囲でできそうだね
$shapp = new-object -com "Shell.Application"
$folder = $shapp.Namespace([System.Environment]::GetFolderPath("desktop"))
foreach ($item in $folder.Items()) {
if ($item.Name -like '*スマホ名*') {
foreach ($Verb in $item.Verbs()) {
if ($Verb.Name -like '*接続とか何とか*') {
$Verb.DoIt();
}
}
}
} カスタムオブジェクトを返すコマンドレットを作って戻り値を変数に割り当てた時、
変数名の後にメンバーが補完される場合とされない場合があるんだけど何が基準なんだろう? >>231
実行ファイル名の変更はマジで影響でかそうだよね。
例えばリモートデスクトップだって実行ファイル名はいまだに大昔の
mstsc(Microsoft Terminal Services Client の略称)のまま変えてないというのに。。 .NETのサポート期間はLTSでも3年なので、今後もしWindowsに標準で入れるなら3年ごとにWindowsUpdateで破壊的変更が入るという冗談のようなシェルになる
どうせ誰も移行しないんだから問題ないよ このスレに来るくらいのヘビーユーザー以外は大した移行コストを払うほどスクリプトを書いてないんんじゃね
少なくとも俺が書いたスクリプトは修正した記憶がない 何年か前からアナウンスしても移行が破綻するほどに互換性が皆無なら、言語そのものが致命的な破壊的変更すぎるということだし
そうでないならどこかのタイミングでエイリアス化してもそこまで困らない
ちょうどいまのIEとEdgeに似た状況なのでは powershellってスクリプトそれ自体が資産というよりは、特定の環境とセットで動きゃOKな書き捨てスクリプトがほとんどだろうから、
現実には.NETランタイムもpwshも自分で入れてサポート期限なんか無視してバージョン固定で塩漬けだろうね
むしろ勝手に更新される心配がない分嬉しいまである
社用端末のログインスクリプトだったり、厳密にサポート期限を気にして更新していかなきゃいけないような案件だったら使い物にならんわな >>453
>社用端末のログインスクリプトだったり、厳密にサポート期限を気にして更新していかなきゃいけないような案件だったら使い物にならんわな
夜間バッチをbatで書いてたのを全部powershellに書き換えた企業とかあるけど、後悔あとに立たずだろうなあw そんな古臭い現場が移行するわけないでしょ
最終的にはps6以降のシリーズよりもps5の方が長くサポートされるだらうから何の問題もないよw 互換性がどの程度でメンテや疎通のコストがどれほど必要になるのかを考えずに騒ぐのってどうなの
ワクチンの0.0014%の死亡率を見て、危険!ありえない!と叫ぶような非論理性を感じる コストは連続じゃないからね
実務経験あるならわかると思うけど、更新しなきゃいけない、更新したら壊れるかもしれない、最低限動作確認しなきゃいけない、
そういうことを考慮しなければならない時点で大きなコストなんだよ
その定量的な頻度や程度はあまり関係なくて、定性的にあるかないかで非連続なコストが発生するの Powershellでどんだけ巨大なシステム組んでんだろw pwsh.exe、psh.exe、ps.exeと3年毎に名前が変わったら俺もキレると思う >>458
結局、それが「考慮しなければならない」とか「定性的にあるかないか」っていう判断をするボーダーラインがあるって事だろ
>>457が言ってる程度の問題と本質的に変わらない コンソール無し版のpowershellwはまだですかいのう ISEは便利そうと思いつつ放置してるんだけどpwsh7xも使えるっぽいとどこかで読んだ
試してみるか なぜいまISE?
msはISEの開発を止めてVS Codeに軸足を移してるから今始めるならVS Codeじゃないのかな
統合エディタだから学習コストも増えるけどモダンエディタを知らずに過ごすのはそれはそれでもったいない >>467
VSCodeでデバッグしてると、たまに挙動おかしくなる(ブレークポイントで止まらなくなったり)んだが、ISEだと問題なかったりする。
こういうときは諦めてISE使うしかないの? >>460
unix系だとシバンで困る
7系をパッケージマネージャで入れるとパスにはpwsh-previewなる実行ファイルが置かれる
8になったら今度はそれがpwsh-previewだろうし
せめてpwsh7とか、あんまり攻めない内容ならpwshでざっくり指定させて欲しい
勝手にni pwsh -target pwsh-preview -itemtype symboliclinkしてるけど 単にブレークポイントまでたどり着いて無いんじゃないのか
VSCodeで実行毎にPowerShellの環境作り直してくれる機能がないとデバッグできないわ (1 -eq 1 -eq 1) #True
(1 -le 2 -le 3) #True
(1 -lt 2 -lt 3) #False
何で3行目だけTrueではなくFalseになるの?誰か教えて 1 -lt [int](2 -lt 3) って扱いになってるのかな 比較演算子の左がブール値なら右の値もブール値として扱われるから0以外は全部trueになるってことやろね .NetCore版って起動の高速化できないのかな
自分で使う分にはいいんだけど、スクリプト使ってもらう時に不安がられる なんかしら起動中の表示してくれたらいいんだけどな
batファイルからPowershellスクリプト実行すれば似たようなことできるが、そのために態々batファイル作るのなんか嫌だ スクリプトに一行足して拡張子.batにするだけだと思うけど、何が嫌なのかな? >>479
よく読んだら「スクリプトに一行足して拡張子.batにする」って
Powershellスクリプトをbatファイルとして保存して実行する方法があるって事? > やってることは、両方ともバッチファイルの中で自分自身を呼び出して、その呼び出す記述を呼び出す側で無視するという感じ。 Rustのメモリ安全性はボローチェッカーによって担保されているが、
Nimと比較してRustはタイプ量が多い事により限りなく低い生産性と
C++のような高い難読性、超巨大なバイナリ生成性能を兼ね備えています
Nimはバージョン1.5.1でRustのボローチェッカーに似た「View types」が実装されれば、
GC無しのView typesで参照の有効性を検証することによってメモリ安全性を保証しつつ
限りなく抑え込まれたタイプ量で高速化したCのソースコードを吐き出せます
Nimソースコード ==nimコンパイラ==> Cソースコード ==Cコンパイラ==> バイナリ
なので、nimコンパイラが通った時点でメモリ安全性が担保されませんか?
Nimの実験的特徴 バージョン1.5.1
http://nim-lang.github.io/Nim/manual_experimental.html
第二プログラミング言語として Rust はオススメしません Nim をやるのです
https://wolfbash.hateblo.jp/entry/2017/07/30/193412
Nimは限りなく抑え込まれたタイプ量で高い生産性とPythonのような高い可読性を実現し
ているにもかかわらず、高速なCのソースコードを吐き出せるのでC言語でリモートワーク
されている方は割り振られた仕事が早く終わっても終わってないふりをして怠けることができる
「怠け者とはこうあるべきだ!」と言うとても大事な事を Nim は我々に教えてくれます batから呼び出す奴はこんなのもあるね
ttps://reosablo.hatenablog.jp/entry/2016/07/09/193617
.batのセキュリティゆるゆるなのを利用して実行権限無しでpowershellスクリプトを走らしちゃう感じらしい 簡易版はホントに短くまとまっててよいですね
今度から俺もこっちにしよう すげーなこういうのよく思い付くな
知ってしまえば簡単な仕組みだけど、
単一ファイルで動かすって発想がなかったから素直に感心する ExecutionPolicyを指定してこんな感じかな
@powershell/exe un /nop '#'+(gc \"%~f0\"-ra)^|iex&exit/b こうか
@powershell/ex u /nop '#'+(gc \"%~f0\"-ra)^|iex&exit/b 例えば漏れは、デスクトップにショートカットを作って、
ダブルクリックで、Ruby スクリプトを起動してる。
同様に、PowerShell スクリプトも起動できないの?
リンク先
C:\Windows\System32\cmd@.exe /k "ruby C:/Users/Owner/Documents/a.rb"
注意。投稿できないので、間に@を入れました
作業フォルダ
C:\Users\Owner\Desktop >>491
だからrubyキチはバカって言われるんだよ >>491
1ファイルで実行したいって言ってるのにショートカット作るのかよw てすと
C:\Windows\System32\cmd.exe バッチファイルに埋め込むときはシフトJISにしないといけないのがチョイ面倒ですね
昨今だとメモ帳もutf-8ですし コードページ変更っていろいろ罠があったような…
フォントを変えておかないとダメとか
コマンドの一部は期待どおりに動作しないとか シフトJISにしておけばget-contentでエンコーディング指定も不要なので、まぁ、いいかなと
VS codeでオープン時or保存時にシフトJISにするだけですし $PSDefaultParameterValue["*:Encodings"] = "utf8NoBom"にしてるけど大体大丈夫だ
コマンドレットには全て暗黙に渡るので一貫性は保てる
Core 6/7だと空でもこれがデフォルトのはず
cmdはレジストリのどっかでchcp 65001指定した、とりあえず今まで問題はない、気がする utf8は低レベルでの扱いがめんどいから、固定長utf-32か、ほぼ固定長のutf-16が流行ってくれた方が嬉しかったんだけれども… 非圧縮だと通信速度が4倍遅くなる可能性があるけどよいか? デコードに結構計算要るし、最悪ケースで一番容量食うのはutf-8だったりするので、俺はそのへん懐疑的
まあ普及してしまったものは仕方ない パイプでネイティブコマンド繋いだりすると化けることあるな
普通のは大丈夫、less.exeとかmingw64配布のネイティブバイナリが怪しい?
sasp を付けて流し込むと直る模様、エンコ調べてハードコードより手軽かつ変更に強そうなのでおすすめ preference variableのエンコード指定はコマンドレットに適用されるので、native.exeは面倒見てくれないけど、saps exe -nonewなら見てくれる
ってことかな win用ページャはvimがいい
マニュアル読むにもデフォルトでpowershellのシンタックスハイライトあるし、読み書きエンコードがコマンドラインオプション指定できて、高度なコマンドも渡せるフィルターとして使える vs code使ってるから、インテリセンスで大体事足りるし、ショートカットキーでオンラインヘルプがブラウザでひらくから、あんま困ったことないかなぁ フィルターというと
gc file |vim - -Es -c ":set fenc=sjis" -c
%p | ...
みたいな使い方か、nkfでもいいけど
sedが多バイト文字怪しかったりbom有りで死んだりするのでvim -c "s/foo/bar/g" -c "wq"で、文法がほぼ同じなvimで代用したりはする
機能的にはsedの上位版ではあるけど、一度バッファに全て読み込むのでスケーラブルじゃないね
先読み後読み駆使した複雑な正規表現ではコンパイルして使い回せるpwshに軍配が挙がる 初心者ですが、PowerShell でスクレイピングしたいので正規表現について教えてください。
$aa = Invoke-WebRequest https://www.epson.jp/products/colorio/ep982a3/spec.htm
$bb = [Text.Encoding]::GetEncoding("UTF-8").GetString( [Text.Encoding]::GetEncoding("ISO-8859-1").GetBytes($aa.Content) )
$cc = ($bb -replace '<[^>]+>','')
$dd = $cc.split("`n").trim() | ?{$_ -ne ""}
$dd | more
:
消費電力
約17W(スタンドアローンコピー時)
電源電圧
AC100V 50/60Hz
外形寸法(幅×奥行×高さ)収納時
479×356×148(mm)
外形寸法(幅×奥行×高さ)使用時
479×668×295(mm)
質量
(注)本体のみ
約8.5kg
:
電源電圧 をキーとして、
AC100V 50/60Hz
質量 をキーとして、
約8.5kg
正規表現でマッチした次の行、次の次の行を得るには どう記述すればいいでしょうか? $aa = Invoke-WebRequest https://www.epson.jp/products/colorio/ep982a3/spec.htm
$bb = [Text.Encoding]::GetEncoding("UTF-8").GetString( [Text.Encoding]::GetEncoding("ISO-8859-1").GetBytes($aa.Content) )
$cc = ($bb -replace '<[^>]+>','')
if ($cc -match '電源電圧\r\n *(.*?)\r\n') {
$Matches[1]
}
if ($cc -match '質量\r\n.+?\r\n *(.*?)\r\n') {
$Matches[1]
} カッコのネストに対応してないのが気になる
正規表現はテスターサイトが色々あるから、とりあえず、色々試しながら覚えるのが手っ取り早いと思う
.netの正規表現ならregex stormが老舗
昔はよくお世話になってました 大昔awkで書いてた時にマッチしたら次の1行読むって処理にしてたのを思い出した Seleniumの勉強中なのでSelenium版
$Driver = Start-SeFirefox
Enter-SeUrl 'https://www.epson.jp/products/colorio/ep982a3/spec.htm' -Driver $Driver
$Element = Find-SeElement -Driver $Driver -XPath '//th[text() = "消費電力"]/following-sibling::td'
Write-Host $Element.Text
$Element = Find-SeElement -Driver $Driver -XPath '//th[text() = "質量"]/following-sibling::td'
Write-Host $Element.Text
$Driver.Quit() playwrightもpowershellともう少し親和性高いアセンブリ用意して欲しいところ ランチャーからPowerShellのスクリプトを実行したいのですが、以下のコマンドラインだと警告が出ます。
powershell -ExecutionPolicy RemoteSigned -f Y:\ps\hoge.ps1
> セキュリティ警告
> 信頼するスクリプトのみを実行してください。インターネットから入手したスクリプトは便利ですが、コンピューターに危害を及ぼ
> す可能性があります。このスクリプトを信頼する場合は、この警告メッセージが表示されないように、Unblock-File
> コマンドレットを使用して、スクリプトの実行を許可してください。Y:\ps\hoge.ps1 を実行しますか?
> [D] 実行しない(D) [R] 一度だけ実行する(R) [S] 中断(S) [?] ヘルプ (既定値は "D"):
警告を出さずに実行するにはどうすれば良いでしょうか。
Unblock-File -Path Y:\PS\hoge.ps1 は実行しています。 ランチャーってのが何を指してるのかよくわからんけど
HKEY_CLASSES_ROOT\SystemFileAssociations\.ps1\Shell\0\Command
でGet-ExecutionPolicyの結果がAllSignedでない時はSet-ExecutionPolicyしてるから,そのせいでは? >>516
XPath を使っているの?
CSS セレクターも使えるの? tasklistの/fi “status eq not responding”を毎回入力するのがくそめんどいんだけど省略形ってない? >>524
遅くなったがエイリアスで解決したわサンクス
しかしbashやzshなら便利なエイリアスが最初からたくさんあるのにPowershellって本当に使い辛いな
特にPascal CaseとKebab Caseで命名されてるCmdletのクソさが半端じゃないわ PSスレで質問に答えてもらって感謝しつつPSをめいっぱいdisって周囲をイラつかせてから去っていくスタイル
これは天然だなw そもそもbashに標準でエイリアスなんて定義されてなくね?
ディストリビュータが各々初期設定用意してることはあるが
優しいdebian系で両方使ってるけど、ls, grepに--color=auto付けるのと、オプション付けた変種のll, egrep, fgrep etc.で多分一桁だと思う
pwshはコマンドレット自体はもちろん、パラメータにもエイリアスの概念があって便利よ
標準では接頭語で定義されてる、曖昧さの生じない限り受け付ける
例:-OutputVariable、-ErrorActionは-ov, -ea等、-Name/-Countは-n/-c等
なんなら-na/-nam/-counでもよい、キモいけど
そもそも毎回パラメータ渡すのが面倒なら、暗黙に渡すようデフォルト設定できるぞ(about_Parameters_Default_Value) ネイティブコマンドは/?を見てシグネチャを書き写し、引数丸投げするツーライナースクリプトを用意すると便利よ
パスに置いておけば勝手に補完が効くので、保管用ディレクトリを作っておき、コマンドラインからリダイレクトで適宜追記してる
自分でオプション文字列をパースするロジックを書き、それをcompletionコマンドで登録していく方式のbash_completionより便利 あとwin限定だけど、tcsh-likeな伝統的aliasコマンドが好きならdoskey コマンドが全く等価
doskey ls=dir /ad
のように使う
名の示す通りレガシーかつunix/linuxと$profileが共有できないので、*-aliasか、シェル関数を推奨 doskeyは外部コマンドだからpwshからも使えるはずだけど、f7でのヒストリ表示とかが効かん
古いコンソールAPI使ってTUIレンダリングアップするからターミナル依存かも? win/coreならヒストリが少なくとも3つあるので競合してる可能性が大
doskey /hと同様にpowershellビルトインのヒストリもF7で表示されることになってるけど、PSReadlineをロードしてれば実際はそっちに吸われる
試しにremove-moduleすればわかる、設定弄って共存も可能とは思うけど、素直にPSReadlineがいいと思うけど
doskey自体は完全にシェル非依存、mingwのsh.exeですら使える事を確認済
/execmd=sh.exe, pwsh.exeの指定を忘れずに そしてPSReadlineのデフォルトではF7にヒストリ表示をバインドしてないので何も起きない
Set-PSReadlineKeyHandler -Key F7 コマンド
でバインドできるのでビルトイン、doskey、その他お好みのを doskeyは標準コマンドだしちょっとしたコンソールアプリにラインエディット機能付けるのに未だに便利だったりする
readlineやlinenoiseは大げさ過ぎるし、rlwrapはwin環境に入ってない事が多いし windows 11でPSCore7が標準装備になるらしいし、気兼ねなくPSReadlineでインタプリタとか書けるようになるんかね psのコンソールでVZエディタのファイラーみたいにファイル選択できるのありますか? 俺はvimのnetrw(標準プラグイン)使ってるな
unix/linuxなら大体入ってるし、winでもwinget install vimだけで導入が楽、同じように使えるのがよい
プロトコルもcurlを使うのでwinならscp等殆ど使える、linuxでは標準コマンドじゃないけど、まあ大体入ってるでしょう
ブックマーク、複数選択してまとめて移動、パターンで一括リネームなど地味に高機能でおすすめ コンソール上でコマンドレットに複数の引数をパイプラインで渡したいとき、一々
$temp = New-TemporaryFile
notepad $temp
cat $temp|渡し先
rm $temp
ってやってるんだけど、一々一時ファイル作るのが面倒です
・実行するとテキストエディタが開く
・保存して閉じたら、その内容が改行で区切られてパイプラインに渡される
・保存したファイルは勝手に消える
みたいなのをやりたいのですが何かいい方法はないでしょうか。
vimとやらでいい具体に出来そうな気がするのですが 書いてる一連の処理をスクリプトにまとめるのではダメなの? エディタで編集したいってのが要件でないのなら、powershellのコンソールから配列作ってパイプに渡せばいいんじゃない? 配列だとクォート面倒だからヒアドキュメントの方がいいか そもそもテキストエディタ使う時点わけわからん
普通にこんな感じでカンマ区切りで複数の値ぶち込んで一行で終わりで良くね
"値1","値2","値3","値4"|コマンドレット 一時ファイルを要求してるのはpwshじゃなくてnotepadの方だからなあ
formsで複数行入力できるテキストエリアでも作ったらいいんじゃないの すいません
$temp = New-TemporaryFile
notepad $temp
部分をbegin、
cat $temp
部分をproccess、
rm $temp
部分をend、
にそれぞれ設定したコマンドレット作ったら解決しました。
>>543
スクリプトならともかく、毎回"a","b",ってやるの大変過ぎません・・・?
テキストエディタで書けばコピペやちょっとした編集も出来るし便利だと思ったんですが 542も書いてるけどヒアドキュメントでいいのでは?
PS C:\> -split @"
>> りんご
>> ゴリラ
>> ラッパ
>> パンツ
>> "@ |% { $_ * $_.length }
りんごりんごりんご
ゴリラゴリラゴリラ
ラッパラッパラッパ
パンツパンツパンツ
普通にコピペもできるし >>535
> windows 11でPSCore7が標準装備になるらしいし、
どこの情報?
Previewにあるのは正式版ではごっそり消えることあるよ >>535
Windows11いれてみたけどPowershellは5.1で、pwshコマンドはないな…。 >>1
>>301のリンク先にPowerShell のサポートライフサイクル書いてあるよ
>PowerShell Coreサポート終了日
7.1 2022 年 2 月中旬 (予定)
7.0 2022 年 12 月 3 日
6.2 2020 年 9 月 4 日
6.1 2019 年 9 月 28 日
6.0 2019 年 2 月 13 日
このドキュメントでは、PowerShell Core のサポートについて説明します。Windows PowerShell (1.0 から 5.1) は、Windows OS のコンポーネントです。 コンポーネントは、親製品または親プラットフォームと同様のサポートを受けます。
PowerShell 7.1 (現在) .NET 5.0 (最新) 上に構築されています。
PowerShell 7.0 (LTS) .NET Core 3.1 (LTS) 上に構築されています。
PowerShell 5.1 Windows 10 Anniversary Update および Windows Server 2016 でリリースされました。
PowerShell 4.0 Windows 8.1 および Windows Server 2012 R2 に統合されています。 Windows 7 SP1、Windows Server 2008 R2 SP1、Windows Server 2012 にインストールできます。 .net (core) に紐付くpwshとOSに紐付くpowershellか
11がpwshのみになったら、結構なインパクトだね まさかpowershellがこんなに早く泥沼レガシー化するとはな
まあPowerShellが成功したことの裏返しではあるが まだ、pwsh一本になるかわからんのでは?
まぁ、自分はpwshになっても困らんけど >>553
powershellにどっぷり依存したスクリプトは死亡か 2年弱で開発会社から使うなと言われる言語/バージョンなんて使えねぇ。
ソフト開発中に期限切れになる。 Windows PowerShell 5.1使っておけばいいんじゃね >>557
それじゃあJavaが糞みたいじゃないか
https://www.infoq.com/jp/news/2021/08/java-17-glass/
多くのチームが6か月サイクルのメジャーリリース番号と一致するようにJavaバージョンをアップグレードしているという証拠はない。
New Relicの顧客ベース(数千万の本番JVMを含む)のデータによると、LTS以外のJavaバージョンが1.5%を超える市場シェアに至ったことは一度もない。
LTS以外のJavaバージョンのほとんどは、リリースから数か月以内に、0〜0.5%に低下する。
むしろ、市場全体としてはJava 8と11を使用し続けている。これには、Oracleから離れ、8と11の増分更新の提供を別のベンダーに依存している場合も含まれる。
現在、2つのLTSバージョンが市場シェアの二分しつつある(統計的なノイズレベルを下回る非LTSバージョンもある)。
これは、Java 8が普及した速さと比較して、Java 11の普及がはるかに遅いことを表している(3年で約50%の市場シェア)。 >>559
Javaはクソだし脱Oracleの流れは相変わらず進んでるしで未来はないだろ
代わりの効かない言語でもなくなっちゃったし そりゃまだCOBOLメインテナンスしてるとこもある 短期のリリースサイクルが困るならLTSのみ使って、インターネット接続がない特殊な用途なら、別途、MSと相談かwindows使わないことを検討したほうがいい
まぁ、ちょっと前だと新生銀行のATMとか、最近でもデジタルサイネージで再起動促すダイアログでて止まってたりするの見かけたけど
普通の使い方ならバージョン固定にしてセキュリテイパッチあてない運用は取り得無いから、ガンガン更新するしかないよね ISO 規格になってる言語は安心だな。
古い規格で作成したシステムも、いつまでも正々堂々と使える。
使うなとは誰も言わないし、ライセンス料も請求されないし、訴訟も起こされない。 後方互換もばっちり。
Java は 1CPU あたり年60万円請求される。 マルチCPU、クラスタシステム、マルチサーバならサーバ側だけでも途方もない金額になるし、
それに加えクライアントPCにも使用者指名ごとに料金が発生する。 > ISO 規格になってる言語は安心だな。
やはりC#の勝利か
ISO/IEC 23270:2018
Information technology - Programming languages - C#
https://www.iso.org/standard/75178.html C#の規格って全然更新されてなくて、実質的に全く意味をなしてないぞ 標準規格は「存在している」ことに意味がある
Rubyなんかもそうだけど、実際には更新されてなくて規格自体の利用価値は皆無だとしても、採用を後押しするための営業トークとしては有効だ
実際564や565は騙されてるわけだしな >>564
今はJRE使わない選択もできるけど、
新規はOracleと関わるの避けるだろうからJavaは緩やかに死んでいくと見た OpenJDKで何一つ困ってないからなあ
Oracleがライセンス変更で一儲け狙ったのに、AmazonとかのOpenJDKのディストリビューションにJava市場がごっそり流れた
焦ったOracleがバージョン17から少しの間無償に戻しますんでどうかまた使ってくださいと懇願中(今ここ)
OracleJDKの有償サポートを望んでいる顧客がほとんどいなかったという結論が出たのでOpenJDKさえあればいい Java の 3rd デベロッパを排除するため、Oracle が Java に機能追加して、
OpenJDK などのプロジェクトが Java に準拠していないと嫌がらせ訴訟することはできる。
Oracle が Microsoft に Java 訴訟したときの言いがかり内容は違うけど、同じ手法を使わないとは言えない。
スレチだから そろそろおしまい。 WinRMはいつまで生き残るんだろうね?
OpenSSHに取って代わられることになるのかなぁ >>545
そこでcmd |vim -Es -c ':g/re/p'
>>574
sshもwinRMも気兼ねなく両方使えばいいのでは
unixとlinuxが接続先ならssh、rshにpwshを設定するのはあまり想定されてないのか設定がちょっと面倒
だとしても、両方標準でサポートしてるwinはやはりunix/linuxよりリモート向きOSだと思ってます 適当なのを探すのが面倒でリマインダーアプリをpowershell(C#)辺りで作ろうかと思うんだが
UIをwinformにするかWeb系にするか迷ってる ver7.1のConvertFrom-Jsonで取得したPSCustomObject/Hashtableが
{ "name"="foo"; "count"=1}
となっていて、key名に"count"が使われている為、
$v.count
$v['count']
等の値の取得でエラーになってしまうんですが、どうにか取得する方法は無いですか?
自分にはjsonの原文をreplaceするぐらいしか方法が見つかりませんでした。orz すみません。別の理由でエラーが出てたみたいで、ちゃんと取得できました。
申し訳ないです。 名前被ってても普通に$hash.count/$hash["count"]で.Valuesのcountが引かれる筈だけど、それがハッシュの文法なので
むしろコレクションのpropertyのCountが隠されるのが問題、こちらが確実に欲しければ$hash.Values.Count等と書くのが安全
$hash.Keys.countも同じ値を返すけど、これはKeysからキー"count"を引いてるように読まれる可能性が高いので勧めない >>581
$hash = @{Values = @{Count = -1}} とかだと、駄目だよね。
これ、本当に確実に取得するのは、わりと面倒なのかも。普通の使い方なら、
$hash.get_Count() とか、$hash.psbase.Count とかでいいとは思う。でも、
$hash | Add-Member ScriptMethod get_Count {-1} -Force
とかされると、get_Count() は使えなくなる。
$hash | Add-Member NoteProperty psbase @{Count = -1} -Force
とかはエラーになるけれど、
$psbase = New-Object Management.Automation.PSNoteProperty psbase, @{Count = -1}
$hash.psobject.Members.Add($psbase, $true)
とか強引に追加すると、妙なことになって、psbase.Count も使えなくなる。
本当に確実そうな方法は、(New-Object hashtable $hash).psbase.Count とか、
$hash.GetType().GetProperty('Count').GetValue($hash) とか? powershellのcd (Get-Childitem)には、CDPATHに相当するもの(か概念)って無いのでしょうか?
(行きたいディレクトリに簡単に行けなくて 不便を感じてるのですが) >>584 情報ありがとうございます
まぁたしかに 何でも「つくればある」のだから、自分なりに工夫してみようかと思いました >>583
ついでに言えば…Set-Location の間違いでした (笑) 使い始めて二日目なもので... ディレクトリをSet-Locationしたら.NETのAPI側も合わせないとずれたままだぞ
だから次のような2行書いとく習慣付けるといいかも
カレントパス指定なんてめったに使わないけど
Set-Location -Path パス名
[IO.Directory]::SetCurrentDirectory((Get-Location).ProviderPath) それこそGetCurrentDirectory使うときだけの話だよな
対話的にSet-Location使う程度では必要ないだろう
べつに(pwd).Pathとかも渡せるし
CDPATH
pwshでそんな移動しまくらないからワイには必要ないな 適当に$CDPATH=Get-Locationとかやってりゃいいんじゃない? 一旦powershellで作ったはいいものの
起動が遅くてバッチやvbsで作り直す
常駐物ならC#で書き直す 一旦powershellで作ったのはいいものでした PowerShellの起動が遅いと思うような環境ならC#アプリの起動も遅そうな気がするんだが >>593
バッチやvbsだとpowershellが起動するまでに処理が終わってるし
C#に関しては話にならんほど差が出る
powershellの起動の問題は.NETランタイム以外にあるんじゃないの
サクっと作れるのは評価するが本番運用ではとても使えない 起動時間シビアに気にするような本番運用ばかりじゃないしな ネットワークが遅いのでは?
起動時にインターネット接続見に行くので、ネットワーク遅いと辛いことに
スクリプト実行するだけなら、noprofile, noninteractive付けると良いですよ PowerShellの起動が遅い人はプロファイルで時間がかかる処理してるんじゃないの イニシャルローディング時間が遅いだけで初回限りの現象なのでは? ネットワーク見てたのchocolatyのプロファイル読んでたからでしたわw PowershellでExcel操作できるの素晴らしくて信者になりそう
VBAやったことないけどVScodeで書きにくいってだけで敬遠する 流石にVBAの方が使いやすいぞ
でもpwshでやるのが好き ExelがインストールされてるならCOM経由で操作できると思うけど、インストールされてない環境ならC#用のライブラリ使う感じかな チャートぐらい.NETの機能で描けるしExcelもVBAもいらない excelはやたら高度な因子分析機能やソルバ(非線形、進化的最適化)ついてるから侮れない チャート描くのが目的なら使わなくていいんじゃない?
Exelの資料を編集するのが目的なら、COMかライブラリ使うしかない エクセルよくわからんけどA.xslxのあるセルの値をB.xlsxのある場所に移す簡単なプログラム依頼されてて、VBA使えばできるんだろうけどわざわざシートにバインドされたマクロ書くのが無駄に感じるからpowershellで済ませようとしている...ダメ? >>611
誰もポストスクリプトファイル実行する話なんかしてないけどね 上の方にあるpowershellスクリプトをバッチファイル内に埋め込む方法使えば、普通のWindows 10 PCなら動かせますよ
ポストスクリプトも一応チューリング完全だから、実行系さえあれば動かせますねwww VSCode の拡張機能・GrapeCity のExcel Viewer じゃ、ダメなのか?
他にも、Rainbow CSV とか 代替案を出しただけでスレチとか
世界征服したいですとか質問が来たらどうすんだ >>618
PSで解決できる案を出せばそれはスレの趣旨に沿うだろ Excel入ってない環境で内容を確認するだけなら使えそう
同じ処理を繰り返し実行するならスクリプト作るのがベスト
CSVなら外部ライブラリ導入せずともpowershellだけで処理出来るし
心を込めた手作業派はスレチ powershellの方がVBより文法的に楽だろJK シジルが気になる人はそれなりにいるんじゃないかな?
まぁ、俺もVBの文法は肌に合わなくて、どうしてもマクロじゃないとダメって時だけしか触りたくないけど VBAマクロはGitとかの管理がしんどくてコードレビューも辛い PowerShellでCOMのIDispatchな操作やるとオブジェクト参照リークしまくるから別の専用プロセスでやるよね? 連想配列を学習中なのですが…
$a = @{"a"=10 ; "b"=20; "c"=30 } などとして連想配列を作り
> $a.count
3 # たしかに要素数は 3
なのに
> $a.length
1
lengthは 1 になるのは何故? …っていうか、1って何の長さ?
普通の配列だと、要素数は lengthでも countでも同じなのに >>626
別プロセスでもよいけど、スクリプトブロック内で参照するオブジェクト作って、ブロックの外側でGC呼び出すだけでも十分じゃない? >>627
$a | Get-Member
すると表示されるプロパティには"length"は無いし,いっつもタブ補完してるからlengthプロパティ見たことなかったけど,確かに1って表示されるね 配列は
$a = 1,2,3
,$a | gm
するとCountがAliasPropertyでLengthがPropertyって出てくるね New V3 Language Features
https://devblogs.microsoft.com/powershell/new-v3-language-features/
You can now use Count or Length on any object, even if it didn’t have the property.
If the object didn’t have a Count or Length property, it will will return 1 (or 0 for $null).
Objects that have Count or Length properties will continue to work as they always have.
PS> $a = 42
PS> $a.Count
1 つまり lengthなんてのが無くても 1は返る…と.
たしかに tabキーでの補完は出なかったけれど
でも 配列には lengthあるし、個人的にはrubyでもlength使えてたので…うっかり書きそうな気はするが、
…とりあえず勉強になりました >>600
pwshだと起動時に更新チェックしてますよ
環境変数でオフに出来るみたいだけど 自分もRuby使ってるから分かりますわー
powershellではプロパティを大文字始まりのCamelCaseで書く様にすると
慣れるの早くなると思います $a.Countで1が変えるよりエラーを返して欲しいな blogの記事読むとForEach-Objectした際に
列挙可能なものかそうでないかの判定を行わずに済ませるためみたいです
確かにv2の頃は出力が一個だけだった時のために@()でくくってましたわ
それよりもForEach-Objectの省略記法で
(ls).FullName
ができるの初めて知りました.これは便利 >>631
なんでこんな余計な機能をつけるんだろうね
>>636が言うように素直にエラーにして欲しいわ foreachできるかいちいち判定するより便利だし、よいと思うけどな
実際、自分で書くスクリプトはめっちゃ恩恵にあずかってる 知ってれば便利だし、知らなくてもあまり害にならないからね
今回の質問のケースも調べる気がなく急いでたならCount使えばいい案件
シェル言語は厳格さより楽さ優先でいい
惜しむらくはPSがもっと普及していれば変な癖も含めて常識になるけど、そこまで至ってないところ こんな感じのコードでもエラーが出ない為と書いてあったね
$x = dir
for ($i = 0; $i –lt $x.Count; $i++)
{
$x[$i] …
}
$x.gettype() で調べると値が1つならSystem.IO.FileSystemInfo
2つ以上ならSystem.Arrayで配列
配列と1つの値で同じコードで出来るのは個人的には楽でいいと思う jQuery Object も、0, 1, 2以上でも、配列として同じ書き方ができる。
0でもエラーにならず、単にループしないだけ
0, 1, 2以上で、表現・型を変えるものは、大変 >>641
配列を期待してるのに1要素が返る場合に配列で返らないのは階層データ構造を作る場合とても困る
gcはいつも$hagelist = [string[]](gc hage.txt)
ってやってるわら
ハゲが一人だと配列にならないしハゲがいないと$nullになるし
要素数0、1、2以上で型が変わる仕様はいつ見ても気持ち悪い まあこの手の仕様はどっちが正解とかはないので結局は好き嫌いでしかないよね
個人的には単一の値と配列を同一に扱いたい時は@(…)で充分なような気がする ForEach-Objectだと配列のネストをフラットにしてくれるけどforeachだとそうならないから
@()でくくるので全て解決ってことにはならないんじゃないかな
あと,エラー出してくれる動作の方が好みなら
Set-StrictMode -Version Latest
にするとエラーになりますよ countが使えるから何だって感じ
外部テキストファイル扱う時は0バイト、1行のみ、複数行のテスト必須だな そうしたければそうすればいいんじゃないかな?
俺は必須だとは思わないけど いちいちバイト数や行数を調べるより
何も考えずに@()を使ったほうが分かりやすい 配列に$nullや空文字列が含まれる場合のチェックはどのみち必要になるだろうからv3記法がスッキリ書けて嬉しい
@()で括るのは想定外の挙動になるのと、もうすでにもっと簡易な記法が言語サポートされてるんだから使う必要ない powershelle初心者だけどこんなバッチファイルを書き換えたい場合どうやって置き換えたらいいかな?
%%j(2番目トークン)の参照方法が分からないので教えてください。
for /F "tokens=1-2" %%i in (%TBL%) do (
if "%1" == "%%i" (
set MSG=%%j
)
) 対応が付きやすいようになるべく同じかきかたしたらこんな感じかな
Get-Content $env:TBL -Encoding Oem | ForEach-Object {
$a, $b = -split $_
if ( $args[0] -eq $a ) {
$msg = $b
}
} >>652
ForEach-ObjectはXargsの様なものだと認識してるのですが少し齧ったレベルだと動きがよく分かりませんね…
後で実際に動かしてみます!どうもありがとうございます >>651でやりたい動きになりました!
本当にありがとうございます! ForEach-Objectはパイプからの入力を逐次に処理するイメージなので、なるべくまとめて処理するxargsとは逆の動作かな
Get-Contentはオプションなしだと行区切りの配列を返すので
自動変数$_には一行文の文字列が入る
-split演算子は右辺のみだと右辺の文字列を空白区切りで配列にして返すので
先頭の2つを受け取って処理してると
バッチと違って、対話環境で一つずつ動作を確認しながら動かせるので
いろいろ試して見ると早く慣れると思う みんなForeach-objectってよく覚えてるよね
省略形の%ばっかり使ってて忘れがちだわ vscodeでスクリプト書いてると略すなって怒られるからね ターミナルでポチポチ動かす時は%や?を使ってる
コマンドレットもlsやcdを使ってるし
スクリプトはvscで指摘されるし補完も効くからエイリアス使わないかな >>656
まあ% = foreach-objectが染み付いてれば書くのも読むのも%のが早くはある
文法忘れるぐらいの頻度でしか触らない人は何じゃこりゃ!?ってなるが スクリプトで低速のforeach-objectなんて使わないから、
結局本名で書く機会なんて無い。 >>660
PSで書くからには速度気にするべきじゃないと思うけどな
なんならパイプが遅いし ボトルネックになるような場所に使うなってのは当然だが
使う場所が無いってのはどうなんだろ 早すぎる最適化は諸悪の根源定期
性能改善を覚えるとそれが目的化するんや
そこに山があるんや ForEach-Objectとわざわざ書く
と
%自体を使わない
がごっちゃになってるな
>>656
これが既成事実になってる気がする
別にみんな覚えてないだろ
補完は覚えているに入りません iwr や gciなども アイリアス元なんか覚えてない >>660
バッチファイルのfor /f(だっけ?)だし使わないわけない
目的が違うとしか言いようがない >>667
いや実際使ってないな
スクリプトブロックを&とかで呼び出して回した方が早いし書きやすいし gciは使わないなぁ
lsか、補完でエイリアス元を使うかどっちか
オプション指定が必要な時はget-childitemですね
invoke-restmethodはproxy指定しないといけないから、コマンド履歴から呼び出してる
本当によく使うならプロファイルに書くんだけど、そこまででもない >>668
どういうこと?
$array.ForEach{}みたいなのはforeach()の方が早いと思うけど
スクリプトブロックで回すってのがわかんないので、教えてもらいたいです >>670
$array | &{process{ 何か処理 }}
スクリプトブロックのprocess部はパイプから受け取ったオブジェクトを1つずつ処理するのでこれでループ処理書ける
良いところ
パイプから渡せる
当然begin部とend部も使える
動作速度は%どころかforeach文すら上回る
悪いところ
&で呼び出すとスコープ周りが面倒臭い(ドットソースで呼べばいいだけだが) すげー!
見た目Foreach-Objectと大して変わんないように見えるけど、なんで早いんだろう? 全然意味ない例だけど試してみた
PS C:\> Measure-Command { ls -Recurse c:\Qt | & { process{$_.fullname > $null} } }
Days : 0
Hours : 0
Minutes : 0
Seconds : 5
Milliseconds : 196
Ticks : 51967700
TotalDays : 6.01478009259259E-05
TotalHours : 0.00144354722222222
TotalMinutes : 0.0866128333333333
TotalSeconds : 5.19677
TotalMilliseconds : 5196.77
PS C:\> Measure-Command { ls -Recurse c:\Qt | % {$_.fullname > $null} }
Days : 0
Hours : 0
Minutes : 0
Seconds : 6
Milliseconds : 190
Ticks : 61909279
TotalDays : 7.16542581018519E-05
TotalHours : 0.00171970219444444
TotalMinutes : 0.103182131666667
TotalSeconds : 6.1909279
TotalMilliseconds : 6190.9279
確かに速いね!不思議 裏を返せばforeachは毎回スコープの是正処理が走るから遅いということか PS C:\> Measure-Command { ls -Rec c:\Qt |&{Begin{$f = [System.Collections.ArrayList]::new(); $d = [System.Collections.ArrayList]::new()} Process{if($_.Mode[0] -eq 'd'){$d.Add($_)}else{$f.Add($_)}} End{Write-Host "Directory: $($d.count), File: $($f.count)"}} }
Directory: 4915, File: 50123
Days : 0
Hours : 0
Minutes : 0
Seconds : 5
Milliseconds : 645
Ticks : 56455459
TotalDays : 6.53419664351852E-05
TotalHours : 0.00156820719444444
TotalMinutes : 0.0940924316666667
TotalSeconds : 5.6455459
TotalMilliseconds : 5645.5459
PS C:\> Measure-Command { ls -Rec c:\Qt |ForEach-Object -Begin{$f = [System.Collections.ArrayList]::new(); $d = [System.Collections.ArrayList]::new()} -Process{if($_.Mode[0] -eq 'd'){$d.Add($_)}else{$f.Add($_)}} -End{Write-Host "Directory: $($d.count), File: $($f.count)"} }
Directory: 4915, File: 50123
Days : 0
Hours : 0
Minutes : 0
Seconds : 6
Milliseconds : 736
Ticks : 67362805
TotalDays : 7.79662094907407E-05
TotalHours : 0.00187118902777778
TotalMinutes : 0.112271341666667
TotalSeconds : 6.7362805
TotalMilliseconds : 6736.2805
なるほどなぁ 凄い懐かしい書き込みを見てしまった、書いた記憶ないよ え?もしかして???
実践ガイドブック買ってましたよ!
会社の備品でですが 2022/1からの電子帳簿保存法改正の関係で、フォルダに格納した電子取引のファイルを
検索できるようにするためにWindowsPowerShellを使ってみようかと思っています。
ひとまずファイルの命名規則を社員に周知して、それを
Get-ChildItem -Name -Recurse | Where-Object { $_ -match ・・・
で正規表現で検索できそうなのは分かったのですが、これをサーバーの上位階層で使うと
それなりに時間がかかりそうです。
そこで以下質問なのですが、
電子取引ファイルを格納するフォルダにも新たに命名規則を適用したうえで
Get-ChildItem * | Where-Object { $_.PSIsContainer }
のようにフォルダ名のみを検索するコマンドを使って、
「サーバー上位階層以下の全てのフォルダから、
複数のAAAで始まるフォルダ名のフォルダの中のみを対象に
BBBで始まる電子取引ファイルのみを表示する」
というコマンドは可能でしょうか? こんな感じですかね
$dir_list = Get-ChildItem -rec -Directory -Filter 'AAA*'
foreach($d in $dir_list) { Get-ChildItem "$($d.FullName)\BBB*" -File } Ruby で作った
# 絶対パスのディレクトリ名の後ろに、* を付けること!
# . で始まる、隠し directory, file は抽出されない
src_dir = "C:/Users/Owner/Documents/Ruby/test"
glob_pattern = src_dir + "/**/*" # 以下のすべてのファイル
# 指定する語句
dir_substr = "/test1"
file_substr = "test"
target_files = Dir.glob( glob_pattern )
.select { |full_path| File.file?( full_path ) } # ファイルのみ
.select { |full_path|
# フルパスのフォルダ名だけを取り出して、その先頭から、src_dirの部分を削除する。
# つまり、src_dir見た、相対パスのフォルダパスだけにする。
# そこから、include?で、指定の語句で始まる、フォルダ名を含むものだけを抽出する
File.dirname( full_path ).delete_prefix( src_dir ).
include?( dir_substr )
}
.select { |full_path|
# ファイル名だけを取り出して、指定の語句で始まる、ファイル名を含むものだけを抽出する
File.basename( full_path ).start_with?( file_substr )
}
puts target_files
出力
C:/Users/Owner/Documents/Ruby/test/csv/test10/test10.rb
C:/Users/Owner/Documents/Ruby/test/test141/test.ini >>681
基準とするフォルダが、C:/Users/Owner/Documents/Ruby/test の時、
出力
C:/Users/Owner/Documents/Ruby/test/csv/test10/test10.rb
C:/Users/Owner/Documents/Ruby/test/test141/test.ini
は、
基準フォルダのフルパス/csv/test10/test10.rb
基準フォルダのフルパス/test141/test.ini
そこで、フォルダ名に含まれる語句が、test1 の場合、
基準フォルダの直下・子だけでなく、/csv/test10/test10.rb など、
子孫のフォルダ名に含まれる場合も抽出している ファイルシステム走査するのが遅いのは仕方ないからCSVでパスと検索フラグ保持するのがよさそう ローカルドライブの話ならWindows Searchサービスの機能って使えないの
あれ何なの 検索出来ればよいだけで、サーバーがWindowsなら、Everything使ってもいいんじゃないでしょうか ファイル名検索で十分そうなんで、全文検索の例は違うかと まずは目標性能を提示した上で実測するところからじゃろ 680で試してもらって、もっと速度が必要ならEverythingを検討するのがよいと思います ありがとうございます。
PGかじっただけの事務方でWindowsPowerShellも5日くらい前から
仕事の合間に調べ始めた初心者なので>>680の中身もパッと見よくわかりませんが
明日にでも調べながら試してみます。
Rubyは名前しか知らないのでごめんなさい。
上手くいかないようならEverythingというのを試してみます。 漏れがテストしたら、
>>680
>>681
は、同じ結果になった >>673
実は配列にもドット演算子が定義されていて、こういう書き方も出来る
処理も速く、書きやすいので記述量のコスパがいい
配列.要素のプロパティ名 → 要素のプロパティ名配列
Measure-Command { (ls -Recurse c:\Qt).fullname > $null} } >>679
自分もファイル検索するスクリプト作ってるが、
速度は Where-Object と -match がボトルネックになってた
PSは特定の演算子の左オペランドを配列にすることでフィルタになるんだが、
これは処理が速いので置き換えた方がいい
配列 | Where-Object{ if($_ -match "正規表現"){$_} }
は、
配列 -match "正規表現"
で置き換えられる。
ただしパイプ処理ではなくなるので使用メモリは増える。 ワイルドカードで事足りるならget-childitemのfilterオプションが早いんじゃない? シェルスクリプト板にも書いてしまったんやが
スクリプト内で関数をサブプロセスで動かして出力も表示させる書き方ってどうすればええんや?
shでの func & 的なことをしたい 脱線話になってしまうんですが、そもそもの国税庁の通達らしきものが全く流れてきていない中で
営業チラシとかからこの電子帳簿保存法の話を知って自分で調べている次第で…
で、調べてみると
https://www.nta.go.jp/law/joho-zeikaishaku/sonota/jirei/pdf/0021005-038.pdf
の2ページ目、検索要件として
「@取引年月日・取引先・金額で検索できること」
「A日付または金額の指定範囲検索」
「B2つ以上の任意の項目による検索」
とあり、そうなるとファイル名の命名規則に上記3項目を組み込み、
正規表現で検索する必要があるかな、という結論になったわけですが…
どうもこの2ページ目の※1に該当してABが不要になる可能性があり、
さらには
https://www.nta.go.jp/law/joho-zeikaishaku/sonota/jirei/pdf/0021006-031_06.pdf
の問12によると、そもそも既存のファイル管理だけしていれば検索機能要らないんじゃ…
というところに行きついたのが先週金曜の夜になります。
税理士に聞いても持ってる情報はこちらと大差なく、どう転んでいくか分からない状況 (;´д`) 大変ですね。。。
税務署に問い合わせれば教えてくれるもんなんでしょうか? >>702
バックグラウンドで動かすのはstart-jobだけど、receive-jobしないといけないから、shと同じ雰囲気で動かすのは難しいんじゃないかな? 標準出力じゃなくてファイルに出力するなら、何も考えなくてよくて簡単なんですけどねぇ (echo foo &) | Receive-Job -Wait 配列にしてファイル名取得してコピーする動きさせたです
以下のようなイメージを浮かべていますが上手くいかなくてどう書いたらいいか有識者の方教えてください
$aaa[0]=〜.txt
$aaa[1]=〜.log
$aaa[2]=〜.sh
foreach($i in 0..2){
copy-item -force aaa[$i] $コピー先
}
$?で戻り値判定 自己解決したかも
下記でうまく動きましたわ頭悪い書き方かもしれないが
$aaa=@(ファイルパス,ファイルパス,ファイルパス)
$aaa | foreach-object { copy-item -force $aaa コピー先} パスの引数はliteralpath使った方がいいよ
普通のpathだとワイルドカードが有効になって面倒なことになる literalpathを使った方が安全安心というのはその通りとして
戻り値チェックがなくなってるけど,それでよいのならこれでもいいんじゃないかと
foreach($i in ファイルパス,ファイルパス,ファイルパス){
copy-item -force $i コピー先
} >>711
literalpath知りませんでした…
>>712
僕がしたかったのはその書き方です!そういう書き方の方が何してるのかわかりやすいと思うので
戻り値の件は書き損ねているだけなので大丈夫です
お二方ともご丁寧にどうもありがとうございます! []*なんかはファイル名としては普通に使えるけどpowershellではワイルドカードとして扱われるんでliteralpath使うとよいです *は使えないけど*は使える
<>は使えないけど<>は使える
つまり >>703
YouTube に、ベストセラー『さおだけ屋はなぜ潰れないのか?』の著者・山田 真哉の動画がある
今現在も刻々と、変わり続けている >>703
Libre Office を使えないの?
それで、何か問題でもあるのか? CSV なら、
VSCode の拡張機能・Rainbow CSV で、
RainBow Query Language(RBQL)とか、
GrapeCity のExcel Viewer などで、フィルター出来るのでは? Objectの配列ってあるやん?
例えばGet-childitemで返ってくるような奴。
こいつのあるプロパティの値で検索かけて、ヒットするオブジェクトを返してくれるコマンドレットってある? Where-Object
てかそれ知らなくても
Get-Childitem | %{ if($_.プロパティ -eq 'xxxx') $_ }
ってやればいいだけ パイプラインからオブジェクトを削除する (Where-Object)
https://docs.microsoft.com/ja-jp/powershell/scripting/samples/removing-objects-from-the-pipeline--where-object-
PowerShell には、Where-Object コマンドレットがあります。これを使用すると、パイプラインの各オブジェクトをテストし、特定のテスト条件を満たしている場合にのみ、オブジェクトをパイプラインに沿って渡すことができます。 テストを通過しなかったオブジェクトは、パイプラインから削除されます。 テスト条件は、FilterScript パラメーターの値として指定します。 質問です。
連想配列Aがあって、このAのkeyを要素とする配列Bがあります。
この配列Bの各要素の値のkeyを連想配列Aで対応するValueに全て置き換えたいのですがどうすれば良いでしょう?
新たに配列Cを作ってそこに置き換えた値を代入でもかまいません。
シンプルに出来れば良いのですが。 重要な事書き忘れてました。
配列Bの要素にマッチする連想配列Aのkeyが存在しなければ、その配列の要素自体削除したい。 新規に$cを作ってよいのなら
PS C:\> $a = @{ a=1; b=2; c=3}
PS C:\> $b = @('a','b','c','d')
PS C:\> $c = @()
PS C:\> foreach ( $k in $b ) {
>> if ( $k -in $a.keys ) {
>> $c += $a[$k]
>> }
>> }
PS C:\> $c
1
2
3
PS C:\>
ではどうでしょう? >> if ( $k -in $a.keys ) {
>> $c += $a[$k]
keysで文字列の配列を作って更にそれを[]で検索して値を得る
って凄く無駄な気がするんだけど
KeyValuePairってPowerSellで使えないんだっけ valueが$nullではない,もしくは,valueが$nullの場合は$cに含めなくてもよいなら
ifの条件を( $null -ne $a[$k] )にできるね
$aの要素がたくさんあるならgetenumeratorでforeachを回して
$bから見つかった要素を削除するのがよいのかな? $a = @{a=1;b=2;c=3}
$b = @("a", "z", "c")
$c = $b | %{ $a[$_] }
これで出来てる? Ruby なら、配列同士の積を使える
hash = { "a"=>1, "b"=>2, "c"=>3 }
p hash.keys #=> ["a", "b", "c"]
p hash.values #=> [1, 2, 3]
ary_1 = [ "c", "x", "b" ]
p ary_2 = ary_1 & hash.keys #=> ["c", "b"] GetEnumerator使ったらこんな感じ
$a.GetEnumerator() |? {$_.key -in $b} | select -exp value これでも
$a.GetEnumerator() | &{process{if ($_.key -in $b) {$_.value}}} やたら凝った回答が多いけど、素直に>>734でいいと思うんだが・・・ だめじゃね?
$c[1] に $null が入るよ
仕様は
> 配列Bの要素にマッチする連想配列Aのkeyが存在しなければ、その配列の要素自体削除したい。
だし $a.GetEnumerator() |?{$_.key -in $b} |% valueか
GetEnumeratorってすぐ忘れそうだけど補完で出てくるからいっか おー、Foreach-Objectの短縮記法か
オシャレっすね
そう書けるのは知識として知ってるんだけど、全然出てきませんわ
Select-Object -ExpandProperty使っちゃう > valueが$nullの場合は$cに含めなくてもよい
が許されるなら
$a[$b] -ne $null
でいけそうだけどあとで何やってるのかわからなるなw >>739
$nullは標準出力に出ないのか
配列のデフォルトの表示形式どうしてこうなった
$c -join ","とかで確認しないといけない >>740
というか$a.GetEnumerator()から順序が考慮されないから正しい実装としては下記と思われる
$c = $b | ?{$a.contains($_)} | %{ $a[$_] } >>739
確認したから嘘だろと思ったら本当に入ってた・・・
表示されないのか
じゃあ途中でキーの有無を確認すればいいから、
$b | ?{ $a.ContainsKey($_) } | %{ $a[$_] }
でどうだろう。
「aのキーにあれば出力」をそのまま描いた感じ 順序気にするなら[ordered]を付ければいい
$a = [ordered]@{a=1;b=2;c=3} 質問よく見てないからかもしれんけど、$aの順序じゃなくて$bの順序を保証しないとだから意味ない 最初の質問も曖昧な点多くてグダグダになってる感
こんなんでいいか?
$a=@{a=1;b=2;c=3}
$b=@("a","z","c")
$c=[ordered]@{}
$b|? {$_ -in $a.keys}|% {$c[$_]=$a[$_]} a 暗号解読用テーブル
b 暗号化された本文
て感じ? >>750
元の$bと同じ単純配列が欲しいって書いてあるのにわざわざ連想配列作るとかグダグタになってるのはお前だけだろw >>750
チラ読みしただけだけど、キーの配列でテーブルを引きたいのなら、単に配列を添字にすればいいのでは?
$b[$a]
対応するキーが無いところはヌルが返る すぐ上に同じような事書いてたごめん>>742
valueが$nullな病的なケースまでは扱いたくないから知らん ($b | %{ $a[$_] }) -ne $null が好きだな
-ne はこのための仕様なので合目的的
わかりにくさが不安ならコメントを添えてもいい
containsとアクセサでハッシュテーブルを2回ずつ検索するより好き >>755
結果は同じだけど定義通りじゃないのがな
存在しないキーの値がたまたまnullだった、フィルタしたら偶然求めたい値と一致したに過ぎない
既に言われてるけどValueがnullだと食い違う
やはりcontainsKeyが1番だと思う
パイプが連続してる方がシェルっぽくて見た目もかっこいいし ああその違いがあったのか
でも発注者が本当に求めている条件がどっちなのかはかなり怪しい事例だと思う(言い訳) >>756
存在しない値を参照するのは自分も抵抗ある
エラーで止まる可能性もあるしね
Powershellはそういうエラーは起こしにくいけど型付け言語ではアウトな気もする copy-itemでフォルダコピーする際、
サブディレクトリにあるフォルダ名やファイル名に特定の文字列 @("*hoge*","*huga*")
が含まれている場合除外したいのですが、
一通りググった方法を試しても上手くいきません。
get-childitemの有無等幾つか方法はあるみたいですが、どうやっても除外ができない。
上手くいく方法をご存知でしたら教えて頂けませんか。 >>760
Get-ChildItemでファイル列挙して正規表現かなんかでコピー対象のファイルなのか一個ずつ判定して一個ずつCopy-Itemすりゃいいんじゃないの >>760
そのフォルダだけじゃなく、
起点のフォルダ以下を、再帰的にすべてコピーするという意味か? >>760
以下みたいな感じでGet-ChildItemの出力にWhere-Objectに-notlikeでフィルタしてCopy-itemすればいい
-Recurse付けたがサブディレクトリ含めなければ外せばいい
Get-ChildItemとWhere-Objectを組み合わせてググれば他の活用も見つかるはず
Get-ChildItem -Recurse|
Where-Object {$_.Name -notlike "*foo*" -and $_.Name -notlike "*bar*"} |
ForEach-Object {Copy-Item $_.Fullname -Destination "出力先フォルダ" -Recurse} >>765
考えてみたらGet-ChildItem に -Recurseつけたら階層が再現しない
コピー元から階層で処理するならこのコードじゃ動かないわ 皆様ありがとうございます。
頂いたアドバイスを受けて、正規表現を使ったりして試しているところです。
解決したら改めて報告します。
ちなみに要件としては、
「起点のフォルダを再起的に全てコピー(同じ階層構造)」となります。 すみません、「起点のフォルダ以下を再起的に」ですね。 >「起点のフォルダを再起的に全てコピー(同じ階層構造)」
パイプを繋げていくとこの点が不安になってくる。
コピー元のフルパスを正規表現で整形すれば良いだけだけど、何だかなって気分になる。
powershellが管理用途を目指したなら何でrobocopy相当の機能を提供しなかったんだろうか。 起点のパスからパイプつなげて階層コピーとかやろうとすると大変なのね
Get-ChildItemだと起点パスからの相対パスが出てこないからこんな汚いコードしか作れなかったわ
Push-Location "コピー元パス"
Get-ChildItem -Recurse|
Where-Object {$_.Name -notlike "*foo*"} |
Where-Object {$_.Name -notlike "*bar*"} |
ForEach-Object {Copy-Item $_.FullName -Destination ("コピー先パス"+(Resolve-Path $_.FullName -Relative))} robocopyで十分ならrobocopy使うべき https://stackoverflow.com/questions/32101358/copy-all-files-and-folders-except-few-in-ruby
Ruby では、Dir.glob("**/*") で再帰的に、起点フォルダ以下のすべてのファイルを配列に入れて、
そこから、コピーしないファイルを削除する
そして、再帰的にコピーする
FileUtils.cp_r( 配列, destination_folder ) powershellでやるなら、一旦、まるっとコピーして、コピー先から不要なファイル消すのが簡単 面白そうだから作ってみた
.NETクラス使ったら負けというポリシーの人には受け入れられないかもしれんが
$SrcPath #コピー元
$DstPath #コピー先
[System.IO.Directory]::EnumerateFiles($SrcPath, "*", [System.IO.SearchOption]::AllDirectories) |
Where-Object { $_ -notlike "*foo*" } |
Where-Object { $_ -notlike "*bar*"} |
Select-Object @{Name = "FPath"; Expression = {$_} }, @{Name = "RPath"; Expression = {$_.SubString($SrcPath.Length)}} |
ForEach-Object { `
[System.IO.Directory]::CreateDirectory(([System.IO.Path]::GetDirectoryName($DstPath + $_.RPath))) | Out-Null; `
Copy-Item $_.FPath -Destination ($DstPath + $_.RPath) `
} わざわざ.NETクラス使った>>775は、>>770に比べてどんな良い事があるの? .NETクラス使える俺スゲー君なんだろ
まあ $DstPath + $_.RPath なんて書いてるから中途半端な知識しかなさそうだけど >>777
Path.Combine使ってほしかったってこと? >>776
コピー先のフォルダーがあらかじめ作成されなくてもエラーにならないこと フォルダ名のファイルがあったらエラーになると思うけど どうでもいいけど -notmatch 'foo|bar' でよくね 先日の質問者です。
下記コードで、想定通りの動作を確認しました。
事前に展開するディレクトリを作成する必要はありますが、
正規表現で抽出して、「Join-Path $DstPath $_.FullName.Substring($SrcPath.Length)」で
展開先ディレクトリに取得した要素を展開する感じです。
色々とアドバイス頂きありがとうございました。
---------------------------------------------------------------------------------
#出力先ディレクトリ
$SrcPath = 任意のディレクトリ
#出力先ディレクトリ(スクリプトの置き場 + 展開するディレクトリ)
$DstPath = Join-Path (Split-Path $MyInvocation.MyCommand.path) ("\test")
#抽出&コピー
Get-ChildItem -Recurse $SrcPath | ?{ $_.FullName -match "^(?!.*file)"} | `
Copy-Item -Destination {Join-Path $DstPath $_.FullName.Substring($SrcPath.Length)} 誤字が酷い・・・
以下の通り訂正します。
#コピー元ディレクトリ
$SrcPath = 任意のディレクトリ 除外するのがファイルなら、全部コピーしてから消す方が、考える時間ノータイムでできるから、自分ならそうしちゃうな
ディレクトリ除外するなら素直にrobocopy使っちゃう 除外する理由も不明で全部コピーとか機械オンチかな
ストレージは有限リソースだぞ Join-Pathのところ
$_.Fullname.replace($SrcPath,$DstPath)
でもよさそう 除外したいファイルが巨大ファイルかもしれないのに一旦コピーしてから削除とかアホやろ 巨大ファイルかもしれないし小さいファイルかもしれない
質問者がまだ開示してない範囲なのでアイデアは言うだけタダだし叩くいわれもないだろう せっかく何でも呼べるシェルなのにrobocopyを呼ばない理由があるのかは知らん
純PSを使いたいという拘りは遊びや向学の範囲ならありだと思うけど 流石にコピーしてから削除は素人くさくて人には見せられないコードだな 対象のファイル存在判定判定を行いたいんだけど
get-childitemで「〜が存在しない為検出できません」と表示されてFalseが返ってくる時と、対象ファイルはないけど何も表示されずにTrueが返ってくる時の違いって何でしょうか?
正規表現で複数のファイルを探してる時と限定して一つを探してる時の差って認識で合ってますでしょうか
認識が合ってるのであれば、Falseが返ってくる際のファイル存在判定ってどうやって行ったらいいですかね robocopyという既存で使えるコマンドがあることはわかりました。
しかし、それを承知の上で、純PowerShellのコマンドで実現できる方法を探していました。
ストレージにも容量があるため、抽出とコピーを同時に済ませたかった次第です。 あ、やっぱスクリプト書くのが目的なんですね
それならそれでよいと思います
ぱぱっと仕事を済ませるために使えるものを使うのであれば
そういう考え方もあるってことで
もちろん、コピー不要なファイルのサイズが大きすぎたりしたときは使えませんが
ただ、エラー時のリトライとかマルチスレッドをpowershellで実装するのは面倒なのでrobocopyかrsync使うことをお勧めします
自分しかアクセスしない領域を扱うなら、ここに書かれていた例でも十分かと思います >>793
test-pathって複数ファイル判定できるのか? test-pathはstring[]を引数に取れて、それぞれの判定結果を返しますね 今回の目的だとRobocopyで良いんだが
Powershellなら複数の条件のandでフィルターしたり正規表現でのフィルターやらリネームしながらのコピーとか活用シーンはあるわ >>787
大文字小文字の差異が発生したときにちゃんと動かないと思う Copy-Itemって時刻や属性とかACLやらもコピーされるんかな
同じにしといてや >>803
大文字と小文字の差を無視したいんじゃないの? 質問です / たとえば…
膨大にファイルがあるディレクトリ以下から 古いファイルを探そうと思って
ls -r |? lastwritetime -lt "2015/10/10"
などとしたら…思いがけなく 沢山のファイルが該当したとき、
「この結果…変数に入れとけばよかったなぁ…そうすれば後で絞り込んだりできるし」
と思うことが あるのですが
でも、あらかじめ
$list = ls -r |? lastwritetime -lt "2015/10/10"
などとすると、検索中は 表示が見えない.
…というわけで、変数に入れつつ 表示させる手段を 今、探していますが なんだか分からず.
今のところは、「ファイルにリダイレクトしながら tee」ってのが、近いけど
使うかどうかわからない結果について、いちいちファイル作りたく無い気持ち(笑)はあったり (これも 検索でも分からなかったのですが)
昔unixを使ってた慣れから pushd と popd を使うことがあるのですが
スタックの中身って見れないのでしょうか (dirsみたいな) >>806
Where-Object -OutVariableとかでできなかったっけ >>808 ありがとうございました
ls -r |? lastwritetime -lt "2015/10/10" -OutVariable list
知らなかった…調べてみると すべてのコマンドレットに備わってるんですね >>809
-OutVariableは -ov が省略形.
あと tee -Va list でもできちゃう. 遅レスだけど>>583にも関連ありそうなのでアンカー付けとく、slじゃなくてpush/pop-locationだけど
CDPATH的なモノはsl -で参照できることから存在してるとおもうけど、もっと柔軟に数の引数取りたい、とかなら簡単なシェル関数書けば良いかと
function cd($bwd=1){iex "cd -;" * $bwd}
さらに
{iex "sl ..;" * $up},
{iex "sl +;" * $fwd}…等
(cdのremove-alias、引数を読んでディスパッチ等はよしなに)
まあ気が散るからlocationスタックに慣れた方がいいとは思う $hoge = Invoke-Command -ComputerName 192.168.0.1 -Credential $cred -ScriptBlock {C:\script\cpu.bat}
こんな感じでリモートPCのCPUの情報を取得したんだけど、
リモート側では返り値の型が Hashtable で連想配列なんだけど、実行する側のPCだと Object[] になって配列になるんだけど
これって仕様なの?
連想配列のまま$hogeで受け取る方法とかない? 無いのかw
PowerShell初めて触ってるんだけど、こいつ癖が強いなぁw >>816
パイプってそんなにアク強かったっけ?
むしろ配列の方がトラップ満載な気がするが パイプラインが気に入らなかったら使わなきゃ良いんだけど
配列は気に入らなくても使わざるを得ないんだよな 初代プレステみたいな拡張子以外ないの?
もうちょっとかっちょいい拡張子使いたい pwshも起動遅いよな
NGenも上手く行かんし。起動の遅さには目をつぶって使ってる感じ? 毎回pwsh起動時に最新バージョンのpwshかWebサイトに確認しにいってる予感 24時間ごとに最初のセッションでバージョンチェックが走るので、テレメトリーを無効にすればちょっとだけ起動が速くなるかも
https://github.com/PowerShell/PowerShell/issues/16234
POWERSHELL_UPDATECHECKは通知の制御だけで、バージョンチェック(を含む通信)はテレメトリー自体を止めないとダメみたい PowerShellを使っている人はWindows Terminalも使っていること多いでしょ
どっちも素のコマンドプロンプトに比べて起動に時間がかかる WSL2 で、Linux も使っている人は、Windows Terminal が便利。
ctrl + c でコピーできる
Linux の端末では、右クリックメニューからコピーしないといけない Windows Terminal上でPowershellを使ってるとき、IME OFFに割り当てた無変換キーを空打ちすると@が入力されちゃう psreadlineでバインドし直せばいいんでないの? >>828
Ahkで無変換をime off機能に割り当てて対策してる。 psreadlineに渡る前にwtに吸われてるのなら無力だったな
めんご >>832
AutoHotkeyで解決した、ありがとう 今回リモートPCの使用状況をlog化して通知するシステムに利用したんだけど、
みんなは何にPowerShell使ってんの?やっぱり反復処理とか?イマイチ使いみちが思いつかないw 分かってる人には当たり前のことなのかもしれないけど、 Set-PSReadLineOption -EditMode Emacs で
Emacs風味キーバインドにしたらCtrl+DでPowerShellが終了するね Ctrl+Dでの終了はzshでも有効にしてるので、違和感なく使ってました 日常的に使ってるのは、VPN接続とリモート接続のログイン自動化スクリプトですね >>834
そんな大層なことしなくても
gci -pa HKLM:/system -rec -inc keyboard* -ea ignore
とかでキーマップが引っかかったと思うから、$profileにブチこんどけばいいんじゃないの、シェル閉じた時のリストア処理も書けるし ターミナル(wt.exe)の問題なら.jsonにキーマップ書けたはずで、それが一番礼儀正しいが レジストリはすぐどこ触ったか分からんくなるから$profileか、pwshの外ならuser\**\startupにコマンド書いて設定した方がいい
少なくとも何を触ったかは記録に残る
できれば初期値についてのコメントも
シェル/環境変数みたいにシャドウイングできるといいんだけど wsl --help の出力結果をパイプやファイルにリダイレクトすると、PowerShellとWSLが不?戴天の仇らしいことがよくわかる Windows PowerShell Inventor Jeffrey Snover Interview
https://evrone.com/jeffrey-snover-interview >>842
とりあえず|out-file -enc 色々噛ませてみては なんで不?戴天になってしまったのかと思ったら環境依存文字使ってたからか
不倶戴天 (環境依存文字なし)
不俱戴天 (環境依存文字あり) 入れるわけないだろ
こんなもんWindows以外では絶対使わん たぶん、PowerShell が、UTF-8 だからじゃないの?
コマンドプロンプトで、
wsl --help > a.txt
とすると、UTF-16LE になり、VSCode・サクラエディタでも見れる
でも、Windows Terminal(WT)では、PowerShell・コマンドプロンプト・WSL のLinux の3つが使えるけど、
そのコマンドプロンプトでやったら、文字化けして見れない
WT は、UTF-8 だから文字化けするのかも
だから、アプリによる >>848
違うぞ
PowerShellの惨めな現実を受け入れろ まあでもWindows上で使ってるぶんには安定してるな。
当たり前だけどw PowerShell上で非ANSIコードページ文字列をパイプやリダイレクトするには以下のようにcmd /C を使うしかない
cmd /C 'wsl --help > aaa.txt'
「ねぇどんな気持ち?」のクマAAをPowerShell愛好家に贈りたい コマンドプロンプトを使わずに、PowerShell で、
wsl --help を文字化けせずに、ファイルへ保存する方法はないのか?
>>848
修正
>でも、Windows Terminal(WT)では、PowerShell・コマンドプロンプト・WSL のLinux の3つが使えるけど、
>そのコマンドプロンプトでやったら、文字化けして見れない。
>WT は、UTF-8 だから文字化けするのかも
Windows Terminal(WT)のコマンドプロンプトで、
もう一度やってみたら、正常に表示された!
ちなみにコマンドプロンプトも、WTのコマンドプロンプトも、両方とも、CP932 でした
chcp
#=> 932 Correct output in CMD, but incorrect output to a file in PowerShell #16012
https://github.com/PowerShell/PowerShell/issues/16012 PowerShellの定番質問に知ったかぶりしてOutputEncodingを変えろと回答する人って自分で試さないんだろうか?
それとも質問を理解できるだけの国語力がないのか? 負けた気がするけどロケールはもう諦めてen_us、圧力掛けるのはおまいらに任せた
あえて真っ白linuxでは使わんけどwslは快適になるな
$profile |add-member -noteprop
で属性付けて
. $profile.common; .$profile.platform
とそーすしてる そんなことより
左辺コレクションの-eqのフィルタの罠に見事に引っ掛かったわ -eq(ual elements are...)と読み慣わしてる OutputEncoding を変えるぐらいでは、出来ないだろ。
PowerShell(PS)は、迷走しまくっている
UTF-16LE とか、あるのか?
PS 6 では、BOM 無しUTF-8 も出来るらしいけど Windows は、CP932, BOM 有りUTF-8/BOM 無しUTF-8, UTF-16LE が入り乱れて、
外部と日本語でやり取りできないw
一方、Linux は、UTF-8 で統一されているから、全く問題ない。
Ubuntu は、UTF-32 らしいけど、外部には関係ない >>861
Input Encodingがシステムコードページ一択(日本語版Windowsだと932)になってることが原因だよ
UTF16-LEの文字列をSJISとみなしてOutputEncodingに変換するから文字化けしているのが真相
このPowerShellのおバカ仕様のせいでMINGWのUTF-8対応済みアプリの恩恵をまったく活かせない >UTF16-LEの文字列を、SJISとみなして
すごい。文字化けの謎を解明してくれたのか! と言うことは、逆変換すればどうかな?
SJIS → UTF16-LE それか、あらかじめデータを、SJIS へ変換しておいてから渡すとか
Ruby では、色々な携帯の機種依存の日本語を変換するのに、
最長6パスとか掛かるものもあるらしい [console]::OutputEncoding = [System.Text.Encoding]::Unicode
v5環境だけどこれでファイル出力の文字化けは解消できた
ただ改行コード\nが全部\r\nになる v7だと多分問題はない、よろしくやってくれてるんだと思う
mingwは使ってないから知らんが少なくとも標準パッケマネのwingetで入るやつ(gnuwinポート)でエンコで困った事はない >>867-868
デタラメを書くな
君らは問題を理解できてない とりあえず環境を(ターミナルも)書いてくれないとアドバイスのしようがない
>>856の対処は試した? >>870
以下コマンドをそれぞれコマンドプロンプトとPowerShellで実行して、aaa.txtに何が書き込まれているか確認してくれ
wsl --help > aaa.txt
あと「>>856の対処」とは何を指すのか具体的に示して マイクロソフトが関与するオープンソース・コミュニティーは問題が解決してないのに解決したことにしてしまうずさんな所が多い
バグ票を閉じることを優先する隠蔽体質あると思う 共産圏の人間が仕切ってるのかと思うような閉じられ方する、まさにノルマ >>871
> is not a raw-bytes conduit to a file in PowerShell, unlike in cmd.exe.
Instead, PowerShell always decodes output from external programs (into .NET strings) before further processing (but not when printing directly to the display), based on the character encoding stored in [Console]::OutputEncoding.
Therefore, before your external-program call, you must (at least temporarily) set [Console]::OutputEncoding to match the actual character encoding used in your external program's output; e.g., [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new() 従来型のパイプラインを選べない時点で設計思想がおかしいんですよ
$(xxx) みたいな特殊表現によるパイプが提供されてしかるべき
というかPowerShellのパイプラインを特殊表現に閉じ込めるべき OutputEncodingとコードページがごっちゃになってるのもよくない
OutputEncodingをUTF8に指定したら、cmd /? で英語ヘルプが返されるようになってしまう
この挙動は、コマンドプロンプト上のchcp コマンドでコードページを変えたときのcmd /?の挙動と同じ >>877
そもそも従来型のパイプラインは生バイト晒してたように聞こえるんだが、テキストモード(ascii)IOを忘れてないか
fopen等システムコールに行儀良く"b"フラグ渡してれば問題はないが、そうでない時にcmdはtypeや |を処理する際にコンソールのファント設定見に行く等奇怪な挙動をしてた
でもたまに制御文字をtypeして死んだり…
テキストモードを排除できれば可能かも gnuとかのプログラムは今でもioモード切り替えフラグ付いてたりするね
生バイトが欲しければProcessInfoとかからstdin/stdout引っこ抜いてIO.BinaryWriterに渡すとか 文字列中に紛れたeof文字相当のバイトを見ても読み込みを続ける挙動は多分windows的には正しくないよな
そんな文字無くしてしまえ、と思うけど PowerShell固有のパイプラインに、|, >, >> を使うのをやめて
例えば $|, $>, $>> のような特殊表現に閉じ込めてほしいんだが
今さら無理か 昔、MINGWのcatコマンドが0x0aを勝手に0x0d,0x0aへテキストモード変換する迷惑行為で人知れず苦しんだ人は多かったと思う c標準ライブラリの"t"フラグはホスト側でよしなに変換してくれという表明だけど、たぶん行論理セパレータ\n↔\r\n変換してくれるやつくらいに考えてる人が多いんじゃねえかな "t"はc規格には無いか、無指定の"w"フラグ等がテキストモードにデフォルトするというだけで
cっぽいopen関数備えてる言語(pythonとか)だと"b"との区別を意識させる為に"wt"とか受け付けるけど マイクロソフト謹製アプリが率先してやらかしてるってところが肝 それと直接関係あるかは再現しないのでちょっと不明
>>871はconhostをsjisに設定してない? v7.2/wt(preview)
[console]のioデフォルトはutf8(=旧nobom)になってた >>888
CP932は日本語OSの規定の設定だよ
再現しないとか何言ってるのかわからない
作られたファイルaaa.txtの文字コードの確認さえできないんなら回答しなくていいよ >>890
原因分かってんのなら変えなよ…
win10パッケージ版(us_en)に日本語パック追加で入れるとデフォルトはこうなると思う あとwin11非対応マシンでms配布のロールバック用iso(非ローカライズ版)イメージで再インストール→日本語パック選択した人も該当するはず
oem版はsjisが多いと思う >>891
Windows Terminalでも起きるんだからconhost.exeは関係ないぞ >>893
conhostも[console]もシステムのcpから拾ってくる
wtに関してはsetting.jsonからも設定できる
様々なエンコーディング切り替えられないソフトが混在してて、グローバルに切り替えるのがためらわれるならば
ps/cmd>ms-settings:~(スタート>歯車のやつ)からアプリ毎にエンコーディング設定するのがおすすめ エンコーディング機能にAutoDetectがあれば良いだけなんだがな
簡単なことを難しくしてしまうのは無能の証なんだよ
PowerShellみててつくづくそう思う オートディテクトはギルティ、頭抱える事になるぞ
素性の良いデータで大体動けばいいような自動化なら、古き良きnkfでも噛ませ
ポータブルにしたいならPSGalleryに純pwsh実装のモジュールが転がってる、クオリティは知らん
i/oエンコーディングをシェルレベルで扱えるのはバベルの塔なwindows環境では重宝する PowerShellのパイプラインそれ自体がすでに低速なのに文字コードの自動判定すらないとか無能すぎでしょ >>896
古き良きnkfを噛ませられないからもめてるですよ
パイプでnkfに入力された時点で汚染されてるから
時すでにお寿司なのがPowerShell リダイレクトの挙動が不自然に感じるのは、ホストの概念で躓いてるのでは
ホストはコンソールとも限らないし、coreバンドルのコンソールホスト以外にもiseやらaspやら色々あるわけで
なんで設定が分かれてるのか考えるべき >>899
別にいろんなホストがあってもいいんだよ
昔ながらの標準入出力と棲み分けして提供すべきだったってこと
だけど、十把一絡げにしたせいで昔ながらのパイプ処理まで低速になってしまった >>900
>>856からrelatedで飛べる
https://github.com/PowerShell/PowerShell/issues/1908
で提案されてるような構文はあったら確かに便利かと思う
もちろんcoreの設計とは相容れないから、追加モジュールかwindows pwsh(新)でリリースすることになると思うけど
イイね押しとこう むしろPowerShelll固有の構文を新しい構文に移行させてほしいくらいだわ
パイプラインにテキスト縛りがある時点でPowerShellは欠陥品なんだよ PowerShellは以下コマンドをFunction化できない。
[console]::OutputEncoding = [System.Text.Encoding]::GetEncoding(932); $OutputEncoding = [Text.Encoding]::GetEncoding(932);
Function内でしかスコープが有効でないことが原因。$global:OutputEncodingを変えてもダメ。
なのでchcpコマンド相当のことをやろうとしたら手入力するしかない
なんというか、PowerShellは他のシェル言語でできいることができない残念なシェル言語。
オワコン化待ったなし ([console])::OutputEncodingをFunction外にも適用できないことにはchcp相当の機能は実現できない
Powershellからchcpを呼ぶとcmdシェルを介してコマンドプロンプトの初期値が表示されるだけであり、グローバル設定とは無関係
([console])::OutputEncodingが効いたかどうかは、cmd /? で戻されるヘルプ文字列が日本語かどうかで判断できる UNIXシェルは糞of糞
やっぱりPowerShellだよな
シェルスクリプトは文字通りの逐次実行
sleepy-yoshi.hatenablog.com/entry/20090917/p1 >>903-904
ドットソースで実行してもだめなの?
function f1 {〜}
. f1 >>906
説明不足だった
やりたいことはコマンド入力じゃなくてSet-PSReadLineKeyHandler -Keyを使ったキーバインドなんだけど
ドット. で反映してくてもScriptBlockやFunctionのスコープに閉じ込められてしまうから解決にならない ま、そういうエンコーディング切り替え機能をどれだけ充実させても既存のbashやCMDのようなプロセス間通信はできないのでやるだけ無駄ってのはわかってる powershell内部でcmd呼んだらいいのでは
何がしたいのかわからんけど PowerShellからcmd を呼んだら負け、みたいな抵抗感が少しある 残念な仕様はあれども、ちゃんと書けば、ちゃんと動く
クソとは思わんな。便利は便利よ CSVを項目で検索し、ヒットした列を編集したいんだけど、パイプが理解しきれてないせいで上手いこといかない
$ArrCsvData | Where-Object{$_.CodeNo -match $Code} |
このあとにカンマ区切りのテキストファイルを該当列に上書きしたいんだけど、どうすればいいのでしょうか? >>913
まず、ArrCsvDataはCSVからオブジェクトに変換(ConverFrom-CSVやImport-CSV)した物なのかな
じゃないとプロパティで値を呼び出せないよ
「カンマ区切りのテキストファイルを該当列に上書きしたい」の意味が測り兼ねるけど、
条件に合致する行を編集したいなら
$ArrCsvData | ForEach-Object{ if($_.CodeNo -match $Code){$_.編集したい列名 = "編集後の文字列";$_ }
とやる。コツは編集後に「;$_ 」とやって出力する所。じゃないと編集だけして破棄する事になる。
さらにCSVで保存したいなら
〜 | Export-Csv -PSPath "保存先パス" ミス
if文の閉じカッコ忘れてた
$ArrCsvData | ForEach-Object{ if($_.CodeNo -match $Code){$_.編集したい列名 = "編集後の文字列";$_ }
↓
$ArrCsvData | ForEach-Object{ if($_.CodeNo -match $Code){$_.編集したい列名 = "編集後の文字列"} ; $_ } >>915
教えていただきありがとうございます
CSVは
「A001,,」
「B001,かきくけこ,12345」
のようなフィールドで
$Code = "A001"を検索し
「A001,あいうえお,12345」
のような内部のテキストファイルがあり、編集したい列名を指定せずにまとめて編集したいと思っています。
実際には編集する項目が多くループさせながら格納だと長くなってしまうため、省略できないかと思い相談させていただきました。 gc $csv_in -Encoding Default | %{ $fields = $_ -split ","; if ($fields[0] -match $Code) { $fieldsを加工; $fields -join "," } else { $_ } } | Out-File $csv_out -Encoding Default >>918
ありがとうございます
まだ理解できていないところもありますので勉強しながら試させていただきます get-aliasをalias、またはget-serviceをservice、
自作の関数でもget-testとしたらtest、のように
エイリアス定義無しでも
get-を省略して実行出来てしまう(または、省略したらget-*扱いになる)のですが
これについて記載されたドキュメントが何処にあるか
教えて頂けないでしょうか >>920
https://docs.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_parsing?view=powershell-7.2
PowerShell がコマンド入力を解析すると、コマンドレットまたはネイティブ実行可能ファイルへのコマンド名の解決が試みされます。 コマンド名が完全に一致しない場合、PowerShell は既定の動詞としてコマンドの前 Get- に付加されます。 PowerShellバカにしてたけど、安定性半端ないわ
適当にササッと書いたやつがなんのエラーもなくずっと正確に動いとる >>921
ありがとうございます!
このドキュメントが見つからず困っていました
助かりました 富士通が昔PowerCobolとか出してたからPowerなんちゃらは不安になる うちはウルトラCとかいうインタープリターだったなー >>927
そう?
方向性はともかくshよりだいぶ高機能になってると思う 質問です。
get-childitemのデフォルトのソート順は何でしょうか?(sort-objectを明示しない場合の並び順)
ソート順について記載されているドキュメントの所在でも良いです。 >>932
NTFSなら何もしなくてもUNICODEのコード順だかでソートされて出てくる
要するにファイルシステム次第 >>933
さて、どうかな
MicrosoftはSJIS時代のソート順をひきずってると思うぞ 932です。先ほどの質問についてご回答頂きありがとうございます。予めソートされていることがわかり、安心しました。
追加ですみませんが、もう1点質問をさせてください。(先ほどの質問は、当疑問からの派生でした。)
■前提事項
比較元と比較先でソート順を変えてdiffを取った場合、バイナリによる比較とハッシュ値による比較では結果が異なります。
具体的に申し上げますと、下記ディレクトリ構成の「file1.txt」を異なる内容にした場合、
バイナリ比較では、比較元の「修正前.xlsx」と比較先の「file1.txt」で差分を出力します。(ディレクトリの違いによるアンマッチを出力する。)
ハッシュ値の比較では、比較元の「file1.txt」と比較先の「file1.txt」で差分を出力します。(同ディレクトリ配下のアンマッチを出力する。)
■質問
なぜハッシュ値による比較では、比較元と比較先でソート順が違うのに同ディレクトリの差分のみを出力できるのか。(データ型の違いにヒントがあるのかなと思っていますが、解明まで至っておりません。)
■コード
$master = Get-ChildItem -LiteralPath [比較元ディレクトリ] -Recurse -File | Sort-Object{$_.LastWriteTime}
$work = Get-ChildItem -LiteralPath [比較先ディレクトリ] -Recurse -File | Sort-Object{$_.FullName}
@(Compare-Object (Get-Content -Encoding Byte $master.FullName) (Get-Content -Encoding Byte $work.FullName) -PassThru)
@(Compare-Object -Property Hash (Get-FileHash $master.FullName) (Get-FileHash $work.FullName) -PassThru)
■ディレクトリ構成(比較元と比較先で同一)
dir1
└─dir2
└─dir3
├─PG1
│ file1.txt
│ file2.txt
│ file3.txt
│
└─PG2
修正前.xlsx 長文になりすみませんでした。
ディレクトリ構成が崩れてしまいましたが、以下の通りです。
dir1\dir2\dir3\PG1\file*.txt
dir1\dir2\dir3\PG2\修正前.xlsx
別の場所で質問すべきということでしたら、その旨をお伝えください。
当スレに相応しくないようでしたら無視頂いて構いません。申し訳ございませんでした。 例えば、ソード結果が異なる、1,2,3 と、3,2,1 を比べれば、2しか一致しない >>917
Ruby で作ってみた
require 'csv'
# ruby ./script.rb ./input.csv (デフォルトは、$stdout)
# ruby ./script.rb ./input.csv > 出力ファイル
# 2列目に、カンマ・改行・シングル/ダブルクォーテーションを入れてみた
csv_text = %(A001,"あ,い\nう'え""お",123) #=> "A001,\"あ,い\nう'え\"\"お\",123"
csv_ary = CSV.parse_line( csv_text ) #=> ["A001", "あ,い\nう'え\"お", "123"]
# 引数は入力ファイル名・input.csv
CSV.filter( File.open( ARGV[ 0 ] ) ) do |row| # 1行ずつ処理する
if row[ 0 ] == csv_ary[ 0 ]
( 0...csv_ary.length ).each do |idx|
row[ idx ] = csv_ary[ idx ] # すべての列を差し替える
end
end
end
入力ファイル・input.csv
A001,,
B,1,2
A001,1,2
出力。A001で始まる、2行が置換された
A001,"あ,い
う'え""お",123
B,1,2
A001,"あ,い
う'え""お",123 目的とやってることがとっちらかってるな
なんで比較するのにLastWriteTimeでソートしてんの https://i.imgur.com/uWA4d1c.png
タスクマネージャーから手動で子プロセスだけ終了させることはできるけど
PowerShellでやるには Get-Process -Name explorer のあと
どうやって子プロセスのPIDを取得すればいいでしょうか?教えてください >>942
Get-WmiObjectかGet-CimInstance使ったら?
(Get-Process -Name explorer).Id | %{Get-CimInstance Win32_Process -Filter "ParentProcessId=$_"}
>>22 でも出てるよ 最近PowerShell使い始めたんだけど
大きなシステムを作るとき、メインと複数のサブルーチンとかも基本1つのファイルで完結させるのか?それともファイルを何個も分けるのか?
どっちだとしても可読性下がる気がする PowerShell ISEでスクリプトウィンドウは何で左側に表示できないんだろ
左側のほうが俺はやりやすいわ >>943
ありがとうございます。これで試してみます >>944
そもそも大きなシステムをPowerShellでは作らない >>944
>>948の通りPowerShellで大きなシステムを作る事自体がアンチパターンの極み
どうやっても可読性最悪だし破綻は避けられない powershellで大きめのものを組むならC#で組むときみたいな箱庭を作る発想は完全に捨てて、UNIX的な思考に切り替えるべき
完成度の高い単独で機能するコマンドを作って組み合わせていくようにすることで、ドメインを拡大させない
コマンド同士の細かい相互作用を作り込んではいけない Unix コンポーネント: 小さいことは美徳である
https://web.archive.org/web/20080709051701/http://www.os-omicron.org/~takano/private/trans/bongo-bong_j.html#:~:text=%E3%82%92%E6%8E%A2%E3%81%9B)-,Unix%20%E3%82%B3%E3%83%B3%E3%83%9D%E3%83%BC%E3%83%8D%E3%83%B3%E3%83%88,-%3A%20%E5%B0%8F%E3%81%95%E3%81%84%E3%81%93%E3%81%A8%E3%81%AF >>951
ちょっと読んでみたらIEのCOMベースってすばらしいよね真似しよが結論になってて時代を感じた
さてBonoboはUnix界でうまくいったのでしょうか
https://en.wikipedia.org/wiki/Bonobo_(GNOME) Get-Contentで取得したテキストファイルが
処理終わっても自分自身で開いていることが多い
別の処理で終わったこのテキストファイルを削除しようとすると
自分で開いているので削除出来ないでエラーが出る
処理が終わっても閉じない原因か対処法はないでしょうか >>954
なるほど破棄すると繋がりが消えるのか
ありがとうございます すみません、オブジェクト破棄を以下のように解釈していたのですが
そうなるとRemobe-Itemでファイルを削除するとき、変数に入れずにフルパスで指定するのか?と思ったけどやっぱり違うと思うし
改めて変数に入れるのも多分違うと思い、すっきりしない状態です。
多分破棄するの意味を間違って、こちらが解釈してると思うのですが、この場合どう書いてますでしょうか?
$lines = (Get-content $FilePath-as [string[]]
Remove-Variable FilePath
Remobe-Item $FilePath remove variableであってるとおもう。
GCに回収させるとより安全。
$nullを代入でもいけるかな ん?ファイル開いているのはlinesじゃないか?
linesを破棄しよう gcでファイル開きっぱなしなんてないと思うけど
削除できないってパターンはありそうだな
削除できるまで無限ループでいいんじゃね Get-content終わってもファイル開きっぱなしなんてあるの?
物凄いデカいファイルだったらあり得るのか? Get-content(cat)はcat.exeと違うバッファリング方法だからユーザーから見れば開きっぱなしに感じる場合もあるかも ___ ━┓ ___ ━┓
/ ― \ ┏┛/ ―\ ┏┛
/ (●) \ヽ ・. /ノ (●)\ ・
/ (⌒ (●) /. | (●) ⌒)\
/  ̄ヽ__) / | (__ノ ̄ |
/´ ___/ \ /
| \ \ _ノ
| | /´ `\
--------------------------------------
このスレはあなたにとって役にたちましたか?
○ とても役にたった
○ 役にたった
○ どちらともいえない
○ 役にたたなかった
● 全く役にたたなかった gcに-waitとか-tailとか付けると開きっぱなしになるけど、明示的に離せってスイッチは無かったっけ?
付けなけりゃ閉じてるものかと思ってた WindowsFormを使いGUIを作ろうと思っていますがtextboxのイベントハンドラが理解できていません
VBAでいうAfterUpdateをやろうと思っているのですが、
textbox1のフォーカスが別に移ったらlabel1にテストと表記したいのですが
そういった処理は可能でしたら下のどこを直せばいいのでしょうか?
Add-Type -AssemblyName system.windows.forms
Add-Type -AssemblyName system.drawing
$form = New-Object System.Windows.Forms.Form
$textbox1 = [System.Windows.Forms.textbox]@{
location = New-Object System.Drawing.point(10,10)
size = New-Object system.drawing.size(100,100)
}
$label1 = [System.Windows.Forms.Label]@{
location = New-Object System.Drawing.point(10,30)
size = New-Object system.drawing.size(250,20)
}
$form.Controls.Add($label1)
$form.Controls.Add($textbox1)
$textbox1.leave
({
$label1.text = "テスト"
})
$result = $form.ShowDialog() >>967
>$textbox1.leave
ここで行を分けてしまうとpowershellのパーサは一旦解釈を終えてしまうからイベントハンドラとして登録できてない。
それとイベンントハンドラの名前は頭にadd_〜を付ける決まりになってる(なぜかは知らない)
従って下のように記述する。
$textbox1.add_leave({
$label1.text = "テスト"
})
それとテキストボックスだけではフォーカスの移動が確認できないから
ボタンとか適当なフォーカスを持つコントロールを配置しておく
$button1 = [System.Windows.Forms.Button]@{ Location="10,50"; Size="80,20"; Text="ボタン"; FlatStyle="popup"}
$form.Controls.Add($button1)
$textbox1.add_leave({ $label1.text = "leave" })
$textbox1.add_enter({ $label1.text = "enter" })
$label1.text = "テスト"
$result = $form.ShowDialog() >>968
教えていただきありがとうございます。
テキストボックスだけだと移動が確認できないなど知らなかったのでとても助かりました。 入力コントロールがフォーカスを失ったという、イベントは無いの? よろしくお願いします。
現在開いているexcelのアクティブブックを捕まる方法ないでしょうか??
例えば、アクティブブックのアクティブシートにのってるグラフの軸を全て変更したい時に、
excelからpowershell ISEに画面を変えて操作したいのです。 >974
ありがとうございます。
xlwingsだとアクティブブックつかめるけど、グラフの細かな設定がない
openpyxlだとアクティブブックをつかめなさそう、
でpowershellでできないかな、と。 pandasに無いような高等な統計関数が必要でないかぎりpythonで完結したほうが楽なんじゃね ありがとうございます。
まぁ、会社でみながexcel使ってるので、、こんな質問をしている次第です、、 シートの名前やらインデックスがpwshでわかれば、その情報をpythonに渡してmatplotlibでtemp.jpgとかで吐き出したグラフをまたpwshで貼れば行ける気がする ActiveWorkBookプロパティで捕まえられるでしょ
VBAから呼んでもPowershellから呼んでもPythonから呼んでもいい 余計なお世話ついでに
ISEはもう終わったプロジェクトなので
後継のVSCode+Powershellプラグインに乗り換えるのがオススメ 色々アドバイスありがとうございました。
それもそだな、と下記でいけました。お騒がせいたしました
$Excel = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Excel.Application")
$Excel.ActiveWorkbook.ActiveSheet.name 教えて下さい
powershellで再帰処理をしたいんですが、
"The script failed due to call depth overflow"
と言うエラーで最後まで処理してくれません。
再帰回数のスタックオーバーフローで
トランポリン処理が有効とまでは調べたのですが
上手く理解出来ず
↓↓
https://qiita.com/yumura_s/items/8a44a70e3e11c4eb1464
詳しい方、よろしくお願いします そのメッセージの言わんとするところは、すげー効率悪いので再帰で書くな
というアドバイスです 対象データが階層構造になっていて、
網羅的に処理したいんですが、うーん 500階層あるデータ構造はさすがに扱ったことがない…
そもそも特定の枝が底なし沼なのだとしたら、それでも延々と潜り続ける、というのは本当に意図した挙動なのか?
底なし沼が時々存在して、それに興味が無いのならば素直な余再帰で書ける幅優先探索を勧める
深さ優先で頑張りたいなら、スタックとしてコールスタックを流用するのでなくて、明示的にスタックにpush/popすると少しは経済的
特定の深さに達したら諦める決め打ちもあり
トランポリンで遅延評価を積む利点は、入力データ構造を処理するというより、需要に応じて任意の深さのデータを出力できるという点にあるので、悪手かと トランポリン?のやってることはSchemeで言うCPS相当だね。まずCPSを理解しないと何が起きてるのか判らないと思う。
であるならば理屈ではトランポリンなんて変な事しなくてもスクリプトブロックをクロージャにするやつだけで再帰をクロージャの連鎖呼び出しに置き換えることはできると思う。 (実装は暗黙のCPSかもしれないけど) schemeだとdelay/forceそのまんまじゃね
イテレータとかストリームとか色んな言い方があるけど、何にせよ処理すべきデータがまだ存在していないような時にのみ有効
もし処理対象のデータが既に存在しているのなら、単に無駄な計算を増やすだけだよ 再帰処理したいつってる本人が理解できないと意味ないからな
再帰が軽い言語で処理すりゃいいんじゃねーの すみません、めちゃくちゃ難しいっす
なんとなくリンク先のスクリプトが
動かせればと思ったのですが…
やはり悪手なんですかね データのサンプル、期待する出力を書いてくれれば具体的なコード提案できるかも(たぶん) 色々回答してありがとうございました
結局再帰を使わずループで代用する
こととしました
トランポリンはもう少し
勉強してみたいと思います powershell内でC#埋め込めばいいんじゃないの
あいにくpowershellのクロージャはダイナミックスコープで使えたもんじゃないのでC#のサンプルだけ
Add-Type -TypeDefinition @"
using System;
public static class test {
static int fib(int n) { //普通の再帰
if (n < 2) {
return n;
} else {
return fib(n - 1) + fib(n - 2);
}
}
static void fibcps(int n, Action<int> cont) { // CPS(継続渡しスタイル)
if (n < 2) {
cont(n);
} else {
fibcps(n - 1, n1 =>
fibcps(n - 2, n2 =>
cont(n1 + n2)));
}
}
public static void recurse() {
for (var n = 0; n <= 20; ++n) {
Console.WriteLine("fib {0}: {1}",n,fib(n)); //普通の再帰
fibcps(n, r => Console.WriteLine("fibcps {0}: {1}",n,r)); // CPS(継続渡しスタイル)
}
}
}
"@
[test]::recurse() 一応powershell版。ただしpowershell関数は末尾再帰の最適化をしてくれないためCPSで書いてもただの効率悪い再帰にしかならない。
上のC#も32bit環境だと末尾再帰の最適化が働かないため64bit環境でのみ有効なコード。
function fib($n) {
if ($n -lt 2) {
$n
} else {
(fib ($n - 1)) + (fib ($n - 2))
}
}
function fibcps($n, $cont) {
if ($n -lt 2) {
& $cont $n
} else {
fibcps ($n - 1) {param($fib1); $cont = $cont
fibcps ($n - 2) {param($fib2);
& $cont ($fib1 + $fib2) }.GetNewClosure()}.GetNewClosure()
}
}
1..10 | %{ $r=fib $_; "fib($_):$r" }
1..10 | %{ fibcps $_ {param([int]$r) "fibcps($_):$r"}.GetNewClosure() } あえて混乱させようとしてるようにしか思えない
仮に末尾最適化でシリアルなコードを得たとして、まさかそれが木の探索に有利だとでも?
呼び出しをstart-(thread)jobで行ってスレッド/プロセスをばら撒けば済む話じゃないの
コールスタック溢れるような計算であればあるほど、スケーラブルで高速 スタックを使わない再帰呼び出しならスタックは溢れないなw
個々の再帰呼び出しをStart-ThreadJob/Wait/Receiveで機械的に置き換えればとりあえず動く雛形にはなる
代わりにプロセス/スレッドが溢れるけど、スレッドなら単に順番待ちに入るだけで悪さはしない
個々のワーカーが自身の子をwaitしている限りはオーバーヘッドでしかないので、メインプロセスを設けStart時に-StreamingHostで直接報告を挙げさせるべき
長く走ってる枝を殺す等、最適化の可能性は大
メモ化や大域脱出程度で済むような問題には薦めない このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 341日 2時間 5分 41秒 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php レス数が1000を超えています。これ以上書き込みはできません。