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

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

新規登録して質問してみよう
ただいま回答率
85.50%
bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

2回答

4832閲覧

diffにて、比較するファイルの特定の条件の内容を省いて比較(例えばコメント)する

ssmxgo

総合スコア178

bash

bash(Bourne-again-Shell)は sh(Bourne Shell)のインプリメンテーションに様々な機能が追加されたシェルです。LinuxやMac OS XではBashはデフォルトで導入されています。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

0クリップ

投稿2016/11/04 01:30

編集2016/11/04 01:37

diffにて、比較するファイルの特定の条件の内容を省いた比較の仕方を教えてください。
例えば、ファイルA,ファイルBのうち、先頭が#や//、REMなどコメントに関しては比較対象から外す
みたいなことをしたいです。

bash

1$ diff -u file_A.php file_B.php

コレに対し、
sed -e "/[^#|^\/\/]/d" file_A(B).php
みたいな要素が入ってくると思うのですが、実現がわかりません。

ご教授いただけると幸いです。

ココらへんが参考になるかと思ったのですが、ちょっとハードルが高くてわかりませんでした。

tempに吐き出せば確かにできるといえば出来るのですが。

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

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

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

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

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

guest

回答2

0

ベストアンサー

プロセス置換を使って以下の通りに書けます。

diff -u <(sed -e "/[^#|^\/\/]/d" file_A.php) <(sed -e "/[^#|^\/\/]/d" file_B.php)

投稿2016/11/04 01:37

ynakano

総合スコア1894

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

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

ssmxgo

2016/11/04 01:45

おおおおおおおおおおおお! 試してみます!
ssmxgo

2016/11/04 02:59

ありがとうございます。手でシェルを叩く分には問題なくできました! 問題としてはシェルに書くとエラーが出てしまいますが、文法的に間違っているとは思えません。謎です test_diff.sh: line XX: syntax error near unexpected token `(' test_diff.sh: line XX: `diff -uBb --suppress-common-lines <(sed -e "/^\/\//d" file_A.php) <(sed -e "/^\/\//d" file_B.php)'
ynakano

2016/11/04 03:18

私も試してみましたがエラーにならないですね。 シェルスクリプト全て記載いただけますか。
ssmxgo

2016/11/04 03:25

#!/bin/sh diff -uBb --suppress-common-lines <(sed -e "/^\/\//d" file_A.php) <(sed -e "/^\/\//d" file_B.php) という極シンプルなものです。 コマンドラインから diff -uBb --suppress-common-lines <(sed -e "/^\/\//d" file_A.php) <(sed -e "/^\/\//d" file_B.php を叩く分には正常に動きます。
ynakano

2016/11/04 03:31

1行目をshではなくbashにしてください。 shにはプロセス置換の機能がありません。 最初に言うべきでしたね。bashだとばかり思っていました。
KiyoshiMotoki

2016/11/04 03:48

ynakano様、ssmxgo様 横から失礼します。 "/[^#|^\/\/]/d" だと  ('#'以外の1文字 または '/'以外の1文字) または '/' という意味になりますので、全ての行にヒットしてしまいます。 正しく(*)は "/^\s*\(\/\/\)\|#/d" ではないでしょうか? * CentOS6.5 で動作確認しました。  Mac だと sed がパイプ('|')をサポートしていないらしく、動作しませんでしたorz 以下、実行結果 (コメントだと行頭の半角スペースが削除されてしまうので、  全角スペースに置き換えてあります) # cat file_A.php <?php // They are human. // He is man.  // They are human.  // He is man. # They are human. # He is man.  # They are human.  # He is man. echo 'They are human.' . PHP_EOL; echo 'He is man.' . PHP_EOL;  echo 'They are human.' . PHP_EOL;  echo 'He is man.' . PHP_EOL; # cat file_B.php <?php // They are human. // She is woman.  // They are human.  // She is woman. # They are human. # She is woman.  # They are human.  # She is woman. echo 'They are human.' . PHP_EOL; echo 'She is woman.' . PHP_EOL;  echo 'They are human.' . PHP_EOL;  echo 'She is woman.' . PHP_EOL; # diff -u <(sed -e "/^\s*\(\/\/\)\|#/d" file_A.php) <(sed -e "/^\s*\(\/\/\)\|#/d" file_B.php) --- /dev/fd/63 2016-11-04 12:43:35.537926244 +0900 +++ /dev/fd/62 2016-11-04 12:43:35.537926244 +0900 @@ -1,5 +1,5 @@ <?php echo 'They are human.' . PHP_EOL; -echo 'He is man.' . PHP_EOL; +echo 'She is woman.' . PHP_EOL;   echo 'They are human.' . PHP_EOL; - echo 'He is man.' . PHP_EOL; + echo 'She is woman.' . PHP_EOL; # diff -u <(sed -e "/[^#|^\/\/]/d" file_A.php) <(sed -e "/[^#|^\/\/]/d" file_B.php)  -> 何も表示されない
ynakano

2016/11/04 03:52

KiyoshiMotoki様 コメントありがとうございます。 実は私はsedの方はスルーしてしまっています。 あくまでプロセス置換に焦点を絞って回答していました。 私の手元で試したのは先ほど記載いただいたシェルスクリプトを(インプットファイルは適宜変更して)実行してみる、というものでした。 shでは動かず、bashで動くことを確認しています。 ※shでプロセス置換ができないことの裏取りだけです。
ssmxgo

2016/11/04 03:58

すみません、しかも私、コードにbashと書いていました。 できました!!!! ヽ(=´▽`=)ノ 本当にありがとうございました!!!!!!
ynakano

2016/11/04 04:00

上手くいったのなら何よりです。 ちなみに、お分かりになったと思うのですがプロセス置換だと中間ファイルができないので、想定通りに動作しない場合の切り分けが面倒になるかもしれません。 これでハマるケースは結構あります。
ssmxgo

2016/11/04 04:04

KiyoshiMotoki様 ありがとうございます。私も実は書きながら、正規表現間違ってるなぁ…と思いつつ、「これは後で勉強してだめなら正規表現の質問としてあげてみよう」と思っていました。 ので大変助かります。テストさせていただきます!
KiyoshiMotoki

2016/11/04 04:05 編集

ynakano様 > 実は私はsedの方はスルーしてしまっています。 > あくまでプロセス置換に焦点を絞って回答していました。 それなら始めからそのように注記しておくべきでしたね。 指摘されてから「実は…」と言うのでは、不親切だと思いませんか? ssmxgo様 解決できたようで、何よりです。
ssmxgo

2016/11/04 04:08 編集

ynakano様 勉強になります。ありがとうございました! KiyoshiMotoki様 ynakano様 気付いたのがつい先程でして…(^_^;)失礼は私めです、もうしわけありませんでした。 今度は早めに修正いたします
ynakano

2016/11/04 04:08

KiyoshiMotoki様 質問文が「sed(中略)【みたいな】」とあったので、この部分は固まっていないのであろう、つまりsedの部分は主題ではないだろうとの判断ですが、言われてみればご指摘の通りかもしれません。
ssmxgo

2016/11/04 04:11

お二方、本当に有難うございました。 正規表現は、sedを片付けた上で改めてチェックしますので小一時間くださいませ
ssmxgo

2016/11/04 05:40

質問文が「sed(中略)【みたいな】」>> アセアセ 正規表現も手探りなもので…申し訳ないばかりです。 ynakano 様、動作確認できました。 グループの()と[]を間違えていたこと、そもそもOR条件をする()程度にしか理解していませんでした。 \(\/\/\)\ だけが理解できませんでした。(\/\/)じゃないかと思ってこちらのサイトで比較したら https://regexper.com/#%5E%5Cs*%5C(%5C%2F%5C%2F%5C)%5C%7C%23 意味が変わっちゃうのですね https://regexper.com/#%5E%5Cs*(%5C%2F%5C%2F)%7C%23 ただし、こちらは質問の主旨からズレてしまうので、どうしてもわからなければ改めて質問してみようかと思います。ありがとうございました!
KiyoshiMotoki

2016/11/04 06:34 編集

ssmxgo様 > \(\/\/\)\ だけが理解できませんでした。 これは、括弧"( )"、パイプ"|"、スラッシュ"/"をエスケープしているだけです。 これらの文字は UNIXコマンドの中で特別な意味を持つので、エスケープしてやる必要があります。 結局、sed コマンドに渡す文字列は以下のようになります。  ^\s*(//)|# ちなみに、私がコメント欄に提示させていただいた正規表現も間違いでした(^^; (グルーピングする場所を間違えていたので、^\s* が // にしか効いていませんでした) 正しくは、以下でした。  "/^\s*\(\/\/\|#\|REM\)/d"
ssmxgo

2016/11/04 06:18

あ、、この場合は()|にエスケープが必要になるんですねぇ(^_^;) お恥ずかしい。 間違いのご指摘、これも言われてみればです。ご丁寧にありがとうございました!
guest

0

grep で処理した方が汎用的な気がしますが、どーしても diff だけで処理しないとダメですか (^^;

bash

1$ diff -u file_A.php file_B.php | grep -vE '^(REM|#|\/\/)'

投稿2016/11/04 02:07

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

ssmxgo

2016/11/04 02:57

おお、その手が! ちょっと検討してみます(盲点でした)
退会済みユーザー

退会済みユーザー

2016/11/04 03:10

パイプ経由でプロセスを一つ、余分に実行することにはなりますけど簡単なのでオススメです :)
ssmxgo

2016/11/04 03:14

確かに簡単でした。実際、sedで実現しなきゃいけないパターンがあるので全て網羅できないのですが、こちらはこちらでお手軽でした(目からうろこ)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問