![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?c9bd177)
バッチファイルで、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コマンド以外でも構いませんので、何かいい方法をご存知の方がおられましたらお教え頂けないでしょうか。
No.1ベストアンサー
- 回答日時:
awk '/222/&&/444/&&/666/{print "MATCHED";next}{print}'
正規表現で 222 444 666 が出てくる順番の6通りを網羅すればいいので、sedだけでも出来ます。
この回答への補足
ご回答ありがとうございます。
自分はプログラミング等の難しい事は解らず、簡単なコマンドを連続させて使う程度なのですが、正直、お教え頂いた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コマンドに当てはめて、実行するという処理を書こうかと考えています。
処理速度の問題も、なんとか考えて解決したいと思います。
ご回答、本当にありがとうございました。
色々なWEBページを参考にして、試行錯誤していたのですが、無事に目的の動作が出来ました。
ありがとうございました。
最初の補足を投稿させて頂く前に、検索エンジンで色々調べてやっていたのですが、結果として、その時にやっていたコマンドの基本的な構文は間違っていませんでした。
しかし、こちらの環境がWindows環境な為、「'」「"」の扱いが他のOSとは違っていて、その為にエラーになっていた様です。
お教え頂いたコマンドを、以下の様に書き換えさせて頂いて、実行してみると、うまく動作してくれました。
awk "/222/&&/444/&&/666/{print \"MATCHED\";next}{print}" in.txt > out.txt
お教え頂いたこの方法が、一番良いと思うので、この方法でやっていこうと思います。
大変助かりました。本当にありがとうございました。
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等が便利でしょう。
ご回答ありがとうございます。
大変丁寧に解説して頂きありがとうございます。
まだ今の自分では、ご説明頂いた全てを理解する事は出来ませんが、何度も読み返して理解して行こうと思います。
ご回答頂いた通りにテストしてみました。
うまく動作してくれました。
ありがとうございました。
ただ、逆に「条件によっては意図した動作にならない」というケースが、まだ今の自分では理解出来ていませんので、今度、時間を掛けて理解して行こうと思います。
何より、sedに対する知識が少し増えた事が嬉しいです。
違うケースでも活用して行こうと思います。
awkやperl等も今後は勉強して行こうと思います。
ご回答、本当にありがとうございました。
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
再度、ご回答頂きありがとうございます。
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が見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- UNIX・Linux sedでの正規化 2 2022/05/10 11:39
- Excel(エクセル) 【VBA】指定フォルダに格納中のテキストファイルをエクセルで処理し結果のエクセルを新規フォルダに保存 1 2022/03/25 14:19
- Visual Basic(VBA) EXCEL VBA 単語置き換え について質問です ブック名 ぶぶぶ シート名 ししし セル V3〜 3 2023/03/08 01:41
- Visual Basic(VBA) Excel VBAでAA(BBB) → BBB.AA に置換したい 2 2022/10/30 13:59
- フリーソフト サクラエディタの正規表現(grep機能)の使い方 3 2022/06/22 10:29
- Visual Basic(VBA) EXCEL VBAで教えてください。 1 2022/12/22 04:20
- Excel(エクセル) Excelにて、フォルダ内のTextファイルをマクロで統合すると文字化けしてしまう時の解消コード 4 2023/01/01 07:32
- Ruby power BI クエリエディター 〇〇を含む文字列置換 1 2022/10/16 17:34
- Visual Basic(VBA) Excel VBA 教えてください。 VBA初心者です。 詳しい方がいましたら教えてください。 下記 3 2023/04/25 11:22
- Excel(エクセル) Excel 複数列のある文字を優先して1列に表示したいです 2 2022/12/03 12:07
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
バッチ終了時にDOS窓を閉じるコ...
-
make test って何をするための...
-
バッチファイル 文字列にスペ...
-
Pythonで単純にファイルを結合...
-
BATファイル作成時の記述に...
-
ftp受信確認
-
バッチファイルでdiskpart.exe...
-
リネームバッチ
-
VB.NETでのDOSコマンドを実行に...
-
コンソールアプリケーションに...
-
コマンドプロンプトをクリック...
-
VBSでタイマー
-
大量のフォルダからひとつのフ...
-
コマンドプロンプトのエラーに...
-
コマンドプロンプトの「%1」と...
-
バッチファイルで以下のような...
-
エクセルのVBAについて とある...
-
stable diffusionのインストー...
-
バッチでテキストファイルから...
-
exeファイルを実行するとコマン...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
バッチ終了時にDOS窓を閉じるコ...
-
バッチファイル 文字列にスペ...
-
make test って何をするための...
-
コマンドプロンプトをクリック...
-
ftpコマンドを実行すると「425 ...
-
ショートカットをデスクトップ...
-
バッチコマンドのIF文(条件...
-
シェルの「:コマンドが見つか...
-
バッチファイルを使ってテキス...
-
コマンドプロンプトでファイル...
-
コマンドプロンプトで、特定の...
-
findstrでヒットした1行前の文...
-
コンピュータ名をファイル名に...
-
Pythonで単純にファイルを結合...
-
AccessVBAで実行時間を指定する...
-
コマンドプロンプトのERRORLEVE...
-
BATファイル作成時の記述に...
-
SSH接続でwindowsサーバのコマ...
-
バッチファイルでdiskpart.exe...
-
DOSコマンドで指定日数よりも過...
おすすめ情報