質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.48%

  • Windows

    1734questions

    Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

  • PowerShell

    492questions

    Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

PowerShellでテキストファイルの編集で困っています

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 3,343

r.y.o

score 31

PowerShellでテキストファイルの編集を行いたいと思っています。
どうしてもうまくできず困っております・・・どなたかお助け願えませんでしょうか。
コードの書き方が全くあってないだろうと承知はしております・・・

<やりたいこと>
テキストファイルの
・1行目では、記載されている内容を指定した文字で前後挿入
・2行目~n行目までは、決まった文字で記載された内容を前後挿入
・n行目の最後は先頭文字列のみ挿入
・最終行は、指定文字で追記
といったところです。

<考えてみたコード>
$filename  = "C:\r.txt"
$filename2 = "C:\Uk.txt"

$bfline = "レシピ"
$afline = "今日のレシピはこちらです!"

Get-Content $filename | % { $_ -creplace $bfline, $afline } > $filename2 
$file = New-Object System.IO.StreamWriter($fileName, $True, [System.Text.Encoding]::GetEncoding("sjis"))
while (($line = $file.WriteLine()) -ne $null)
{
$file.WriteLine($line) > $filename2
Write-Host("・" + $line + "、") > $filename2 
}
Write-Host("")
$file.Close()

Write-Host("以上です")

<テキスト例>
【加工前】
レシピ
じゃがいも
にんじん
カレールー
豚肉
ごはん

【加工後】
今日のレシピはこちらです!
・じゃがいも、
・にんじん、
・カレールー、
・豚肉、
・ごはん
以上です

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

こんにちは。
ご提示のコードの何がダメかは imihito さんの回答の通りですので、私からはざっくり動作するコードを提示します。

# Windows 10, PowerShell 5.1な環境で動作確認ずみ
$HeaderTemplate = "今日の{0}はこちらです!"
$DetailTemplate = "・{0}、"
$FooterTemplate = "以上です。"
Get-Content .\recipe_base.txt -Encoding Default | ForEach-Object -Process {
    if ( $_.ReadCount -eq 1 ) {
        # 1行目はヘッダ扱い
        Write-Output ($HeaderTemplate -f $_)
    } else {
        # 2行目以降
        Write-Output ($DetailTemplate -f $_)
    }
} -End {
    # 最終行を処理した後
    Write-Output "$FooterTemplate"
} | Out-File .\recipe_result.txt -Encoding Default -Append:$false
  • recipe_base.txt
レシピ
じゃがいも
にんじん
カレールー
豚肉
ごはん

の部分になり、処理の結果はrecipe_result.txtに出力されます。 

  • 実行結果
今日のレシピはこちらです!
・じゃがいも、
・にんじん、
・カレールー、
・豚肉、
・ごはん、
以上です。

・ごはん、

と最後の行の後ろにが残っていますが、まあ、そのあたりは頑張って直してみてください。

 簡単に解説

ForEach-Objectコマンドで-Process-Endパラメーターを指定していますが、これはそれぞれ

  • -Process : Get-Contentで得た各行ごとに実行される
  • -End : Get-Contentで得たすべての行の処理が終わった後に実行される

ものとなります。
$_にはrecipe_base.txtの各行の文字列が設定されます。  
Get-Contentを使った時だけ使用可能な特別なプロパティReadCountで現在の行数を取得することができ、1行目とそれ以外を判定しています。

また、文字列の変形には書式指定演算子(-f)を使用しています。  
こちらはC#などのString.Formatメソッドと同等の機能となります。  

文字コードについて、日本語Windows環境であれば-Encoding DefaultはSHIFT_JISになります。 

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/12 12:04

    お返事遅くなり申し訳ございません。
    解説及び参考となるコードを提示いただきありがとうございました。
    大変参考になりました。
    本サンプルをベースに自分が希望するものを作ることが出来ました。
    ありがとうございました。

    キャンセル

+1

コードが見にくいです。
コードの上下の行に「```」を挿入すると、多少見やすくできます(</>ボタンを押しても挿入できます)。

今回のやりたいことの場合、Get-Contentの結果を一度変数に格納し(行毎の配列になります)、その中身を修正してから改めて出力、とすると上手く出来そうな気がします。

機能・動作的にいくつか勘違いされている、ちゃんと理解されていないと思われる点を挙げておきます。

 >演算子

>演算子は「直前のコマンドの結果を指定したファイルに出力する(常に上書き)となります。

そのため

"a" > $filename  
"b" > $filename  

とすると、結果は

b  

となります。

既存の内容を維持して追記したい場合は>>を使用します。 また、そのためのコマンドレットとしてAdd-Contentも存在します。

>>>の違いはシェル系一般の話です。

 WriteLineメソッド

WriteLineメソッドは「指定されたものを改行付きで書き込み、結果を返さない」メソッドです。

結果を返さないので、変数に入れたり、リダイレクトしたところで空($null)が入るだけです。

 Write-Hostコマンドレット

Write-Hostコマンドレットは「指定されたものをコンソール画面(Host)に出力し、結果を出力しない」コマンドレットです。

そのため

Write-Host("なにか") > $filename  

としても、$filenameには何も出力されません(>なので空の出力で上書きされます)。

なお、何かコマンドを実行したとき結果がコンソールに表示されるのは、「出力先が指定されなかった結果はコンソール(標準の出力先)に出力される」となっているためです。

Write-Host   "なにか" # 直接Hostに出力  
Write-Output "なにか" # 結果出力→出力先が指定されないので、Hostに出力  
"なにか" # `Write-Output "なにか"` と同じ  

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/12 12:03

    お返事が遅くなり申し訳ございません。
    見づらさの指摘ありがとうございました。
    また、私の勘違い個所等をご指摘いただき大変参考になりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.48%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Windows

    1734questions

    Windowsは、マイクロソフト社が開発したオペレーティングシステムです。当初は、MS-DOSに変わるOSとして開発されました。 GUIを採用し、主にインテル系のCPUを搭載したコンピューターで動作します。Windows系OSのシェアは、90%を超えるといわれています。 パソコン用以外に、POSシステムやスマートフォンなどの携帯端末用、サーバ用のOSもあります。

  • PowerShell

    492questions

    Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。