
TechNet コラムへようこそ。このコラムでは、よく寄せられるシステム管理スクリプトに関する質問に Scripting Guys がお答えします。システム管理スクリプトについて質問がある場合は、scripter@microsoft.com (英語のみ) までお送りください。すべての質問に回答することはできないかもしれませんが、可能な限り対応いたします。
詳細情報
| • | |
| • | |
| • |
![]()
Scripting Guy さん、よろしくお願いします。Windows PowerShell を使用して、テキスト ファイルに含まれるすべてのアスタリスクを他の文字に置き換える方法はありますか。
-- RC

RC さん、こんにちは。このコラムを執筆している Scripting Guy は、多くの人からこのように聞かれます。「どうやっているのですか。一体どうやって毎日欠かさず新しいコラムを執筆しているのですか」と。(もちろん、他の多くの人からは、どうして毎日新しいコラムを書くのかと聞かれますが、それはまた別の話ですね)。「毎日欠かさずですよね」と多くの人は驚きます。「Hey, Scripting Guy! コラムの執筆にうんざりすることはないのですか」と言われます。
信じられないかもしれませんが、その質問への答えは "いいえ" です。このコラムを執筆している Scripting Guy は、Hey, Scripting Guy! コラムの執筆に決してうんざりすることはありません。実際、このコラムを執筆している Scripting Guy は、世界中で一番健康かもしれません。それは厳しい食事制限と運動を行っているからなのか、ですって。いいえ、そういうわけではありません。ただし、TV を見ることが運動で、ドーナツが健康食であると考える場合は別です。そうではなく、このコラムを執筆している Scripting Guy が健康な理由はただ 1 つ、働きすぎで過剰なストレスにさらされているからです。
事実、仕事のストレスは体に良いと言われています。ヨーロッパの研究者たちがこのほど、人は毎日仕事をしているときよりも休暇中の方が病気になる危険性が高いことを発見しました。研究者たちは、その理由は職場のストレス要因によって体の防御機構が活性化し、病気や感染を予防しやすくしているからであると説明しました。家でくつろぎ、リラックスしていると、体の防御機構が弱まって、あっという間に風邪やインフルエンザにかかります。本当に健康になるには、職場のストレスが必要なのです。
これは、このコラムを執筆している Scripting Guy にとっては良い知らせです。何しろ、もし職場のストレスが人を健康にするのであれば、彼はおそらく 190 歳まで生きるでしょう。少なくとも、当分の間は生きています (そして、働いています)。
そして、それは彼の旧友である編集者にとっては大きなスリルとなるかもしれません。
注 : 考えてもみてください、編集者。この先何十年も同じチームで働けるんですよ。そのこと自体はあまり楽しくなさそうに思えるかもしれませんが、それによってどれだけ健康になれるかを想像してみてください。 |
(今度の 2008 年冬季スクリプト競技大会の準備のために) 午前中を掛けて Perl スクリプトの記述方法を考えたことを思えば、今日は特に "健康" な気分です。このことを念頭に置いて、Windows PowerShell を使用してテキスト ファイルの文字を置き換える方法をご説明しましょう。たとえば、次のようなテキスト ファイル (C:\Scripts\Test.txt) があるとします。
This is line 1.* This is line 2*. *This is line 3. This is * line 4.
また、(ある理由で) これらの厄介なアスタリスク (*) をアットマーク (@) に置き換える必要があるとします。どうすればいいかというと、次のスクリプトを使用します。
(Get-Content C:\Scripts\Test.txt) |
Foreach-Object {$_ -replace "\*", "@"} |
Set-Content C:\Scripts\Test.txt
ご覧のとおり、これは単純なスクリプトです。実際、Web ページの幅がもう少し広ければ、全体を 1 行で記述していたでしょう。まず、Get-Content コマンドレットを使用して、C:\Scripts\Test.txt ファイルからテキストを読み取ります。既定では、テキストは配列として読み取られ、配列の各項目はテキスト ファイル内の 1 行を表します。そして、Get-Content コマンドをかっこで囲んだことに注目してください。なぜこのようにしたかというと、PowerShell によって、他の処理が行われる前にファイルの内容全体が読み取られるようにするためです。
では、PowerShell によってテキスト ファイルの内容全体が読み取られた後は、どうするのでしょうか。次は、読み取った内容を Foreach-Object コマンドレットにパイプします。少し前に述べたように、PowerShell によってテキスト ファイルの内容が読み取られると、その情報は自動的に配列に格納されます。次に、Foreach-Object コマンドレットによって、配列のすべての項目がループ処理されます。つまり、テキスト ファイル内のすべての行がループ処理されます。そして、Foreach-Object コマンドレットによって、それらの行ごとに次のスクリプトが実行されます。
{$_ -replace "\*", "@"}
おそらくご存知でしょうが、Windows PowerShell パイプラインでは、$_ は現在のオブジェクトを表します。この場合、1 回目のループ処理では、$_ はテキスト ファイルの 1 行目を表します。2 回目のループ処理では、$_ はテキスト ファイルの 2 行目を表します。そして、これ以降も同様です。これらの行ごとに (つまり、これらの文字列値ごとに)、Replace メソッドを使用して、各行に含まれるすべてのアスタリスクを @ 記号に置き換えます。それに必要な作業は、対象の文字 (アスタリスク) とそれに続けて置換テキスト (@ 記号) を指定するだけです。
ここで注意が必要なのは、アスタリスクが Windows PowerShell の予約文字であるという点だけです。このため、アスタリスクを使用して検索と置換の操作を実行するには、その文字を "エスケープ" する必要があります。その処理はどのくらい難しいのか、ですって。まったく難しくありません。アスタリスク (または、その他の予約文字) の前に \ を追加する必要があるだけです。
"\*"
そして、この処理はとても重要です。円記号を省略すると、ループ処理を 1 巡するたびに次のようなエラー メッセージが表示されます。
無効な正規表現パターン: *。
発生場所 C:\scripts\test.ps1:2 文字:33
+ Foreach-Object {$_ -replace "*", <<<< "@"} |
もちろん、アスタリスクをエスケープする必要がある理由は、単にアスタリスクが正規表現では予約文字だからである、という点に注意する必要もあります。予約文字以外の文字を検索する場合は、\ は不要です。
{$_ -replace "a", "@"}
つまり、\ が必要な場合とそうでない場合があるということでしょうか。文字をエスケープする必要があるかないかは、どのようにして特定できるのでしょうか。これは頭が痛くなる疑問です。
ですが、心配は要りません。思い出してください、ストレスは体に良いのです (ということは、「さあ、心配してください」と言うべきだったかもしれません。何しろ、心配は多大なストレスを引き起こしますから)。どの文字が予約文字であるかを覚えておく必要はありません。どの文字が予約文字であるかは、次に示します。(MSDN から引用した) 次の一覧が予約文字の "完全な" 一覧であると断言することはできませんが、手始めには良いでしょう。
| • | $ |
| • | ( ) |
| • | * |
| • | + |
| • | . |
| • | [ ] |
| • | ? |
| • | \ |
| • | / |
| • | ^ |
| • | { } |
| • | | |
では、スクリプトの説明に戻りましょう。Foreach-Object コマンドレットによる検索と置換の操作が完了すると、仮想テキスト ファイルは Set-Content コマンドレットに渡されます。次に、Set-Content コマンドレットによって、変更されたデータが元の C:\scripts\Test.txt ファイルに書き込まれます。
Set-Content C:\Scripts\Test.txt
これで完了です。
おっしゃるとおり、確かに少し簡単すぎますね。では、Test.txt を開いて何が起きたか見てみましょう (何か起きていればの話ですが)。
This is line 1.@ This is line 2@. @This is line 3. This is @ line 4.
いやあ、これは驚きました。本当に簡単にできましたね。
これでご質問の回答になっているとよいのですが、RC さん。回答になっていない場合はお知らせください。ところで、このコラムを執筆している Scripting Guy は少し困惑しています。彼は今日、早く帰宅するつもりでした。それは、仕事をするよりもずっと楽しいことのように思えました。唯一の問題は、仕事から離れるほど、この Scripting Guy が病気になる危険性が高まることです。実際、本当に永遠に生きたければ (彼はそう願っています)、毎晩遅くまで残業する必要があります。週末も、休日も、ずっとです。
うーん。おそらく、研究者たちは推測を再確認するべきです。何しろ、長時間働いて休暇を取らなくても永遠に生きられない可能性は十分にあります。ただ、永遠に生きてきたような錯覚を起こさせるだけです。
ですが、それも心配は要りません。最高齢の Scripting Guy である Peter Costantini にちょっと聞いてみましょう。Peter なら知っているはずです。何しろ、彼は実際、ほとんど永遠の時を生きてきたのですから。