Just another IT site ※IT系の記事は当方環境での実施内容となるため実施する場合は自己責任でお願いいたします。At Your Own Risk!! TURN BACK WHILE YOU CAN
PR

【作成中】【AIに依頼】縦リストデータを横にカンマ区切りで展開する

※IT系の記事は当方環境での実施内容となるため実施する場合は自己責任でお願いいたします。スクリプトはAI生成のものも多いのでコピー&ペーストの際は文字コードに注意ください!

Geminiに考えてもらったがうまく動かない・・・
日本語コメントを残していると、エラーになり、また、)のすぐ上にラベルがあると「)の使い方が間違っています」と言われるため、とりあえずREMをかましてみると、とりあえず実行はできるのだが何も出力されず。

Claudeにも聞いてみるか・・・

縦に並んだデータをカンマ区切りで横に変換し、特定の条件で改行を挿入するWindowsバッチファイルを作成しますね。

縦長のデータを横に変換するバッチファイル
このバッチファイルは、指定された入力ファイルからデータを読み込み、各行をカンマで区切りながら横に連結します。以下の条件に合致する行は完全に無視し、特定の条件で改行を挿入します。

END という文字列が見つかった場合、それまでのデータを出力し、END の行自体は出力せずに改行のみを挿入します。

空白行 は処理せず無視します。

# で始まる行は処理せず無視します。

a=b のように = が含まれる行の場合、左辺 (a=) は出力せず、右辺のデータ (b) のみを出力します。もし = が含まれない行であれば、不正な形式とみなし無視します。

使用方法
上記のコードをメモ帳などに貼り付け、「convert_data.bat」などの名前で保存します。

convert_data.bat と同じフォルダーに、変換したいデータが入ったテキストファイルを作成します。

このテキストファイルの名前は、バッチファイル内の set "inputFile=input.txt" の部分で指定されている名前(デフォルトでは input.txt)と同じにしてください。

例: input.txt の内容

key1=データA
key2=データB
#コメント行
key3=データC

key4=データD
END
key5=データE
key6=データF
key7=
バッチファイル内の以下の設定をご自身の環境に合わせて変更してください。

set "inputFile=input.txt":入力ファイル名

set "outputFile=output.txt":出力ファイル名

convert_data.bat をダブルクリックして実行します。

実行結果の例
上記の input.txt を使用した場合、output.txt は以下のようになります。

データA,データB,データC
データD
データE,データF,
このバッチファイルは、データの整形、不要な行のスキップ、そして指定された形式でのデータ抽出を効率的に行います。ぜひご活用ください。


@echo off
setlocal enabledelayedexpansion

:: ★★★ 設定 ★★★
:: 入力ファイル名を指定してください (例: input.txt)
set "inputFile=input.txt"

:: 出力ファイル名を指定してください (例: output.txt)
set "outputFile=output.txt"
:: ★★★ 設定ここまで ★★★

set "outputLine="
:: 出力ファイルを削除 (存在しない場合はエラーを抑制)
del /q "%outputFile%" 2>nul

:: 入力ファイルを1行ずつ処理
for /f "usebackq tokens=*" %%a in ("%inputFile%") do (
    set "currentLine=%%a"
    
    :: 空白行、または # で始まる行は完全に無視する
    if "!currentLine!"=="" (
        goto :next_line_skip
    )
    if "!currentLine:~0,1!"=="#" (
        goto :next_line_skip
    )

    :: END が見つかった場合、それまでの蓄積された行を出力し、
    :: outputLineをリセットして次の行へ進む(END自体は出力しない)
    if /i "!currentLine!"=="END" (
        :: outputLineが空の場合でも改行を出力するため、そのままecho
        echo !outputLine!>>"%outputFile%"
        set "outputLine="
        goto :next_line_skip
    )

    :: "=" が含まれていない行は不正な形式とみなし、スキップする
    :: (例: "justavalue" のような行は処理しない)
    echo !currentLine! | findstr "=" >nul
    if errorlevel 1 (
        goto :next_line_skip
    )

    :: 左辺の "a=" を除いて右辺のデータのみを抽出する
    :: "=" より右側の全ての文字列を取得します。
    :: (例: "key=value with spaces" -> "value with spaces")
    :: (例: "key=" -> "")
    set "extractedValue=!currentLine:*==!"
    
    :: 通常のデータ行の場合、カンマ区切りで連結する
    if defined outputLine (
        :: outputLineに既にデータがある場合はカンマを追加してから連結
        set "outputLine=!outputLine!,!extractedValue!"
    ) else (
        :: outputLineが空の場合はそのまま現在の行をセット
        set "outputLine=!extractedValue!"
    )
    :next_line_skip
)

:: 全ての行を処理した後、outputLineにデータが残っていれば最後に出力する
if defined outputLine (
    echo !outputLine!>>"%outputFile%"
)

echo.
echo 処理が完了しました。
echo 結果は "%outputFile%" に出力されました。

endlocal
pause


はい、承知いたしました。Windowsバッチファイルと同じ機能を持つBashシェルスクリプトを作成しますね。

このスクリプトは、指定された入力ファイルからデータを読み込み、カンマ区切りで横に連結します。以下の条件に合致する行は完全に無視し、特定の条件で改行を挿入します。

END という文字列が見つかった場合、その行のデータは出力せず改行のみ挿入します。

空白行 は処理せず無視します。

# で始まる行は処理せず無視します。

a=b のように = が含まれる行の場合、左辺 (a=) は出力せず、右辺のデータ (b) のみを出力します。もし = が含まれない行であれば、不正な形式とみなし無視します。

データ変換Bashシェルスクリプト
6月29日 18:31
使用方法
上記のコードをメモ帳やテキストエディタに貼り付け、「convert_data.sh」などの名前で保存します。

保存したファイルに実行権限を付与します。ターミナル(コマンドライン)で以下のコマンドを実行します。

Bash

chmod +x convert_data.sh
convert_data.sh と同じフォルダーに、変換したいデータが入ったテキストファイルを作成します。

このテキストファイルの名前は、スクリプト内の inputFile="input.txt" の部分で指定されている名前(デフォルトでは input.txt)と同じにしてください。

例: input.txt の内容

key1=データA
key2=データB
#コメント行
key3=データC

key4=データD
END
key5=データE
key6=データF
key7=
justavalue
スクリプト内の以下の設定をご自身の環境に合わせて変更してください。

inputFile="input.txt":入力ファイル名

outputFile="output.txt":出力ファイル名

ターミナルで以下のコマンドを実行します。

Bash

./convert_data.sh
実行結果の例
上記の input.txt を使用した場合、output.txt は以下のようになります。

データA,データB,データC
データD
データE,データF,
このBashスクリプトは awk コマンドを使用して、非常に効率的にデータを処理します。ぜひご活用ください。




#!/bin/bash

# ★★★ 設定 ★★★
# 入力ファイル名を指定してください (例: input.txt)
inputFile="input.txt"

# 出力ファイル名を指定してください (例: output.txt)
outputFile="output.txt"
# ★★★ 設定ここまで ★★★

# 出力ファイルを削除 (存在しない場合はエラーを抑制)
> "$outputFile"

# awkを使ってデータを処理
awk -v OFS="," -v RS="\n" '
BEGIN {
    # output_line変数を初期化
    output_line = ""
}

# 空白行、または # で始まる行は完全に無視する
/^$/ { next }
/^#/ { next }

# END が見つかった場合、それまでの蓄積された行を出力し、
# output_lineをリセットして次の行へ進む(END自体は出力しない)
tolower($0) == "end" {
    print output_line >> "'"$outputFile"'"
    output_line = ""
    next
}

# "=" が含まれていない行は不正な形式とみなし、スキップする
# (例: "justavalue" のような行は処理しない)
index($0, "=") == 0 { next }

{
    # 左辺の "key=" を除いて右辺のデータのみを抽出する
    # "=" より右側の全ての文字列を取得します。
    # (例: "key=value with spaces" -> "value with spaces")
    # (例: "key=" -> "")
    split($0, arr, "=");
    extracted_value = "";
    # arr[1]はイコールの左側、arr[2]以降が右側。
    # イコールが複数あっても最初のイコールで分割し、以降全てを値とする。
    if (length(arr) > 1) {
        extracted_value = substr($0, index($0, "=") + 1);
    }
    
    # 通常のデータ行の場合、カンマ区切りで連結する
    if (output_line != "") {
        # output_lineに既にデータがある場合はカンマを追加してから連結
        output_line = output_line OFS extracted_value
    } else {
        # output_lineが空の場合はそのまま現在の行をセット
        output_line = extracted_value
    }
}

END {
    # 全ての行を処理した後、output_lineにデータが残っていれば最後に出力する
    if (output_line != "") {
        print output_line >> "'"$outputFile"'"
    }
}
' "$inputFile"

echo ""
echo "処理が完了しました。"
echo "結果は \"$outputFile\" に出力されました。"
@echo on
setlocal enabledelayedexpansion

set "inputFile=input.txt"

set "outputFile=output.txt"

set "outputLine="
del /q "%outputFile%" 2>nul

for /f "usebackq tokens=*" %%a in ("%inputFile%") do (
    set "currentLine=%%a"
    
    if "!currentLine!"=="" (
        goto :next_line_skip
REM
    )
    if "!currentLine:~0,1!"=="#" (
        goto :next_line_skip
REM
    )

    if /i "!currentLine!"=="END" (
        echo !outputLine!>>"%outputFile%"
        set "outputLine="
        goto :next_line_skip
REM
    )

    echo !currentLine! | findstr "=" >nul
    if errorlevel 1 (

        goto :next_line_skip
REM
    )

    set "extractedValue=!currentLine:*==!"
    
    if defined outputLine (
        set "outputLine=!outputLine!,!extractedValue!"
    ) else (
        set "outputLine=!extractedValue!"
    )
    :next_line_skip
REM
)

if defined outputLine (
    echo !outputLine!>>"%outputFile%"
)

echo.
echo Processing completed.
echo The results were output to "%outputFile%".

endlocal
pause

サンプルデータ

#
# ID=MYSELF01
#

SNDFILE=MYSELF01
FILENAME=C:\Users\Administrator\Documents\myself01_send.txt
DBID=
TRANSTYPE=T
TRANSPRTY=50
INTERVAL=0
BLOCKLEN=0
BLOCKCNT=0
COMP=N
JOBID=
COMMENT=
GRPID=localhost
FMTID=
EJOBID=
KJCHNGE=S
CLEAR=K
PASSWORD=
CODESET=0
COMPSIZE=0
PREJOBID=
SHIFTTRANSACT=Y
COMPMODE=
MAILID=
END

#
# ID=MYSELF02
#

SNDFILE=MYSELF02
FILENAME=C:\Users\Administrator\Documents\myself02_send.txt
DBID=
TRANSTYPE=T
TRANSPRTY=50
INTERVAL=0
BLOCKLEN=0
BLOCKCNT=0
COMP=N
JOBID=
COMMENT=
GRPID=localhost
FMTID=
EJOBID=
KJCHNGE=S
CLEAR=K
PASSWORD=
CODESET=0
COMPSIZE=0
PREJOBID=
SHIFTTRANSACT=Y
COMPMODE=
MAILID=
END

 

タイトルとURLをコピーしました