バッチファイルで順番問わず文字列をマッチさせる方法

このQ&Aのポイント
  • バッチファイルで順番を問わずに複数の文字列をマッチさせる方法を知りたいです。
  • sedコマンドを使用して順序を無視して複数の文字列をマッチさせる方法をご教示ください。
  • 文字列の順番を問わずに指定した複数の文字列が含まれる行を置換する方法について教えてください。
回答を見る
  • ベストアンサー

バッチファイルで文字列を順番問わずマッチさせたい

バッチファイルで、2個以上の文字列を順番問わずマッチさせたいと考えています。 例えば、 「111 222 333 444 555 666 777」 という内容のテキストファイルがあったとして、 sedコマンドを使って 「222」と「444」と「666」が この順番で含まれている行を置換したい場合、 sed -e "s/.*222.*444.*666.*/置換後の文字列/" in.txt > out.txt とすれば、問題なく置換されると思います。 しかし、上記の例では、 「777 666 555 444 333 222 111」 という内容のテキストファイルは置換されません。 文字列の順番を問わず、 「222」と「444」と「666」が含まれている行ならば、 その行を置換する、といった事は出来ないでしょうか。 sedコマンド以外でも構いませんので、何かいい方法をご存知の方がおられましたらお教え頂けないでしょうか。

  • kon77
  • お礼率97% (92/94)

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4847/10260)
回答No.1

awk '/222/&&/444/&&/666/{print "MATCHED";next}{print}' 正規表現で 222 444 666 が出てくる順番の6通りを網羅すればいいので、sedだけでも出来ます。

kon77
質問者

お礼

色々なWEBページを参考にして、試行錯誤していたのですが、無事に目的の動作が出来ました。 ありがとうございました。 最初の補足を投稿させて頂く前に、検索エンジンで色々調べてやっていたのですが、結果として、その時にやっていたコマンドの基本的な構文は間違っていませんでした。 しかし、こちらの環境がWindows環境な為、「'」「"」の扱いが他のOSとは違っていて、その為にエラーになっていた様です。 お教え頂いたコマンドを、以下の様に書き換えさせて頂いて、実行してみると、うまく動作してくれました。 awk "/222/&&/444/&&/666/{print \"MATCHED\";next}{print}" in.txt > out.txt お教え頂いたこの方法が、一番良いと思うので、この方法でやっていこうと思います。 大変助かりました。本当にありがとうございました。

kon77
質問者

補足

ご回答ありがとうございます。 自分はプログラミング等の難しい事は解らず、簡単なコマンドを連続させて使う程度なのですが、正直、お教え頂いたawkも使い方がよく分からず、うまく動作させる事が出来ません。sedでも実現出来るとの事で、そちらの方向で行きたいと思います。 sedでも、 「222.*444.*666」「222.*666.*444」 「444.*222.*666」「444.*666.*222」 「666.*222.*444」「666.*444.*222」 と、書けばいいのかも知れませんが、 今回、このバッチファイルを使用したい理由が、商品のタイトルが数千書かれているリストから、「●●」「■■」「▲▲」という単語を含む行は削除する、といった用途でして、商品タイトル以外の情報も記載されている為、ファイルの容量が大きいのです。 つまり、sedを6回実行していると、それだけ時間も要すると思いますので、出来ればそれはしたくなかったのです。 それに、検索するキーワードも、どんどん追加していかないといけない為、その度にキーワードの並びを変えて、6個のパターンを作り、キーワードのリストに書き込んでいくという作業も、大変手間な訳です。 ですので、「●● ■■ ▲▲」と、キーワードのリストに一行書き込むだけでいいようにしたかったのです。 キーワードのリストは、後でまとめて、sedコマンドに当てはまるように置換して、バッチファイルとして実行しています。それは既に実現出来ています。 ですので、今考えている事としましては、「●● ■■ ▲▲」というキーワードが書かれていれば、そこから自動で6つのパターンを生成して、それをsedコマンドに当てはめて、実行するという処理を書こうかと考えています。 処理速度の問題も、なんとか考えて解決したいと思います。 ご回答、本当にありがとうございました。

その他の回答 (2)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

sedの命令は アドレス(範囲) コマンド (必要なら)引数 となっています。 指定したアドレスだけに、コマンドを実行する、というものです。 s/AAA/BBB/ というのは アドレス: 省略されている=全行が対象 コマンド: s 引数: /AAA/BBB/ ということです。 アドレスでは、行番号を指定したりできますが、「正規表現に一致した行」を対象とする、というものがあります。 命令同士は ; や改行で区切って複数記述できます。 また、{ コマンドという 、複数のコマンドをまとめるコマンドと、}コマンドという、{の終了を表わすコマンドがあります。 これらを組み合わせると /条件1/{/条件2/{s/.*条件3.*/置換後/;};} という方法があります。 これは アドレス: /条件1/ → 条件1 という正規表現にマッチする行が対象 コマンド: { → 対応する } までを一つのコマンドとして扱う 引数: /条件2/{s/.*条件3.*/置換後/;} → これをコマンドとして実行する ; で上記コマンドの区切り } コマンドで、上記 { の終了 となります。 この方法での欠点は、条件によっては意図した動作にならないことです。 条件1: 12 条件2: 23 条件3: 34 の様に重複した文字があると 1234 → 12.*23.*34 等では対象外 → /12/,/23/,/34/と分けると、すべてマッチするので対象 となってしまいます。 そこまで対応しようとしたら、sedではちょっと難しいかな、と思います。 awk,perl等が便利でしょう。

kon77
質問者

お礼

ご回答ありがとうございます。 大変丁寧に解説して頂きありがとうございます。 まだ今の自分では、ご説明頂いた全てを理解する事は出来ませんが、何度も読み返して理解して行こうと思います。 ご回答頂いた通りにテストしてみました。 うまく動作してくれました。 ありがとうございました。 ただ、逆に「条件によっては意図した動作にならない」というケースが、まだ今の自分では理解出来ていませんので、今度、時間を掛けて理解して行こうと思います。 何より、sedに対する知識が少し増えた事が嬉しいです。 違うケースでも活用して行こうと思います。 awkやperl等も今後は勉強して行こうと思います。 ご回答、本当にありがとうございました。

  • notnot
  • ベストアンサー率47% (4847/10260)
回答No.2

No1です。 sedが使えるのに、あの程度の簡単なawkが使えないというのがよくわかりませんが、sedでやるなら、 #!/bin/sh K1=222 K2=444 K3=666 X=置換後の文字列 sed -e "s/.*$K1.*$K2.*$K3.*/$X/" -e "s/.*$K1.*$K3.*$K2.*/$X/" -e "s/.*$K2.*$K3.*$K1.*/$X/" -e "s/.*$K2.*$K1.*$K3.*/$X/" -e "s/.*$K3.*$K1.*$K2.*/$X/" -e "s/.*$K3.*$K2.*$K1.*/$X/" in.txt >out.txt

kon77
質問者

お礼

再度、ご回答頂きありがとうございます。 awkはsedより簡単なのですね。awkも勉強して行こうと思います。 あと、当方の環境を書き忘れておりまして、こちらはWindows環境です。書き忘れていてすみませんでした。 ですので、お教え頂いたコマンドをWindows用に書き換えさせて頂いて、 set K1=222 set K2=444 set K3=666 set X=置換後の文字列 sed -e "s/.*%K1%.*%K2%.*%K3%.*/%X%/" -e "s/.*%K1%.*%K3%.*%K2%.*/%X%/" -e "s/.*%K2%.*%K3%.*%K1%.*/%X%/" -e "s/.*%K2%.*%K1%.*%K3%.*/%X%/" -e "s/.*%K3%.*%K1%.*%K2%.*/%X%/" -e "s/.*%K3%.*%K2%.*%K1%.*/%X%/" in.txt > out.txt とやってみましたら、無事に成功しました。 ありがとうございました。 勉強不足でお恥ずかしいです。 もっとコマンドを勉強して行こうと思います。 お手数をお掛け致しました。 ご回答、本当にありがとうございました。

関連するQ&A

  • バッチファイルでテキストファイルを分割したい

    テキストファイルを、指定した数値の倍数の行を、指定した個数に分割するバッチファイルを作成しようとしています。 例えば、以下の様な内容の「in.txt」というテキストファイルを3分割したい場合、 ----- in.txtの内容 ----- 1 2 3 4 5 6 7 8 9 10 ------------------------ 以下の様な内容で、 「out1.txt」「out2.txt」「out3.txt」として出力したいのです。 ----- out1.txtの内容 ----- 1 4 7 10 -------------------------- ----- out2.txtの内容 ----- 2 5 8 -------------------------- ----- out3.txtの内容 ----- 3 6 9 -------------------------- 自分はプログラミングの知識がないので、WEBに書かれている構文を少し書き換えたりして試しているのですが、うまく行きません。 AWKを使い、以下のようなバッチファイルを作成して実行してみましたが、「out3.txt」だけがうまく行きませんでした。構文の意味も分からないので修正も出来ません。 awk "NR%%3==1" "in.txt" > "out1.txt" awk "NR%%3==2" "in.txt" > "out2.txt" awk "NR%%3==3" "in.txt" > "out3.txt" AWKの解説ページを読み始めたのですが、時間的な猶予があまり無く、今回質問させて頂いた処理が出来るようになるまでまだ時間が掛かりそうなので、どなたかお分かりの方がおられましたお教え頂けないでしょうか。 AWKでなくとも、sedでもPerlでもその他のコマンドでも構いませんし、スクリプトファイルを読み込めるコマンドでしたらスクリプトでの書き方でも結構ですので、ご存知の方がおられましたらお教え頂けないでしょうか。

  • コマンドプロンプトのバッチファイルでテキストファイル内の文字列を抜き出したい

    コマンドプロンプトのバッチファイルでテキストファイル内の文字列から何文字か抜き出すにはどうすればよいですか? たとえば,abcde****** のようにその行の最後から6文字目までとか。

  • 正規表現にマッチした文字列の抽出

    閲覧頂きありがとうございます。 Linuxのsedコマンドに該当するwindowsコマンドは存在しますでしょうか? 存在しない場合、batやマクロでの長い記述となってしまっても構いません。 検索で調べたところ、特定のdllを入れればsedを使用できるとあったのですが、その方法は取りたくありません。 100万行以上あるテキストファイル(一行=一レコード)の中から、正規表現とマッチする文字列の抽出作業です。 1行に1つ、不特定な場所にその文字列が存在するという形です。 その抽出した文字列を、別のテキストファイルへ吐き出す…といった処理を想定しています。 どうかご教示いただけると幸いです。 環境 windows7、EmEditor使用

  • 複数のファイルに同じ文字列を自動入力するバッチ

    複数のテキストファイルに同じ文字列を入力して保存するバッチを作成したいです。 テキストファイル1.txt テキストファイル2.txt テキストファイル3.txt 上記3つのテキストファイルがあったとしてバッチを起動すると 同じ文字列のデータを自動的に入力したい。 自動入力する文字列:あいうえお そもそも実現可能なのかもよくわかっていませんが ご教示いただけますと幸いです。

  • 【コマンドプロンプト】テキストファイル内の文字列置換

    こんにちは。 コマンドプロンプトのバッチファイルでテキストファイル内の文字列の置換を行いたいと考えております。 例えば以下のような内容があった場合、 --開始-- ABCDEFG1111 ABCDEFG ABCDEFG1111 HIJKLMN --終了-- バッチファイル処理結果として 1111 ABCDEFG 1111 HIJKLMN という結果を別ファイルに出力したいのです。 制限としては、sed,awkなどのwindows上で稼動するツールがあるようですが それらは使用できません。 どなたかご存知の方教えていただけないでしょうか よろしくお願い致します。

  • バッチファイルでテキストファイルの文字列を取得したい

    すみません、どなたか教えて下さい。 バッチファイル(test.bat)内で、他のテキストファイル(ok.txt)の文字列を取得したいです。 ok.txtは 20070614 TEST となってます。 この2つの文字列をそれぞれで取得する方法を教えて下さい。 よろしくお願い致します。

  • バッチファイルでテキストファイル内の特定の文字列をコンピュータ名に置換

    バッチファイルでテキストファイル内の特定の文字列をコンピュータ名に置換したい バッチファイルの記述方法について教えて下さい。 テキストファイル内に特定の文字列が存在していた場合、その文字列をバッチファイルを実行するPCのコンピュータ名で置換するにはどのように記述したら良いでしょうか。 なおPCはWindowsXPを使用しています。

  • ファイル内の文字列を置換

    掲示板利用させていただきます。 現在、ファイル内の特定の文字列を置換し、 保存する方法を探しています。 できればスクリプト言語を利用したいと考えています。 sedコマンドを使用して文字列置換を行ったのですが 置換前と置換後のファイルで 文字コードと改行コードが変わってしまうのでダメでした; 「ファイル内の特定の文字列を任意の文字列に置換し、置換前と置換後で改行コードと文字コードを変えない方法」 をご存知の方、ご教示ください。 bash,perl,javaのどれでも結構です。 よろしくおねがいします。

  • バッチファイルで文字列の検索結果件数を取得したい

    バッチファイルでテキストファイルに含まれる、文字列を検索し、その検索結果個数は取得可能でしょうか? 【例】test.txt 【内容】abcdefg12345xyza テキストファイルは1レコードです。 "a"で検索したときは2を取得したいのです。。。 バッチファイルだけじゃ無理ですかね(><) よろしくお願いします。

  • ファイルの内の文字列の置換について

    質問なんですが、sedコマンドを使用して文字の置換をやってみたんですが、同じファイルに置換した情報を上書きすることは可能でしょうか? 今試した例としては sed -e 's/aaa/bbb/g' test > test と試してみたんですがファイルの内容がなくなってしまっていました。 同じファイルに置換内容を入れることは可能なのでしょうか? 他の方法がある場合は教えてください。 よろしくお願いします。

専門家に質問してみよう