PowerShell -Part 7
XMLヘルプファイル用意して参照させればParam()のないfunctionに対し「構文」部分を書ける。 PowerShell標準から外れた「引数に -i を複数回指定」みたいな内容を書けるかは知らん。 国内公式からLenovoのノートPC買ったら何故かISEが英語環境になって意味わからん。 どこに言語設定あるの?当然OSは日本語設定にしてるし、他のアプリも日本語になってる。 これまでLenovoのPCは5台くらい買ってきたのにISEだけ英語になるの初めてなんだが。 https://i.imgur.com/H4NVkKH.png そういうのsurfaceでもあったな OSセットアップ時の国設定が半端に適用された状態だから入れ直した方が早いかも >>85 Windowsは英語版を日本語に切り替えると日本語にならないところがある だから日本語版でインストールした方がいい ちなみにいまどきISEを使っているのもよくわからない powershell iseってのを知らなかったけど起動したらUIシンプルで美しいな VSCodeもこれくらいシンプルになってくれんかな カスタマイズしてシンプルにすればいいと思うよ 俺はどちらかというとVSCodeのほうが機能美を感じる デフォルトで万人の感性にフィットするモノは存在しない カスタマイズも嫌なら自分で作るか作らせるか Class C { $a = '失敗' } function f { Param([ref]$r); $r.Value = '成功' } $o = [C]::new() f ([ref]$o.a) $o.a $t = '失敗' f ([ref]$t) $t こんなの聞いてないよ 何が言いたいのかわからないw コードを実行した結果が書かれてないので 何を言いたいのか知るにはこのコードを実行しなきゃならない めんどくさいw $o | Get-Member を実行してみれば分かるけど$o.aはフィールドじゃなくてプロパティだからな $o.aのgetter( $o.get_a() )の戻り値を関数に渡しても$o.aの値は変わらない パワーシェルすげえな 仕事がどんどん片付いていくよ 2つのCSV(どちらも同じヘッダー)で両方に一致するデータ行があった場合にその行を2つのCSVから取り除きたいんだけどどうしたらいいの? ヘッダーがDate,Shop,Sales だとしてユニークな項目がなく全く同じデータが1つ目のCSVに1行、2つ目のCSVに2行あった場合に2つ目のCSVは1行だけ消したい Where-object だと2行とも消えちゃう 2つのCSVをどうやってwhere-objectに渡してんだよ その2行が消える間抜けコード晒してみなよ # CSVファイルを読み込む $csv1 = Import-Csv -Path 'csv1.csv' $csv2 = Import-Csv -Path 'csv2.csv' # CSV1の各行について foreach ($row1 in $csv1) { # CSV2の中で一致する行を探す $match = $csv2 | Where-Object { $_.Date -eq $row1.Date -and $_.Shop -eq $row1.Shop -and $_.Sales -eq $row1.Sales } # 一致する行が見つかった場合 if ($match) { # CSV1とCSV2から一致する行を削除 $csv1 = $csv1 | Where-Object { $_ -ne $row1 } $csv2 = $csv2 | Where-Object { $_ -ne $match[0] } } } # 結果を出力 $csv1 | Export-Csv -Path 'csv1.csv' -NoTypeInformation $csv2 | Export-Csv -Path 'csv2.csv' -NoTypeInformation わーいできたー $csv1=gc csv1.csv $csv2=csv2.csv #どうせ全一致ならテキストのまま比較すりゃいいだろ $i=0 foreach($row in $csv1){ $csv2|%{ $j=$k=0 }{ if($_ -eq $row -and $i -eq 0){ $csv1[$i]=$csv2[$j]=$null $k=1 } $j++ } $i++ } $csv1|sc csv1.csv $csv2|sc csv2.csv $i1 = "csv1.csv" $i2 = "csv2.csv" $o1 = "csv1_out.csv" $o2 = "csv2_out.csv" gc $i1, $i2 | group readcount | ?{$_.group[0] -ne $_.group[1]} | foreach{$_.group[0] | ac $o1; $_.group[1] | ac $o2; $_.group[0].readcount} 段階を踏まないのは謎だよな ファイルをコピーする概念もなさそう これで良かったわ $csv1=gc csv1.csv $csv2=gc csv2.csv $compare=compare $csv1 $csv2 $compare|?{$_.SideIndicator -eq "<="}|% InputObject|sc csv1.csv $compare|?{$_.SideIndicator -eq "=>"}|% InputObject|sc csv2.csv CSVファイルに想定外のデータがあることを考慮しないのか わ仕事早い… csv1の方はDateがYYYY/MM/DDの10桁固定で csv2の方はDateがYYYY/M/Dで8〜10桁になってて 日付としてみれば同じなんですが1行を文字ででみると違う可能性があります… 後出しですいません またShopはだいたい一致してるのですが 「ローソン札幌店」と「ローソン札幌」や「ローソンサッポロ」みたいな内容が異なることがあってそこを必ず自前のfunctionの変換リストかましてから比較する予定でした 私の想定を超えるプログラムでfunctionを挟むこともできない カラムの曖昧さとかは全く興味沸かないなあ自分でやんな 昨日の少し試しましたが $compare=compare $csv1 $csv2 $compare|?{$_.SideIndicator -eq "<="}|% InputObject|sc csv1.csv $compare|?{$_.SideIndicator -eq "=>"}|% InputObject|sc csv2.csv でうまくいきそうです ありがとうございます 自分でつけてる家計簿からクレジットで相殺してる項目だけ出力したcsvと 三井住友のVpassの明細(ファイルの日付的には翌月)を突き合わせを自動でやって7割ぐらい減ってくれたらいいなと思って AIにプログラム書かせたらすぐにできるかなと思ったけどAIもまだまだアホでした 土日に頑張ります 目的よりも手段にこだわっていると思われる テキストファイルとPowerShellだけで、イレギュラーなデータがあるかもしれないデータを操作をするのは、かなり面倒なやり方だぞ。 >>110 はキャラクタセットも気にしてなさそうなんだよな 行比較が出来るようになれば対象が何だろうが応用できるだろ 話はとっくに終わってんのよ >目的よりも手段にこだわっていると思われる これまんまお前のことじゃね? そんなに複雑なら、シェルの範囲を超えている。 Ruby など動的言語の出番 >>106 RubyのCSV では、コンバーターで変換器を自作する Ruby では、2024-01-01 のみ、Date 型へ変換できる。 2024/1/1,2024/01/01,2024-1-1 は変換できない。 以下のように、自分で変換器・コンバーターを定義すれば変換できる でも表記揺れは別の処理として、最初に一括して変換した方が安全 require 'csv' input_csv = <<"EOT" 2024/1/1,2024-1-2 2024/02/01,2024-02-02 EOT # Date 型へ変換する proc = Proc.new do |field, field_info| case field_info.index when 0 then Date.strptime( field, "%Y/%m/%d" ) # 0列目 when 1 then Date.strptime( field, "%Y-%m-%d" ) # 1列目 else field # 処理なし end end options = { :converters => proc } p CSV.parse( input_csv, options ) 出力 [ [#<Date: 2024-01-01>, #<Date: 2024-01-02>], [#<Date: 2024-02-01>, #<Date: 2024-02-02>] ] PowerShellだと何も考えずにDateTime変換できるのに、Rubyだとそんなに手間かかるのか もうそんな言語使うの止めて大人しくPowerShell使ったら? すいません初心者でとんちんかんな質問だったらごめんなさい PowerShellからarduinoにデータを送ってOLEDで表示するセンサーモニターを作ってます CPU・GPUの使用率や温度は取り出せて表示できたのですが FPSってどこからか取り出す方法ってありますか? 使用率や温度と違うのでPresentMonやAfterburnerからGet-Counterで取得する? とか考えて調べてるのですが分からなくて とんちんかんなこと言ってたらすいません できるできない含めて教えてください 基本的に、Go でも、こういうのしかない 2024-01-01 2024-01-01 15:01:01 それか、RFC 3339, RFC 3339 Nano これら以外を使っているシステムは、バグるからダメ! >>117 FPSて。要するにモニタのリフレッシュレートが欲しいんじゃろ? ほれ $RefreshRate = Get-WmiObject -Class:Win32_videocontroller | Select-Object -ExpandProperty CurrentRefreshRate >>119 返事ありがとうございます 言葉足らずですいません 頂いた情報は現在設定しているリフレッシュレートが表示されるようです 欲しいデータはGeForce ExperienceやMSI Afterburnerで画面上でオーバーレイさせて 表示しているリアルタイムのFPSとして表示されている数値なんです FPSやフレームレートで検索してましたがリフレッシュレートでも探してみます >>119 返事ありがとうございます 言葉足らずですいません 頂いた情報は現在設定しているリフレッシュレートが表示されるようです 欲しいデータはGeForce ExperienceやMSI Afterburnerで画面上でオーバーレイさせて 表示しているリアルタイムのFPSとして表示されている数値なんです FPSやフレームレートで検索してましたがリフレッシュレートでも探してみます 連投してましたすいません 引き続き皆さんの知恵を貸してください まずそれらがfps値返すようなAPI持ってるか調べなよ 無いなら値として取得は無理だろうね fps表示部分が単色ならそのエリアをキャプチャして数字認識でもした方が早そう >>123 ヒントありがとうございます APIを調べてみたらNVIDIAにNVAPIと言うのがありました ここからどうやって取り出すか調べてます もし良かったらもう少し何かヒントをください もうpowershell関係ないがPresentMon64に計測対象のPID渡せばfps取得できるみたいね >>125 はいPresentMonでもFPSを取れるみたいなのは調べました ただ、今arduinoㇸpowarshellからCPUGPUのデータを 受け取ってたのでそこと一緒に入れる方法が見つけられなくて Add-Type -AssemblyName System.Windows.Forms function ConvertShopName([string]$shopName) { switch -Wildcard ($shopName) { "ファミリーマート*" { $shopName2 = [regex]::Replace($shopName, "(ファミリーマート)([ ]*)(.*)(店)", { $args.groups[1].value + " " + $args.groups[3].value }) } "ローソン*" { $shopName2 = [regex]::Replace($shopName, "(ローソン)([ ]*)(.*)", { $args.groups[1].value }) } "セブンイレブン*" { $shopName2 = "セブンイレブン" } "マクドナルド*" { $shopName2 = "マクドナルド" } "すき家*" { $shopName2 = "すき家" } "Amazonで注文" { $shopName2 = "AMAZON.CO.JP" } default { $shopName2 = $shopName } } return $shopName2 } if ($Args.Count -eq 0) { [System.Windows.Forms.MessageBox]::Show("引数にファイルを指定してください", "エラー") return 0 } # 家計簿から抽出した csv ファイルを読み込む $excelData = Import-Csv $Args[0] -Encoding Default -Header "Date", "Shop", "Amount" | Select-Object @{ label = 'Date'; expression = { [DateTime]$_.Date} }, Shop, @{ label = 'Amount'; expression = { [int]$_.Amount } } # 引数で指定されたファイルをフォルダパスとファイル名(拡張子なし)に分離する $baseName = [System.IO.Path]::GetFileNameWithoutExtension($Args[0]) $folderPath = [System.IO.Path]::GetDirectoryName($Args[0]) # ファイル名から日付に変換する $targetDate = [DateTime]::ParseExact($baseName + "01日","yyyy年MM月dd日", $null) # 引数と同じフォルダにある Vpass からダウンロードした csv ファイル(ファイル名は翌月) を読み込む $vpassFile = $folderPath + "\" + $targetDate.AddMonths(1).ToString("yyyyMM") + ".csv" $vpassData = Import-Csv $vpassFile -Encoding Default -Header "Date", "Shop", "TotalAmount", "Type", "Count", "PaymentAmount", "ShopDetail" | Select-Object @{ label = 'Date'; expression = { [DateTime]$_.Date } }, Shop, @{ label = 'TotalAmount'; expression = { [int]$_.TotalAmount } }, Type, Count, @{ label = 'PaymentAmount'; expression = { [int]$_.PaymentAmount } }, ShopDetail echo "実行します . . ." # 家計簿データの Shop が "自動引き落とし" で Amount がプラスのデータを削除する $excelDataList = [System.Collections.ArrayList]$excelData | Where-Object { $_.Shop -ne "自動引き落とし" -and $_.Amount -lt 0 } # 家計簿データの 2項目目が空のデータ行を削除する $excelDataList = [System.Collections.ArrayList]$excelData | Where-Object { ![string]::IsNullOrEmpty($_.Shop) } # 家計簿のマイナスになっている消し込みデータをプラスに変換し、店名をクレジット明細側に変換する foreach($data in $excelDataList) { $data.Amount = $data.Amount * -1 $data.Shop = ConvertShopName($data.Shop) } # vpass データの Type, Count, PaymentAmount, ShopDetail が null のデータを削除する $vpassData2 = $vpassData | Where-Object { ![string]::IsNullOrEmpty($_.Type) -or ![string]::IsNullOrEmpty($_.Count) -or ![string]::IsNullOrEmpty($_.PaymentAmount) -or ![string]::IsNullOrEmpty($_.ShopDetail) } # vpass の Date, Shop, TotalAmount, Type, Count, Count, ShopDetail が null のデータを削除する $vpassData3 = $vpassData2 | Where-Object { ![string]::IsNullOrEmpty($_.Date) -or ![string]::IsNullOrEmpty($_.Shop) -or ![string]::IsNullOrEmpty($_.TotalAmount) -or ![string]::IsNullOrEmpty($_.Type) -or ![string]::IsNullOrEmpty($_.Count) -or ![string]::IsNullOrEmpty($_.ShopDetail) } # 抽出後のデータを格納するための変数 [System.Collections.ArrayList]$vpassDataList = @() [System.Collections.ArrayList]$unknownhDataList = @() # vpass データのデータを必要な項目のみにする foreach($data in $vpassData3) { if ( $data.Type -eq "1" -and $data.Count -eq "1" -and $data.TotalAmount -eq $data.PaymentAmount -and $data.ShopDetail -eq "" ) { $temp = $data | Select-Object Date, Shop, @{ label = 'Amount'; expression = { [int]$_.TotalAmount } } $vpassDataList += $temp } elseif ( $data.Type -eq "1" -and $data.Count -eq "1" -and $data.TotalAmount -eq $data.PaymentAmount -and $data.ShopDetail -ne $null ) { $temp = $data | Select-Object Date, @{ label = 'Shop'; expression = { $_.ShopDetail } }, @{ label = 'Amount'; expression = { [int]$_.TotalAmount } } $vpassDataList += $temp } else { $unknownhDataList += $data } } # 重複するオブジェクトを探す $commonObjects1 = Compare-Object -ReferenceObject $excelDataList -DifferenceObject $vpassDataList -Property Date, Shop, Amount -IncludeEqual | Where-Object { $_.SideIndicator -eq '<=' } $commonObjects2 = Compare-Object -ReferenceObject $excelDataList -DifferenceObject $vpassDataList -Property Date, Shop, Amount -IncludeEqual | Where-Object { $_.SideIndicator -eq '=>' } Add-Content $Args[0] "`r`n`r`n--------`r`n`r`n" Add-Content $Args[0] $unknownhDataList Add-Content $Args[0] "`r`n`r`n" Add-Content $Args[0] $commonObjects1 Add-Content $Args[0] "`r`n`r`n" Add-Content $Args[0] $commonObjects2 echo "終了しました。続行するには何かキーを押してください . . ." $host.UI.RawUI.ReadKey() ----- とりあえず形にはなりました。ありがとうございました! それだけプログラミングできるなら、 データベースもある、Ruby on Rails で稼げ PowerShell では稼げないだろ 無償のRDBに取り込んで操作すれば楽なのにな SQL Server ExpressもSQLもわからないのかもしれないが マイクロソフト製品じゃないとダメな理由がよく分からない SQL Server Expressを嫌がる理由がわからない FPS値を取得したがっていた者です あれから色々調べてHWiNFOから取得する事ができました ご協力ありがとうございました ウェブ開発では、Ruby on Rails 一択。 Railsは、PostgreSQL, MySQL, SQLite の3大データベースに対応している。 ただし本番用では、PostgreSQL一択。 SQLiteは開発用・個人用など AWS Aurora は、PostgreSQL, MySQLに対応している。 SQLiteはブラウザなど、多くのアプリに含まれて使われている デフォで存在してるところが良いんじゃないか わざわざインストールするのなら今更新規にRubyを入れるのは無いだろうな >>141 オラクル社とマイクロソフト社がクラウドの世界では提携しているのを知らないのか? 「主なRDB」でググった結果 Microsoft SQL Server. Oracle Database PostgreSQL. MySQL Amazon Relational Database Service. IBM Db2 Database. 家計簿レベルなら1ヶ月に多くても1000件ないでしょ csvをそのままOS標準で使える言語で処理するのがいいよ >>147 複式簿記というものを知らないのがバレているぞ 複式簿記の自作なんて無理。 テーブル数も、100 ぐらい行きそう 総勘定元帳とか、複数のテーブルを紐付けしないといけないから、 プログラムがめちゃめちゃ複雑。 これは有料の会計ソフトを使うべき 自作では、単純な単式簿記しかできない Ruby のCSV Table や、データベースを使うなら、Ruby on Rails とか。 Railsなら、3大データベースに対応している 参照、>>140 Rubyガイジってどこにでもわくんだな トコジラミ並み このスレは PowerShell -Part 7 です Set-ExecutionPolicyとSudoって何が違うん? とあるps1ファイルを実行する時にそのプロセスだけ実行ポリシーを変更するSet-ExecutionPolicy -ExecutionPolicy Bypass -Scope Processを実行後にxxx.ps1を実行してるんだが Sudoが実装されたし楽ちんになるなとSudo xxx.ps1を入力するとエラーになる どっちも一時的にパーミッションを変更してアクセス権限を付与するコマンドだと思うんだが何が違うんだ? >>153 そもそもいつからあなたのなかでは、ps1ファイルが実行形式ファイルになったのか? Powershell コンソールで、xxx.ps1 とするとエラーになる! パス付きで、./xxx.ps1, .\xxx.ps1 か、 powershell ./xxx.ps1, powershell .\xxx.ps1 なら実行できる だいたい間違って実行してしまわないような仕様にしたのがわからない世代がいるのか ダブルクリックのような感覚で簡単実行なんてUACすら邪魔だと思ってんのかな? 自分で作って自分かミスして自分だけの問題で終わるならかまわないが、そんな趣味でPowerShellを使っている人間なんてほとんどいないと思う。 コマンドレベルまで作り込んでテストされつくされているものと、自作のスクリプトをPATHに設定してどこからでも実行できるものが同列とはおそろしいな vscodeのターミナルと、windowsターミナルで同じpowershellでも認識できるコマンドが違うのなんでだろ プロファイル見るとそれぞれ同じpowershellのexe参照してるのに >>159 VSCodeはWindowsの一部じゃないぞ? VSCodeアプリケーションは、同じような動きと結果をマネているだけで、エミュレーションのようなことをしているのだから、完全に同じようにするのは困難。 大体ps1の1って何なのとか vbsやcmdやらがそのまま実行できるのにps1だけ半端に縛るのもおかしな話だし >間違って実行してしまわないような仕様 こんなのいつ決まったんだ MSでポリシーが統一されてるようには全く思えないんだが 世を取り巻くセキュリティ事情が日々刻々と変わっているのにかなり先発のvbsやcmdと同じじゃないからおかしいとな 少なくともある程度シェアを占める見込みがあるのだし前例踏襲に固執して0か100か思考に陥るほうがまずい そういう脊髄反射的な他責や論点ずらしの癖は周囲を白眼視させるだけじゃよ >>161 >>間違って実行してしまわないような仕様 >こんなのいつ決まったんだ powershellが出たばかりの頃に中の人が言ってたよ >大体ps1の1って何なのとか バージョン1の事 元々の計画ではPowerShell2向けのスクリプトファイルは.ps2にするつもりだった 拡張子にバージョン含めるアホは初めて見たかも Windowsの技術者の発想ではないね Powershellはこの拡張子含めて起動周りだけ残念 まぁMSはOSも言語も開発環境も既に人気もなく寿命もつきようとしてるから Windows最後の砦だったゲームもValveがProtonとSteam OS作ったからLinuxでほぼすべてのゲームが動いてパフォーマンスもWindowsより良い場合もある ただしあくまでエミュレートだからカーネルモードで動くアンチチートだけは動かなくてフォトナやヴァロやApexなんかの人気FPSが動かなかったり永久BAN対象になる まぁこれも時間の問題でWindowsが必要とされなくなるのは間近だな いるよねこういう極論振り回す人 脳内で完結してるから聞く耳を持たない プログラマに限らずIT界隈はMS批判するのがカッコいいと勘違いしてる人多いからね >>165 まあ、マイクロソフトだから、拡張子を3文字にする慣習が伝統的にあるせいかな。 >>167 いまでもシェアのほとんどがWindowsなのにね powershell 7.xってどういう立ち位置なんだろ windows標準では入ってないから、開発者向けなのかな Rubookは7.2が標準だけど PowerShell Core(6.0以降) では ・.NET Coreインストール可能なWindows以外のOSでも実行可能 ・デフォルト文字コードがUTF8(BOMなし)、改行がLF ・WorkFlowなど機能の一部は使用不可 あと WindowsPowerShell → PowerShell Coreで破壊的変更あり(PowerShell Core 破壊的変更でBingってください) C#のソースを流用する場合ジェネリックが使える7.3が便利かなと思います 自分は未だPowerShell Coreに移行出来ていません >>172 解釈はまかせるけど技術ブログでは以下の記載がある https://devblogs.microsoft.com/powershell/powershell-openssh-team-investments-for-2023/ > As a reminder, PowerShell 7 is built on the latest .NET which does not have the same support lifecycle as Windows. We can’t ship something as a feature in Windows that does not align with Windows’ support lifecycle. 用がないなら関わる必要ないんじゃね OSに標準で入ってる事しかメリット無いんだし SJISで出力しようとするとエラーで怒られるのはなんでなんですか 仕方がないのでnkf -s --overwriteでしのいでるんですが うまくいく >dir | Out-File -Encoding 'utf8' output.txt どちらもエラーが出る >dir | Out-File -Encoding 'shift-jif' output.txt >dir | Out-File -Encoding [System.Text.Encoding]::GetEncoding('shift-jis') output.txt Out-File : パラメーター 'Encoding の引数を確認できません。引数 "[System.Text.Encoding]::GetEncoding " は、ValidateSet 属性で指定されたセット "unknown,string,unicode,bigendianunicode,utf8,utf7, utf32,ascii,default,oem" に属していません。このセットの引数を指定して、コマンドを再度実行してください。 shift-jifになってますがjisでもちゃんとエラーになります コマンドレットの引数と.NETのそれを混同してるのでは -Encoding Defaultでしょ よく知らんけど、UTF8もSHIFT-JISもMS932 ASCIIも、全部半角英数文字なら、 完全に互換性あるよな❓ BOM付UTF8はダメだろうが ていうか、改行はLF CR LF+CR CR+LF のどれが正しいの❓ ていうか、拡張子mp3は音楽で音なのに、 でもてか、拡張子mp4は動画で映像だし、ま、音声も含まれてるけど もしかして、拡張子mp5は匂いとかになるのかな❓ なんて訳ないよね mp3: MPEG-1 Audio Layer-3 mp4: MPEG-4 Part 14 read.cgi ver 07.5.1 2024/04/28 Walang Kapalit ★ | Donguri System Team 5ちゃんねる