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

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

新規登録して質問してみよう
ただいま回答率
85.48%
コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

Q&A

解決済

2回答

319閲覧

テキストファイルの自動編集

byct

総合スコア1

コマンドプロンプト

コマンドプロンプト(cmd.exe)はMicrosoftによって提供されているコマンドラインインタプリタです。OS/2・Windows CE・Windows NTで使用可能です。

0グッド

0クリップ

投稿2024/01/15 04:02

編集2024/01/17 03:05

実現したいこと

テキストを自動で編集出来るようにしたいです。
ファイル内の各行に特定の文字列が含まれている場合は何もしないまたは特定の処理を行って別のファイルに書き込む、特定の文字列が含まれていない場合はそのまま別のファイルに書き込む、という機能のバッチファイルが作成したいものです。

具体的には、

行の中に特定の文字列が含まれる場合、以下の処理を0個以上実行する。何を実行するかは含まれる文字列によって決定する。
・特定の文字列を削除する。
・特定の文字列を別の文字列に置換する。
・先頭または末尾から決められた数の文字を削除する。
・先頭または末尾に文字列を追加する。
・行の内容を別のファイルに書き込む。
・その行の後に空行または文字が入力された行を1行以上追加する。
特定の文字列が含まれない場合は、元の行の内容をそのまま別のファイルに書き込む。

といった感じです。

発生している問題・分からないこと

テキストファイルの各行の内容が条件を満たしているかどうか判定する方法が分かりません。
findで特定の文字列を探させてerrorlevelで判定する方法を試してみたのですが、うまく動作しませんでした。

また、これは必須ではないのですが、
現在はforループで1行ずつ処理させており、元のテキストの行数が多いので実行に時間がかかっています。
編集が必要な行は多くても50行程度なので、全行を読み込むのは無駄な気がしています。もっと効率的な方法があればそれも回答して頂けると助かります。

下記のコードは「xcv」を含む行の先頭2文字を削除するというだけのものです。
これは例であり、実際に使用するものではありません。

該当のソースコード

@echo off setlocal enabledelayedexpansion set write=0 for /f "delims=" %%a in (z.txt) do ( set line=%%a find "xcv" %%a >nul 2>&1 if %errorlevel%==0 ( set line=%line:~2% ) if %write%==0 ( echo %line%> b.txt set write=1 ) else ( echo %line%>> b.txt ) ) endlocal

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

詳細はこちらです。
https://teratail.com/questions/fog9eznsow5fb5

追記
「バッチ bat 文字列 判定」等の単語で検索して出てきた情報を色々試してはみたものの駄目でした。
errorlevelを使用しているのはその影響です。

補足

特になし

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

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

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

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

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

melian

2024/01/15 04:44

> 下記のコードは「xcv」を含む行の先頭2文字を削除するというだけのものです。 Windows バッチによる処理が必須条件でなければ、sed コマンドを使うとよいかと思います。(Windows 版の sed コマンドを別途インストールする必要がありますが) sed '/xcv/s/^..//' z.txt > b.txt
guest

回答2

0

ベストアンサー

まず、setlocal enabledelayedexpansionを書いているにも関わらず、その意味を全く理解してないようです。
set /?で表示される説明の、98~147行目を読んで、サンプルコードも実行してみると
setlocal enabledelayedexpansionの意味が分かるかと思います。

・特定の文字列を削除する。
・特定の文字列を別の文字列に置換する。
・先頭または末尾から決められた数の文字を削除する。

は、全部バッチスクリプトの組み込み機能で出来ます。

やり方はset /?に書いてあります。文字位置指定の切り出しはご存じのようですが、置換は%変数名:置換対象=置換後%などです。%HOMEPATH:\=/%など。
「削除」は「空文字列への置換」で実現します(これはバッチスクリプトに限らない話)。
ただし、置換元の英大文字と小文字は区別できないので、例えば「Aは削除したいが、aは削除しない」はバッチスクリプトの組み込み機能では実現できません。この区別が必要なら、何らかのテキスト処理用コマンドを起動してそれに任せる必要があります。まあ、そういう場合は最初から全部PowerShellで書くのでしょうか。

・先頭または末尾に文字列を追加する。
・行の内容を別のファイルに書き込む。
・その行の後に空行または文字が入力された行を1行以上追加する。

このあたりは、そのように書けば良いだけなので、大丈夫ですよね?

xcvを含む行の先頭2文字を削除する」のサンプル。

CMD

1@echo off 2setlocal enabledelayedexpansion 3( 4 for /f "delims=" %%a in (z.txt) do ( 5 set line=%%a 6 if not "!line:xcv=!"=="!line!" ( 7 rem xcv が存在した 8 set line=!line:~2! 9 ) 10 echo !line! 11 ) 12) > b.txt

xcvが含まれる」と「xcvを削除すると元の文字列と等しくない」は等価という事実を利用しています。
findfindstrは外部コマンドなので、行ごとに起動するとすごく遅い。

制約としては、少なくとも下記4つ。もっとあるかもしれません。
・置換元文字列は大文字小文字区別しない
・文字列置換は置換元が複数あれば全部対象(最初の1つだけとかは不可)
・ファイルの空行は読み取られずスキップされる
aaa!temp!bbbのような!を複数含んだ行があると、!temp!が環境変数展開される。定義済みの環境変数ならその値の文字列、未定義の環境変数なら空文字列になる。(単独の!は単に削除される)

これが駄目なら、上述のようにPowershellかなにかで。VBAでもいいですが。

投稿2024/01/15 12:16

otn

総合スコア84571

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

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

byct

2024/01/17 03:08

回答ありがとうございます。 解決しました。
guest

0

もっと効率的な方法があればそれも回答して頂けると助かります。

下記のコードは「xcv」を含む行の先頭2文字を削除するというだけのものです。
これは例であり、実際に使用するものではありません。

参考までに、PowerShell で処理する場合は以下の様になります。

powershell

1gc 'z.txt' | %{ $_ -replace '^(?=.*xcv)..', '' } > 'b.txt'

投稿2024/01/15 05:31

melian

総合スコア19825

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問