12
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[PowerShell] たまに書くワンライナー

Last updated at Posted at 2022-03-20

PowerShellにはがあり、配列、連想配列、オブジェクト等を扱えます。パイプライン処理もできます。これを生かして手元で何かごちゃごちゃすると便利なのですが、普段使わないので忘れがちです。それを書き留めます。そして忘れます。

基礎

パイプライン処理ではforeach, where, select, sortなどのコマンドをよく使う。
渡されたデータの各要素に$_でアクセスできる。
%foreachを、?whereを意味するエイリアス。ややこしいので気をつけて使う。

(例)where でフィルター、foreachで加工、改行せずにコンソール出力
@(1..10) | where {$_ % 2 -eq 0} | foreach {"${_} "} | Write-Host -NoNewline
# 2 4 6 8 10 

(1-10の連番を生成し、2で割り切れる数のみ、空白で区切って、改行せずに出力)

ファイル名の変更

カレントディレクトリの全ファイルの拡張子を.txtにする
ls | foreach {ren $_ ($_.BaseName + ".txt")}
.logファイルの拡張子を.txtにする
ls | ?{$_.Extension -eq ".log"} | %{ren $_ ($_.BaseName + ".txt")}

lsはカレントディレクトリのファイルを列挙する。各ファイルオブジェクトには.BaseNameのようなメンバがある。
また、renはファイルオブジェクトと新ファイル名を受け取ってリネームする。

文字列を扱う

ファイルから空行を消す
cat sparse.txt | where {$_ -ne ""} > dense.txt
# sparse.txt の空行を消したものを dense.txt として出力
(数値型変数の展開)
$n = 10

echo ("$n + 1 = " + ($n+1))
# 10 + 1 = 11

echo(      $n + 1 )
# 11
echo("" + ($n + 1))
# 11
echo("" +  $n + 1 )
# 101

echo("${n}yen")
# 10yen
echo('${n}yen')
# ${n}yen

日付時刻

(Get-Dateを使う)
(Get-Date).GetType().Fullname
# System.DataTime という型

(Get-Date).AddHours(-1)
# 1時間前のDataTimeが得られる
1時間以内に作成されたファイルを表示
ls | where {(Get-Date).AddHours(-1) -le $_.CreationTime}
1時間以前に作成されたファイルを全消去(危ない)
ls | where {$_.CreationTime -le (Get-Date).AddHours(-1)} | rm

()でコマンドを囲むと結果をオブジェクトとして扱える

連番で何かする

@(n..m)で配列を作ってパイプで渡す。(n..m)とも書ける。

CSVを作成(列名なし)
@(1..10000) | foreach {"${_},user_${_}"} > foo.csv
生成されるデータ
1,user_1
2,user_2 ...
値にダブルクォーテーションを含めたい場合
@(1..10000) | foreach{"$_" + ',"user ' + $_ + ' is here"'} > foo.csv
生成されるデータ
1,"user 1 is here"
2,"user 2 is here" ...
  • ""で括らないと変数が展開されないので先頭は"$_"
  • 文字としてのダブルクォーテーションは''の中に書いた方が分かりやすい
  • 真ん中にある$_""で括る必要はない
    • (前方の文字列と+しているので文字列と解釈される)

補足

文法をおさらい

  • 変数の先頭に$が付く
  • |でパイプ(次のコマンドに向けて出力)して、>とか>>でファイルに出力
  • $_でパイプで送られてきたデータの各要素を参照
  • "で囲むと$n ${n}という表記で、文字列中で変数を参照できる
  • 'で囲むと変数を展開しない
  • {}で囲まれた処理を「スクリプトブロック」と言う
  • ()でコマンドを囲むと結果をオブジェクトとして扱える
  • []で配列やオブジェクトの各要素にアクセスする
    • (ls)[0] でカレントディレクトリのファイル1つを対象に取れる

cmdletの補足

こんな感じでプロパティについて調べる(stackoberflowより)
ls testfile1.txt | Get-Member BaseName | format-list

TypeName   : System.IO.FileInfo
Name       : BaseName
MemberType : ScriptProperty
Definition : System.Object BaseName {get=if ($this.Extension.Length -gt 0){$this.Name.Remove($this.Name.Length - 
         $this.Extension.Length)}else{$this.Name};}
  • renRename-Itemのエイリアス
  • Get-Dateの返すDateTimeについてオブジェクトのプロパティとメソッドを表示するには、パイプラインの下に オブジェクトを 送信します Get-Member。 たとえば、「 Get-Date | Get-Member 」のように入力します。だそうです
    • いやドキュメントに書いといてくれよ

これマジ?

"a" + 1 👈 😉「a1」
1 + "a" 👈 🤬「値”a”を型"System.Int32"に変換できません。」
"" + 1 + "a" 👈 😌「1a」)

@(1..10) 👈 😉「1, 2, ... 10」
@(1...10) 👈 😤「1, 0」(.100.1と解釈されて、丸めて0
@(1...50) 👈 🤔「1, 0」
@(1...51) 👈 🤔「1」

@(1...50000000000000005) 👈 🤯「1, 0」
@(1...50000000000000006) 👈 😇「1」(環境に依存しそう)

ビル・ゲイツ!!!

12
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?