プロが教える店舗&オフィスのセキュリティ対策術

前提・実現したいこと
①CSVファイルの先頭列にファイル名が入力された列を追加したい
②①と同様のCSVファイルを最初のファイル以外の先頭行(項目ラベル)を削除して結合したい

発生している問題・エラーメッセージ
現在コマンドプロンプトにて同型のCSVファイルの結合について苦戦しています。
下記のような売上明細のデータを分析したいのですが、何も考えずに一括で結合すると2ファイル名以降の項目ラベル(カテゴリ、担当、購入者)が分析の邪魔になり、かつどの商品のデータなのかがわからなくなってしまいます。

<ファイル>
ドライヤー_4月売上
テレビ_4月売上
ウォーターサーバー_4月売上
・・・
・・・
・・・
・・・

<ファイルの中身>
カテゴリ 担当者 購入者 購入日
家電   佐藤  田中  4/6    ←ファイル名がないので何の商品の売上なのかわからない
家電   佐藤  高橋  4/8
・    ・   ・   ・
・    ・   ・   ・
・    ・   ・   ・
カテゴリ 担当者 購入者 購入日 ←結合すると2ファイル目以降のラベルが分析の邪魔に。
キッチン 宮下  栗原  4/2
キッチン 宮下  桃井  4/11

<理想の状態>
ファイル名 カテゴリ 担当者 購入者 購入日
ドライヤー 家電   佐藤  田中  4/6    
ドライヤー 家電   佐藤  高橋  4/8
・    ・   ・   ・
・    ・   ・   ・
ドライヤー 家電   佐藤  高橋  4/8
ミキサー  キッチン 宮下  栗原  4/2   ←2ファイル目以降の項目ラベルを削除 
ミキサー  キッチン 宮下  桃井  4/11

ファイル名が全レコードに挿入

試したこと
別々の処理だったら可能なのですが、同時に処理を行うことができずに困っています。

<2ファイル目以降のヘッダー削除>

@echo off
setlocal enabledelayedexpansion

set /a counter=0

for /f %%i in ('dir /b *.csv') do (

echo %%i
if !counter!==0 (
set /p _head=<%%i
echo !_head!>>result.csv
)
set /a counter=!counter!+1

for /f "tokens=* skip=1" %%b in (%%i) do (
echo %%b>>result.csv
)
)
pause

<先頭列に結合前データ名を挿入>
@echo off

for %%F in (*.csv) do (

for /f "delims=" %%L in (%%F) do (

echo %%F,%%L

)

)

補足情報(FW/ツールのバージョンなど)
win10を使用しています。
なにかあと少しでできそうな予感はあるのですが最後の一歩がうまくいかず大変悔しい思いをしています。どうかご協力をお願い致します。

A 回答 (3件)

コマンドプロンプトでやるよりも Excelのマクロのほうが簡単だと思います。



ところで項目に 購入日 とありますが 売上日 ではないのですね
    • good
    • 0

全てをバッチファイルに行わせると分からないので、処理を行うPowerShellスクリプトをバッチファイルで呼び出す形式にしてみました。


一案としてどうぞ。

以下のtest.bat, test.ps1を作成し、CSVファイル群と同じフォルダに置いて、test.batを実行します。

----- test.bat
powershell -executionpolicy bypass .\test.ps1
----- ここまで

----- test.ps1
$output = "result.csv"

#既存の$outfile削除
$output = Join-Path -Path $(Get-Location) -ChildPath $output
if(Test-Path -Path $output -ne $null) { Remove-Item -Path $output }

$first_file = $true
Get-ChildItem *.csv | %{
#個々のCSVファイルについて処理
$first_line = $true
$file_name = $_.BaseName
Get-Content -LiteralPath $_ | %{
#各行について処理
if($first_file -and $first_line){
#最初のファイルの1行目
$first_file = $false
$first_line = $false
"ファイル名," + $_ | Out-File -FilePath $output -Encoding default
}elseif($first_line){
#2番目以降のファイルの1行目
$first_line = $false
}else{
#2行目以降
$file_name + "," + $_ | Out-File -FilePath $output -Encoding default -Append
}
}
}
----- ここまで
    • good
    • 0

上の奴で, 中の for を下の奴に合わせて


for /f "delims= skip=1" %%L in (%%i) do (
echo %%F,%%L
)
のようにしてもだめなんだっけ?

ちなみに上の奴は「counter」ってあるけど, 実際にファイル数を数える必要ないと思うよ.
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!