স্থান পরিবর্তনের জন্য কীভাবে "সেড" প্রতিবেদন করবেন


23

sedস্থানে স্ট্রিংগুলি প্রতিস্থাপনের জন্য ব্যবহার করার সময় , কীভাবে এটি পরিবর্তনগুলি (পুরানো এবং নতুন ফাইলের উপর নির্ভর না করে) প্রতিবেদন করার উপায় আছে?

উদাহরণস্বরূপ, আমি কীভাবে কমান্ড লাইনটি পরিবর্তন করতে পারি

find . -type f | xargs sed -i 's/abc/def/g'

তাই আমি কী উড়ানের পরিবর্তনগুলি দেখতে পাচ্ছি?

উত্তর:


15

আপনি ব্যবহার করতে পারে sed'র wপারেন সঙ্গে পতাকা /dev/stderr, /dev/tty, /dev/fd/2আপনার সিস্টেমে সমর্থিত হয়। যেমন একটি ইনপুট সহ উদাহরণস্বরূপ file:

foo first
second: missing
third: foo
none here

চলমান

sed -i '/foo/{
s//bar/g
w /dev/stdout
}' file

আউটপুট:

bar first
third: bar

যদিও fileবিষয়বস্তুতে এতে পরিবর্তন করা হয়েছিল:

bar first
second: missing
third: bar
none here

সুতরাং আপনার ক্ষেত্রে, চলমান:

find . -type f -printf '\n%p:\n' -exec sed -i '/foo/{
s//bar/g
w /dev/fd/2
}' {} \;

জায়গাগুলি এবং আউটপুট ফাইলগুলি সম্পাদনা করবে:

./file1:
বার স্টাফ
আরও বার

./file2:

./file3:
প্রথম বার
তৃতীয়: বার

আপনি যেমন কিছু মুদ্রণ করতে পারেন original line >>> modified line:

find . -type f -printf '\n%p:\n' -exec sed -i '/foo/{
h
s//bar/g
H
x
s/\n/ >>> /
w /dev/fd/2
x
}' {} \;

জায়গাগুলি এবং আউটপুটগুলিতে ফাইলগুলি সম্পাদনা করে:

./file1:
foo স্টাফ >>> বার স্টাফ
আরও foo >>> আরও বার

./file2:

./file3:
foo first >>> প্রথমে বার করুন
তৃতীয়: foo >>> তৃতীয়: বার

16

আপনি pপ্রথম পাসে রিন্ট অ্যাকশন ব্যবহার করে দুটি পাসে এটি করতে পারেন :

find . -type f | xargs sed --quiet 's/abc/def/gp'

যেখানে --quietসেড প্রতিটি লাইন প্রদর্শন করে না এবং pপ্রত্যয়টি কেবলমাত্র রেখাগুলি প্রদর্শন করে যেখানে প্রতিস্থাপনটি মিলেছে।

এতে সীমাবদ্ধতা রয়েছে যা শেডটি দেখায় না যে কোন ফাইলগুলি পরিবর্তন করা হচ্ছে অবশ্যই কোন অতিরিক্ত জটিলতার সাথে কোনটি ঠিক করা যেতে পারে।


আপনার দুটি পাসের দরকার হওয়ায় এটি আমি যা চাইছিলাম তা পুরোপুরি করে না, তবে আমি ভোট দিচ্ছি কারণ আমি এই পি জিনিসটি শিখেছি এবং এটি খুব দরকারী। বিশেষত যদি, আপনি যেমন বলেছিলেন, ফাইলগুলিও মুদ্রিত হয়েছিল। এর মতো কিছুfor x in `find . -type f`; do echo ///File $x: ; sed --quiet 's/abc/def/gp' $x; done
18'4 এ রিচাব

@ এমএসডাব্লু আমার অনেক sedঅভিব্যক্তি আছে, আমি /gpপ্রত্যেকের জন্যই লিখতে চাই না । কীভাবে এটি বিশ্বব্যাপী সেট করবেন?
আলহালাল

8

আমি এটি সম্ভব বলে মনে করি না, তবে পরিবর্তে পার্ল ব্যবহার করা সম্ভবত একটি কাজ হতে পারে:

find . -type f | xargs perl -i -ne 's/abc/def/ && print STDERR' 

এটি স্ট্যান্ডার্ড ত্রুটিতে পরিবর্তিত রেখাগুলি মুদ্রণ করবে । উদাহরণ স্বরূপ:

$ cat foo
fooabcbar
$ find . -type f | xargs perl -i -ne 's/abc/def/ && print STDERR' 
foodefbar

আপনি লাইন নম্বর, ফাইলের নাম, মূল লাইন এবং পরিবর্তিত লাইন মুদ্রণ করে এটিকে আরও জটিল করে তুলতে পারেন:

$ find . -type f | 
   xargs perl -i -ne '$was=$_; chomp($was);
                      s/abc/def/ && print STDERR "$ARGV($.): $was : $_"' 
./foo(1): fooabcbar : foodefbar

+1 আপনি $ARGVযে ফাইলটি চালিত হচ্ছে তার নামের জন্যও ব্যবহার করতে পারেন ।
জোসেফ আর।

@JosephR। ভাল পয়েন্ট, যোগ।
টেরডন

ধন্যবাদ, এটি সম্ভবত সহায়ক (এটি নিজেই পরীক্ষিত হয়নি)। আমি সেডটি ব্যবহার করে না বলে নির্বাচন করছি না, সুতরাং এটি প্রশ্নের সঠিক উত্তর দেয় না।
রিস্যাব

@ricab যে জরিমানা, আপনি একটি উত্তর গ্রহণ করা উচিত নয় যদি না তা আসলে উত্তর আপনার প্রশ্নের। মনে রাখবেন যদিও এর মতো সাধারণ জিনিসের জন্য perlএর সিনট্যাক্সের সাথে খুব মিল থাকে sedএবং আপনি যা চাইছেন তা আসলে সম্ভব কিনা তা আমি মনে করি না sed
টেরডন

3

ডাব্লু পতাকা ব্যবহার করে এটি সম্ভব যা কোনও ফাইলটিতে বর্তমান প্যাটার্নটি লেখে। সুতরাং এটিকে বিকল্প কমান্ডে যুক্ত করার মাধ্যমে আমরা একটি ফাইলকে পর পরের প্রতিবেদনগুলি রিপোর্ট করতে পারি এবং কাজটি শেষ হওয়ার পরে এটি মুদ্রণ করতে পারি। আমি গ্রেপ সহ প্রতিস্থাপিত স্ট্রিংটি রঙিন করতে চাই।

sed -i -e "s/From/To/gw /tmp/sed.done" file_name
grep --color -e "To" /tmp/sed.done

দ্রষ্টব্য, ডাব্লু এবং এর ফাইলের নামের মধ্যে একটি মাত্র স্থান থাকতে হবে ।

এটি ডিফের চেয়ে আরও ভাল, কারণ বিযুক্তকরণগুলি সেড দ্বারা না করেও পরিবর্তনগুলি প্রদর্শন করতে পারে।


কেবল এটি পরীক্ষিত হয়েছে এবং সেড কেবল পরিবর্তিত লাইনগুলি লিখে দেয় sed.done। মূল ফাইলে "তো" দিয়ে রেখাগুলি মুদ্রিত হয় না sed.done, সুতরাং আপনি যখন grep "To" sed.doneকেবলমাত্র সেই রেখাগুলি দেখতে পাবেন যেগুলি পরিবর্তিত হয়েছে sed। আপনি প্রতিস্থাপনের আগে ফাইলটিতে মূল লাইনটি দেখতে পাবেন না , যদি আপনি এটি লক্ষ্য রেখে
চলেছেন

1

আমি @terdon সমাধানটি পছন্দ করি - পার্ল এটির জন্য ভাল।

আমার টুইটের সংস্করণটি এখানে:

  • ম্যাচের স্ট্রিং না থাকা ফাইলগুলিকে পরিবর্তন করার চেষ্টা করবে না
  • যে ফাইলগুলি পরিবর্তন হয় তার আগের সংস্করণটির ব্যাকআপ নেবে (একটি .bak সংস্করণ তৈরি করুন)
  • পরিবর্তিত প্রতিটি ফাইল / লিনেনো তালিকাভুক্ত করবে এবং সহজ পঠনের জন্য এই লাইনের ওল্ড এবং নতুন সংস্করণটি ইন্টেন্টেড এবং নীচে দেখানো হবে

কোড

find /tmp/test -type f ! -name "*.bak" -exec grep -l '/opt/gridmon' {} \; | xargs -L1 perl -ni'.bak' -e'$old=$_; s/\/opt\/gridmon/~/g && print STDERR "$ARGV($.):\n\tOLD:$old\tNEW:$_"'

উদাহরণ আউটপুট

/tmp/test/test4.cfg(13):
    OLD:    ENVFILE /opt/gridmon/server/etc/gridmonserver.cfg
    NEW:    ENVFILE ~/server/etc/gridmonserver.cfg
/tmp/test/test4.cfg(24):
    OLD:    ENVFILE /opt/gridmon/server/etc/gridmonserver.cfg
    NEW:    ENVFILE ~/server/etc/gridmonserver.cfg
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.