@bill_g (ka g)

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

CSVのファイル名先頭3文字を、CSVの各行の先頭に格納したい。

解決したいこと

Windows11のDOS窓で作業します。大量のcsvファイルの1行1行の先頭に、ファイル名の先頭3文字を入れたいです。

例)
数十個のcsvファイルがあります。ファイル名は
025〇〇区東支店.csv
204××区南支店.csv
259△△区南川支店.csv など

1つのcsvの中身の各行の先頭にファイル名の先頭3桁を入れたいです。
025〇〇区東支店.csvの中身

【実行前】
商品AAA,単価,個数,販売先
商品BBB,単価,個数,販売先
商品CCC,単価,個数,販売先

【実行後】
025,商品AAA,単価,個数,販売先
025,商品BBB,単価,個数,販売先
025,商品CCC,単価,個数,販売先


手順としまして
1 ファイル名を取得
2 ファイル名の先頭3文字を取得
3 ファイルの中身の先頭に3文字を張り付け
4 ファイルの最後の行まで行う
5 次のファイルを読む

バッチで実行する方法を教えて下さい。

別のコミュニティサイトを参考にしました、元のソースです。
6行でファイル名を各行の先頭に貼り付けていました。短さに驚きました。
作者様の思考力に脱帽です。これを元に自分も頑張ってみようと
奮闘しましたが…

参考ソース

cd /d "対象ディレクトリ"
for %%A in (*.csv) do (
  findstr "^" %%A NUL > tempfile
  move %%A %%A.bak
  move tempfile %%A
)

この状態ではファイル名全部が、各行の先頭に付加されます。
以下のようにset stringで先頭から3文字を取得…
にしてみましたが結果は0バイトのファイルができるだけでした。

自分で試したこと

cd /d "対象ディレクトリ"
for %%A in (*.csv) do (
  %%A:~0,3%
  set string=%%A:~0,3%
  findstr "^" string > tempfile
  move %%A %%A.bak
  move tempfile %%A
)

ファイル名の先頭3文字を取得できません。
また、先頭3文字を各行に入れる手順はどのようにすればよいでしょうか。

0 likes

2Answer

6行でファイル名を各行の先頭に貼り付けていました。短さに驚きました。

結果的に、そういう操作をしているように見えますが、実態は全然違います。
findstrコマンドの結果をリダイレクトしてファイル出力しているだけです。

findstrは、引数で指定したファイルから特定の文字を検索するコマンドです。
次のコマンドを手打ちしてみてください。findstr "^" 025〇〇区東支店.csv NUL

検索する文字列は正規表現の^で、これは、「文頭」を意味するので、すべての行が一致します。結果的に、各行の先頭にファイル名を付加した出力になった訳けです。

そういうわけで、これ(findstrコマンド)を使って「ファイルの3文字」にすることはできません。
以下でどうでしょうか?

@echo off
setlocal EnableDelayedExpansion

cd /d "対象ディレクトリ"

for %%A in (*.csv) do (
	set "filename=%%A"
	set p3=!filename:~0,3!
	(for /f %%B in (%%A) do (
		echo !p3!,%%B
	)) > tempfile
	move %%A %%A.bak
	move tempfile %%A
)

なお、1行づつ処理しますから、それなりの時間を要します。

1Like

Comments

  1. @bill_g

    Questioner

    ご回答ありがとうございます。DOSコマンド勉強不足が多く参考にさせていただきます。
    ファイル名先頭から3文字を格納、1行の先頭に付ける、難しいですね。

元のファイル名を、一旦変数に格納してから加工したらどうでしょう。

@echo off
rem ↓CSVの文字コードがutf-8ならchcpが必要、不要なら削除
chcp 65001 > nul

setlocal enabledelayedexpansion
for %%A in (*.csv) do (
    move %%A %%A.bak
    set in_file=%%A
    set add_data=!in_file:~0,3!
    (for /f "delims=" %%B in (%%A.bak) do (
        echo !add_data!,%%B
    )) > %%A
)
endlocal
1Like

Comments

  1. @bill_g

    Questioner

    ご回答ありがとうございます。1~2行のバッチファイルは使用していました。
    utf-8のお気遣いいただきありがとうございます。
    endlocalの位置が上?かも。参考にさせていただきます。

Your answer might help someone💌