মন্তব্যগুলি উপেক্ষা করে ফাইলগুলি কীভাবে পৃথক করবেন (# দিয়ে শুরু হওয়া লাইন)?


55

আমার দুটি কনফিগারেশন ফাইল রয়েছে, প্যাকেজ ম্যানেজারের আসল এবং আমার নিজের দ্বারা সংশোধিত একটি কাস্টমাইজড ফাইল। আমি আচরণ বর্ণনা করতে কিছু মন্তব্য যুক্ত করেছি।

আমি কীভাবে diffকনফিগারেশন ফাইলগুলিতে চালাতে পারি ? একটি মন্তব্য করা লাইন দ্বারা সংজ্ঞায়িত:

  • leadingচ্ছিক শীর্ষস্থানীয় সাদা স্থান (ট্যাব এবং স্পেস)
  • হ্যাশ সাইন ( #)
  • অন্য কিছু চরিত্র

(সহজতম) নিয়মিত প্রকাশটি প্রথম প্রয়োজন বাদ দেওয়া হবে #.*। আমি জিএনইউ ডিফের ৩.০ এর --ignore-matching-lines=RE( -I RE) বিকল্পটি চেষ্টা করেছিলাম , তবে আমি আরইআর দিয়ে এটি কাজ করতে পারিনি। আমিও চেষ্টা .*#.*এবং .*\#.*ভাগ্য ছাড়া। আক্ষরিকরূপে লাইনটি ( Port 631) কোনওটির সাথে REমেলে না, এমনভাবে আরআরএকে স্ল্যাশের মধ্যে রাখতে সহায়তা করে না।

যেমনটি "ডিফ" পরামর্শ দেওয়া হয়েছে তেমন রিগেক্সের সরঞ্জামটির গন্ধটির অভাব রয়েছে? , আমি চেষ্টা করেছি grep -G:

grep -G '#.*' file

এটি মন্তব্যের সাথে মিলছে বলে মনে হয় তবে এটি কার্যকর হয় না diff -I '#.*' file1 file2

সুতরাং, এই বিকল্পটি কীভাবে ব্যবহার করা উচিত? আমি কীভাবে diffনির্দিষ্ট লাইনগুলি ছেড়ে যেতে পারি (আমার ক্ষেত্রে, মন্তব্যসমূহ)? দয়া grepকরে ফাইলটি ইনগ করার এবং অস্থায়ী ফাইলগুলির তুলনা করার পরামর্শ দিবেন না।


12
-Iবিকল্পটির ফলে কেবল একটি ব্লককে এড়ানো হবে যদি তার সমস্ত লাইনগুলি রেজিপেক্সের সাথে মেলে। সুতরাং আপনি সেইভাবে কোনও মন্তব্য-পরিবর্তনের পরিবর্তনকে এড়িয়ে যেতে পারেন তবে কোনও মন্তব্য নয় এমন মন্তব্য পরিবর্তনের নয় যা কোনও মন্তব্য নয় change
গিলস 'অশুভ হওয়া বন্ধ করুন'

@ গিলস: ধন্যবাদ, এখন আমি পেয়েছি কেন diff -Iআমার প্রত্যাশা অনুযায়ী আচরণ হয় না। আমি আমার উত্তরটি একটি উদাহরণ দিয়ে আপডেট করেছি যা আমার জন্য এই আচরণটি স্পষ্ট করে।
লেকেনস্টেইন

উত্তর:


49

গিলসের মতে, -Iসেটের ম্যাচের ব্যতীত যদি সেটের মধ্যে আর কিছুই মেলে না তবে বিকল্পটি কেবল একটি লাইন উপেক্ষা করবে -I। আমি এটি পরীক্ষা না করা পর্যন্ত আমি এটি পুরোপুরি পাইনি।

পরীক্ষা

তিনটি ফাইল আমার পরীক্ষার সাথে জড়িত:
ফাইল test1:

    text

ফাইল test2:

    text
    #comment

ফাইল test3:

    changed text
    #comment

আদেশগুলি:

$ # comparing files with comment-only changes
$ diff -u -I '#.*' test{1,2}
$ # comparing files with both comment and regular changes
$ diff -u -I '#.*' test{2,3}
--- test2       2011-07-20 16:38:59.717701430 +0200
+++ test3       2011-07-20 16:39:10.187701435 +0200
@@ -1,2 +1,2 @@
-text
+changed text
 #comment

বিকল্প উপায়

-Iবিকল্পটি কীভাবে সঠিকভাবে ব্যবহার করবেন সে সম্পর্কে এখন পর্যন্ত কোনও উত্তর না থাকায় , আমি এমন একটি বিকল্প সরবরাহ করব যা ব্যাশ শেলগুলিতে কাজ করে:

diff -u -B <(grep -vE '^\s*(#|$)' test1)  <(grep -vE '^\s*(#|$)' test2)
  • diff -u - ইউনিফাইড ডিফ
    • -B - ফাঁকা লাইন উপেক্ষা করুন
  • <(command)- প্রক্রিয়া প্রতিস্থাপন নামে একটি বাশ বৈশিষ্ট্য যা কমান্ডের জন্য একটি ফাইল বর্ণনাকারী খোলে, এটি একটি অস্থায়ী ফাইলের প্রয়োজনীয়তা সরিয়ে দেয়
  • grep - একটি প্যাটার্ন মিলছে লাইন মুদ্রণের জন্য কমান্ড (নয়)
    • -v - মিল না-করা লাইনগুলি দেখান
    • E - বর্ধিত নিয়মিত এক্সপ্রেশন ব্যবহার করুন
    • '^\s*(#|$)' - মন্তব্য এবং খালি লাইন মিলছে একটি নিয়মিত অভিব্যক্তি
      • ^ - একটি লাইনের শুরুতে মেলে match
      • \s* - হোয়াইটস্পেস (ট্যাব এবং স্পেস) মিলিয়ে নিন
      • (#|$) একটি হ্যাশ চিহ্নটি, বা বিকল্পভাবে, একটি লাইনের শেষে মেলে match

6

চেষ্টা করুন:

diff -b -I '^#' -I '^ #' file1 file2

দয়া করে নোট করুন যে রেজেক্সকে উভয় ফাইলের সাথে সম্পর্কিত লাইনের সাথে মিল রাখতে হবে এবং এটি কাজ করার জন্য হুনের প্রতিটি পরিবর্তিত লাইনের সাথে মেলে, অন্যথায় এটি এখনও তফাতটি দেখায় show

শেল প্রসারিত হতে প্যাটার্ন রক্ষা করতে এবং রেজেক্স-সংরক্ষিত অক্ষরগুলি (যেমন বন্ধনী) থেকে বাঁচতে একক উদ্ধৃতি ব্যবহার করুন।

আমরা diffutilsম্যানুয়ালটিতে পড়তে পারি :

যাইহোক, -Iকেবল হুনের প্রতিটি পরিবর্তিত রেখা (প্রতিটি সন্নিবেশ এবং প্রতিটি মুছে ফেলা) নিয়মিত প্রকাশের সাথে মিলে গেলে নিয়মিত অভিব্যক্তি যুক্ত রেখাগুলির সন্নিবেশ বা মোছার বিষয়টি উপেক্ষা করে।

অন্য কথায়, প্রতিটি অজ্ঞানীয় পরিবর্তনের জন্য, অদ্বিতীয় diffএবং তার আশেপাশের পরিবর্তনের সম্পূর্ণ সেট মুদ্রণ করে। একাধিক -Iবিকল্প ব্যবহার করে লাইনগুলিকে উপেক্ষা করার জন্য আপনি একাধিক নিয়মিত অভিব্যক্তি নির্দিষ্ট করতে পারেন । diffপ্রদত্ত সর্বশেষটি দিয়ে শুরু করে প্রতিটি নিয়মিত অভিব্যক্তির বিপরীতে প্রতিটি লাইন মিলানোর চেষ্টা করে।

এই আচরণটি এখানে আর্মেল দ্বারাও ভালভাবে ব্যাখ্যা করা হয়েছে

সম্পর্কিত: আমি কীভাবে কোনও পারফর্ম করতে পারি যা সমস্ত মন্তব্যকে উপেক্ষা করে?


2

ওয়েবে সন্ধানের পরে, লেকেনস্টেইনের বিকল্প উপায়টি আমি খুঁজে পেয়েছি।

তবে আমি প্যাচ হিসাবে পৃথক আউটপুট ব্যবহার করতে চাই ... এবং একটি সমস্যা আছে কারণ "গ্রেপ-ভি" এর কারণে লাইন নম্বর নোটটি রাখা হয়েছে।

সুতরাং আমি এই কমান্ড লাইনের উন্নতি করার লক্ষ্য রেখেছি:

diff -u -B <(sed 's/^[[:blank:]]*#.*$/ /' file1)  <(sed 's/^[[:blank:]]*#.*$/ /' file2)

এটি নিখুঁত নয় তবে লাইন নম্বরটি প্যাচ ফাইলে রাখা আছে।

যাইহোক, যদি মন্তব্য লাইনের পরিবর্তে কোনও নতুন লাইন যুক্ত করা হয় ... তবে মন্তব্যটি প্যাচ করার সময় একটি হুঙ্ক ফেইলড তৈরি হবে যখন আমরা বেলো দেখতে পাচ্ছি।

File test1:
  text
  #comment
  other text
File test2:
  text
  new line here
  #comment changed
  other text changed

এখন আমাদের কমান্ড পরীক্ষা

$ echo -e "#!/usr/bin/sed -f\ns/^[[:blank:]]*#.*$/ /" > outcom.sed
$ echo "diff -u -B <(./outcom.sed \$1)  <(./outcom.sed \$2)" > mydiff.sh
$ chmod +x mydiff.sh outcom.sed
$ ./mydiff.sh file1 file2 > file.dif
$ cat file.dif
--- /dev/fd/63  2014-08-23 10:05:08.000000000 +0200
+++ /dev/fd/62  2014-08-23 10:05:08.000000000 +0200
@@ -1,2 +1,3 @@
 text
+new line

-other text
+other text changed

/ dev / fd / 62 এবং / dev / fd / 63 প্রক্রিয়া প্রতিস্থাপন দ্বারা ফাইল উত্পাদিত হয়। "+ নতুন লাইন" এবং "-অন্য পাঠ্য" এর মধ্যে লাইনটি মন্তব্যগুলি প্রতিস্থাপনের জন্য আমাদের সেড এক্সপ্রেশনটিতে সংজ্ঞায়িত করা ডিফল্ট স্পেস ক্যারেক্টার।

এবং এখন, যখন আমরা এই প্যাচটি প্রয়োগ করি তখন কী ঘটে থাকে:

$ patch -p0 file1 < file.dif 
patching file file1
Hunk #1 FAILED at 1.
1 out of 1 hunk FAILED -- saving rejects to file file1.rej

সমাধান হ'ল -u ছাড়া ইউনিফাইড ডিফর্ম্যাট বিন্যাসটি ব্যবহার করবেন না

$ echo "diff -B <(./outcom.sed \$1)  <(./outcom.sed \$2)" > mydiff.sh
$ ./mydiff.sh file1 file2 > file.dif
$ cat file.dif
1a2
> new line
3c4
< other text
---
> other text changed
$ patch -p0 file1 < file.dif 
patching file file1
$ cat file1
text
new line
#comment
other text changed

এখন প্যাচ ফাইল ওয়ার্কিং ফাইল (খুব জটিল ডিফ প্রসেসের ফলাফলের ওয়ারেন্টি ছাড়াই)।


প্রসঙ্গ পার্থক্যের কারণে আপনার ইউনিফাইড ডিফ প্রয়োগ করতে ব্যর্থ। আপনি diff -U0 one twoপ্রসঙ্গটি অক্ষম করতে ব্যবহার করতে পারেন । প্যাচিংয়ের জন্য, এমন একটি গুচ্ছ সরঞ্জাম রয়েছে যা কেডিফ 3 এর মতো আরও উপযুক্ত হতে পারে।
লেকেনস্টেইন

-U0প্রসঙ্গ অক্ষম করার বিকল্পের জন্য আপনাকে ধন্যবাদ । দ্রষ্টব্য: kdiff3 একটি গ্রাফিকাল সরঞ্জাম। গিট মার্জ বৈশিষ্ট্যগুলি পরিচালনা করার জন্য আমার স্বয়ংক্রিয় সরঞ্জাম প্রয়োজন।
সমন্বয় করুন

vimdiffথ্রি-ওয়ে সংহতিকে সমর্থন করে, এটি দেখার মতো হতে পারে।
লেকেনস্টেইন

আরও সুনির্দিষ্ট হওয়ার জন্য, স্কিট স্ক্রিপ্টে বহিরাগতদের সাথে গিট মার্জ প্রক্রিয়াটি স্বয়ংক্রিয় করার জন্য আমার একটি স্ক্রিপ্ট সরঞ্জাম প্রয়োজন। kdiff3 এবং vimdiff ইন্টারেক্টিভ টুলস, আমার ক্ষেত্রে ব্যবহারযোগ্য নয়।
সামঞ্জস্য করুন

1

আমি সাধারণত এই গন্ডগোলটিকে এড়িয়ে যাচ্ছি:

  • grep -v "^#" | cat -sএগুলি ব্যবহার করে এবং তার থেকে আলাদা করে মন্তব্যবিহীন সংস্করণগুলি তৈরি করা হয় ...
  • vim -dফাইলগুলি দেখতে ব্যবহার করে। সিনট্যাক্স হাইলাইটিং মন্তব্য বনাম বনাম মন্তব্যগুলির পার্থক্যকে বেশ সুস্পষ্ট করে তোলে care ইন-লাইন পার্থক্যের আলাদা হাইলাইট করা যাতে আপনি দেখতে পান কোন মান বা মানগুলির অংশগুলি এক নজরে পরিবর্তিত হয়েছে তা এটি আমার প্রিয় করে তোলে।

0

আমি এখানে সমস্ত মন্তব্য করা রেখাগুলি মুছে ফেলার জন্য যা ব্যবহার করি তা হল- কোনও ট্যাব বা স্পেস দিয়ে শুরু করা- এবং ফাঁকাগুলি:

egrep -v "^$|^[[:space:]]*#" /path/to/file

বা আপনি করতে পারেন

sed -e '/^#.*/d' -e 's/#.*//g' | cat -s
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.