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

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

新規登録して質問してみよう
ただいま回答率
85.31%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

PowerShell

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

Q&A

解決済

3回答

1643閲覧

Powershellで、CSVファイル内の特定の文字だけ残したい

SUSU0703

総合スコア17

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

PowerShell

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

0グッド

1クリップ

投稿2023/07/19 06:41

編集2023/07/19 09:17

こんにちは。

とあるCSVファイルがあり、以下のようにUsername、とAssigned_toという二つのコラムがあり、その下に
ユーザ名と、 ”@{display_value=Tom John; link=https://contoso.service-now.com/api/now/table/sys_user/a7bc02d2db48b4184f08b29a689619ed” というような複数の行のデータがあります。

Username Assigned_to
Taro @{display_value=Taro Yamada; link=https://contoso.service-now.com/api/now/table/sys_user/a7bc02d2db48b4184f08b29a689619ed

Hanako @{display_value=Hanako Tanaka; link=https://contoso.service-now.com/api/now/table/sys_user/b7bc02d2db48b4184f08b29a68ahgb22

これで、最後の31文字部分だけを残して、 a7bc02d2db48b4184f08b29a689619ed その前の文字列を全て消して
違うCSVファイルに出力したいのですが、どのようにすればよいかご存じの方、ご教授頂けないでしょうか。色々試していますがうまくできません。

Set the path to CSV file

$csvFilePath = "./test1.csv"

Read the CSV file

$csvData = Import-Csv -Path $csvFilePath

Define a regular expression pattern to match the desired format

$pattern = '@{display_value=.*/(\w{31})}'

Loop through each row in the CSV data

foreach ($row in $csvData) {

Extract the last 31 digits using the regular expression pattern

if ($row.assigned_to -match $pattern) {

$lastThirtyOneDigits = $matches[1]

$row.assigned_to = $lastThirtyOne
}
}
$csvData | Export-Csv -Path ./test2.csv -NoTypeInformation

#------------------------------------------------------------------

Set the path to CSV file

$csvFilePath = "./test1.csv"

Read the CSV file

$csvData = Import-Csv -Path $csvFilePath

$pattern = '@{display_value=.*(\d{31})$'

Loop through each row in the CSV data

foreach ($row in $csvData) {

Extract the last 31 digits using the regular expression pattern

if ($row.URL -match $pattern) {

$lastThirtyOneDigits = $matches[31]

$row.URL = $lastThirtyOne
}
}

$csvData | Export-Csv -Path ./test2.csv -NoTypeInformation

どうぞ宜しくお願い致します

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

otn

2023/07/19 06:49

末尾31文字の取り出し方が分からないという質問でしょうか? あるいは、プログラムをゼロから書いて欲しいと言うことでしょうか?途中まで出来ているなら、それを書きましょう。
SUSU0703

2023/07/19 07:23

otnさん ご連絡ありがとうございます! 例えば以下のように先頭から決まった文字であれば以下のような方法で消えてくれるのは確認済みですが、 Import-Csv ./test01.csv | ForEach-Object { $_.Assigned_To = $_.Assigned_To -replace '@{display_value=', '' $_ } | Export-CSV ./test02.csv -NoTypeInformation すべてのAssigned_toコラム内のデータ桁数が違うのでそれは使えず、*とか使えるのかと思いましたがそれも駄目で。ただ、末尾の桁数は31桁と決まっているため、末尾から31桁より前の文字列を消したい、もしくは末尾31文字だけ取り出して別CSVファイルにしたいと思っています。 ググって色々試してはいるのですがまだできていない状態です。宜しくお願い致します。 # Set the path to CSV file $csvFilePath = "./test1.csv" # Read the CSV file $csvData = Import-Csv -Path $csvFilePath # Define a regular expression pattern to match the desired format $pattern = '@{display_value=.*\/(\w{31})}' # Loop through each row in the CSV data foreach ($row in $csvData) { # Extract the last 31 digits using the regular expression pattern if ($row.assigned_to -match $pattern) { $lastThirtyOneDigits = $matches[1] $row.assigned_to = $lastThirtyOne } } $csvData | Export-Csv -Path ./test2.csv -NoTypeInformation #------------------------------------------------------------------ # Set the path to CSV file $csvFilePath = "./test1.csv" # Read the CSV file $csvData = Import-Csv -Path $csvFilePath $pattern = '@{display_value=.*(\d{31})$' # Loop through each row in the CSV data foreach ($row in $csvData) { # Extract the last 31 digits using the regular expression pattern if ($row.URL -match $pattern) { $lastThirtyOneDigits = $matches[31] $row.URL = $lastThirtyOne } } $csvData | Export-Csv -Path ./test2.csv -NoTypeInformation
otn

2023/07/19 07:58

コードはコメントから削除して、質問文を編集して載せましょう。
guest

回答3

0

ベストアンサー

■CSVファイル内の特定の文字だけ残すサンプルプログラム

PowerShell

1$CSV = @(Import-Csv "./test01.csv" -Delimiter "," -Encoding UTF8 -Header @("A","B")) # Import-Csvで読み込む(カンマ区切りのファイル)+ヘッダを付ける 2$CSV = $CSV | ForEach-Object {$_.B -replace '@{display_value=.*\/(\w{31})','$1'} # 正規表現で特定の文字だけ残す 3$CSV = $CSV | Select-Object @{Name='Assigned_to';Expression={$_}} # オブジェクトに変更 4$stream = New-Object System.IO.StreamWriter("./test02.csv",$False,(New-Object System.Text.UTF8Encoding($False))) # UTF8-BOM無しで保存 5Write-Output $CSV | ConvertTo-Csv -NoTypeInformation | Select-Object -skip 2 | ForEach-Object { $stream.WriteLine($_) } # UTF8-BOM無しで保存+ヘッダを削除 6$stream.Close() # UTF8-BOM無しで保存

※ Import-Csvで読み込んでいます(カンマ区切りのファイル)
※ 正規表現で特定の文字だけ残しています。
※ オブジェクトに変更しています。
※ UTF8-BOM無しで保存しています(保存時にヘッダを削除しています)
※ 保存時にヘッダが必要な場合は -skip 2 → -skip 1 に変更してください。

私の環境ではテストが出来ないので、
動作するか分かりません。ご了承ください。

投稿2023/07/19 11:50

ccc-

総合スコア356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SUSU0703

2023/07/19 13:15

CCC- さん ありがとうございます。無事できました!! これは自力では無理ですね。。大変助かりました。ありがとうございます!!
Zuishin

2023/07/19 22:30

> $stream = New-Object System.IO.StreamWriter("./test02.csv",$False,(New-Object System.Text.UTF8Encoding($False))) # UTF8-BOM無しで保存 > Write-Output $CSV | ConvertTo-Csv -NoTypeInformation | Select-Object -skip 2 | ForEach-Object { $stream.WriteLine($_) } # UTF8-BOM無しで保存+ヘッダを削除 > $stream.Close() # UTF8-BOM無しで保存 この部分ですが、以下のようにするのが PowerShell 流です。 $CSV | Select-Object -Skip 2 | Export-Csv -NoTypeInformation -LiteralPath ./test02.csv -Encoding utf8NoBOM
guest

0

powershell

1$data = "data.txt" 2$output = "output.txt" 3Get-Content $data | Select-Object -Skip 1 | 4ForEach-Object { $_.split("/")[-1] } | Out-File -Encoding utf8 $output

output.txt

text

1a7bc02d2db48b4184f08b29a689619ed 2b7bc02d2db48b4184f08b29a68ahgb22

投稿2023/07/19 07:54

編集2023/07/19 11:58
melian

総合スコア21118

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

SUSU0703

2023/07/19 09:15

melianさん ありがとうございます!! csvファイルの場合、どのように変更すればよいかご存じでしょうか。自分なりに色々試していますがまだ解決できず。。 宜しくお願い致します
melian

2023/07/19 09:23

CSV ファイルでも結果は同じになるはずです。(CSV かどうかは無関係ということです) 入力の CSV ファイル名を変更して貰えばよいかと思います。 $data = "実際のCSVファイルのパス名" 処理内容は、ヘッダ行(Username,Assigned_to)をスキップして、2行目以降から行の末尾32文字($_[-32..-1])を抽出して output.txt へ出力しています。
melian

2023/07/19 11:59

少し書き換えてみました。($_.split("/")[-1])
SUSU0703

2023/07/19 13:24

melianさん ありがとうございます。自分のcsvに変えて試してみました。もともとのdata.csvのヘッダーは LoginUserと、assigned_toの二つで、A列のLoginUserには社員番号、B列のassigned_toには例の https://contoso.service-now.com/api/now/table/sys_user/a7bc02d2db48b4184f08b29a689619ed のような文字の羅列がそれぞれ入っています。 $data = "data.csv" $output = "output.csv" Get-Content $data | Select-Object -Skip 1 | ForEach-Object { $_.split("/")[-1] } | Out-File -Encoding utf8 $output 実行後、output.csvを開くと、ヘッダーが二つとも消えて、A列に社員番号と文字の羅列が(これはちゃんと末尾から31桁になっていました)合体して表示されている状態でした。ご報告まで。ありがとうございます。
melian

2023/07/19 13:26

もしかして、Username カラムの内容はそのままで、Assigned_to カラムの末尾の32文字を残すということだったのでしょうか。すっかり勘違いをしていました。
guest

0

ChatGPTさんに聞いてきました。

powershell

1# 入力ファイルのパスを指定 2$filePath = "C:\work\hoge.txt" 3# 出力ファイルのパスを指定 4$outputFilePath = "C:\work\hoge_out.txt" 5 6# 入力ファイルの内容を読み込み、各行の末尾の31文字を取得して新しい文字列として保存 7$output = Get-Content $filePath | ForEach-Object { $_.Substring($_.Length - 31) } 8 9# 出力ファイルに保存 10$output | Out-File -Encoding utf8 $outputFilePath 11

投稿2023/07/19 07:26

poto568

総合スコア358

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.31%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問