PowerShell -Part 5
レス数が950を超えています。1000を超えると書き込みができなくなります。
まあでも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 レス数が950を超えています。1000を超えると書き込みができなくなります。