প্রতিটি প্রতিস্থাপনের আগে আমাকে কি নিশ্চিতকরণের জন্য জিজ্ঞাসা করার জন্য কোনও উপায় আছে? ভিএম এর ভিতরে প্রতিস্থাপন ব্যবহার করার সময় 'সি' এর মতো কিছু।
সেড কি আদৌ এটা করে?
প্রতিটি প্রতিস্থাপনের আগে আমাকে কি নিশ্চিতকরণের জন্য জিজ্ঞাসা করার জন্য কোনও উপায় আছে? ভিএম এর ভিতরে প্রতিস্থাপন ব্যবহার করার সময় 'সি' এর মতো কিছু।
সেড কি আদৌ এটা করে?
উত্তর:
এটি sed
একটি আন্তঃ-ইন্টারেক্টিভ স্ট্রিম সম্পাদক হিসাবে সম্ভবত এটি করা সম্ভব হবে না। sed
স্ক্রিপ্টে জড়ানোর জন্য অনেক বেশি চিন্তাভাবনা প্রয়োজন। এটি দিয়ে এটি করা সহজ vim
:
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' file.in
যেহেতু এটি নীচে মন্তব্যে উল্লিখিত ছিল, এখানে বর্তমান ডিরেক্টরিতে কোনও নির্দিষ্ট ফাইলের নাম গ্লোব্বিং প্যাটার্ন মিলিয়ে একাধিক ফাইলে কীভাবে এটি ব্যবহার করা হবে তা এখানে:
for fname in file*.txt; do
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done
বা, আপনি যদি প্রথমে নিশ্চিত করতে চান যে ফাইলটিতে সত্যই একটি রেখা রয়েছে যা প্রতিস্থাপনের আগে প্রথমে প্রদত্ত প্যাটার্নের সাথে মেলে,
for fname in file*.txt; do
grep -q 'PATTERN' "$fname" &&
vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done
উপরের দুটি শেল লুপগুলি find
কমান্ডে পরিবর্তিত হয়েছে যা একই কাজ করে তবে কোনও ফাইলের জন্য বা নির্দিষ্ট top-dir
ডিরেক্টরিতে কোথাও নির্দিষ্ট নাম সহ সমস্ত ফাইলের জন্য ,
find top-dir -type f -name 'file*.txt' \
-exec vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' {} \;
find top-dir -type f -name 'file*.txt' \
-exec grep -q 'PATTERN' {} \; \
-exec vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' {} \;
অথবা, মূল শেল লুপগুলি ব্যবহার করে এবং find
সেগুলিতে ফিডের পাথের নাম রাখা:
find top-dir -type f -name 'file*.txt' -exec sh -c '
for pathname do
vim -c "%s/PATTERN/REPLACEMENT/gc" -c "wq" "$pathname"
done' sh {} +
find top-dir -type f -name 'file*.txt' -exec sh -c '
for pathname do
grep -q "PATTERN" "$pathname" &&
vim -c "%s/PATTERN/REPLACEMENT/gc" -c "wq" "$pathname"
done' sh {} +
আপনি কোনও অবস্থাতেই করুন, যেহেতু কিছু করতে চান নাfor filename in $( grep -rl ... )
grep
লুপের প্রথম পুনরাবৃত্তি শুরু করার আগেই শেষ হওয়া দৌড়াদৌড়ি করা দরকার , যা নিষ্ক্রিয় andgrep
আসা পাথের নামগুলি হোয়াইটস্পেসে শব্দের মধ্যে বিভক্ত করা হত এবং এই শব্দগুলি ফাইলের নামটি গ্লোব্বিংয়ের মধ্য দিয়ে যাবে (এটি স্পেস এবং বিশেষ অক্ষর ধারণ করে এমন পাথের নাম অযোগ্য করে দেয়)।সম্পর্কিত:
sed
হ'ল এটি একাধিক ফাইলগুলিতে অপারেট করতে পারে, যেমন, sed -i 's/old/new/g' /path/to/*.txt
বা অনুরূপ কিছু similar
for i in $(grep -rl "old"); do vim -c "%s/old/new/gc" -c "wq" "$i"; done
আপনি এটি করে এটি পেতে পারেন:
:%s/OLD_TEXT/NEW_TEXT/gc
বিশেষত, c
তৃতীয় সীমানাটির পরে যুক্ত করা ।
মনে রাখবেন যে 'সি' বিকল্পটি কেবল ভিমে কাজ করে; আপনি sed
কমান্ড লাইনে এটি ব্যবহার করতে সক্ষম হবেন না ।
sed
।
vim
, সুতরাং এই উত্তর প্রযোজ্য; যদিও, স্পষ্টত
আপনি sed
ফাইলটিতে এটি করার অনুমতি দিতে পারেন এবং তারপরে ফলটিকে একটি অস্থায়ী ফাইলে সংরক্ষণ করতে পারেন যা তারপরে ইন্টারেক্টিভভাবে মূল ফাইলটিতে প্যাচ করতে পারেন sdiff
(দেখুন http://www.gnu.org/software/diffutils/manual/diffutils.html # ইনভোকিং-এসডিফ ):
sed -r 's/something/something_else/g' my_file > tmp_file
sdiff -o my_file -s -d my_file tmp_file
searchandreplace () {
if [ -z $2 ] ; then
realpath * | xargs grep -ins --directories=skip --color=always "$1" | nl -s "."
else
realpath * | xargs grep -ins --directories=skip --color=always "$1" | nl -s "."
exp=$(realpath * | xargs grep -ins --directories=skip --color=never "$1" | cut -d':' -f1,2 | awk -F':' '{print $2 $1}' | sed -E "s|^[0-9]+|sed -i \'&s/|; s|//|/"$1"/"$2"/g\' /|")
IFS=$'\n'
for d in $exp
do
read -p "Exec $(echo -e -n "\033[1;31m$d\033[0m")? " -e REP
if [ "$REP" = y ]; then
echo `bash -c $d`;
fi
done
fi
}
আপনি যদি searchandreplace "AAA"
এটি একক যুক্তি দিয়ে খাওয়ান - - এটি কেবল বর্তমান ডিরেক্টরিতে সেই স্ট্রিংটি অনুসন্ধান করে, তবে আপনি যদি এটি দ্বৈত যুক্তি দিয়ে খাওয়াতে থাকেন searchandreplace AAA BBB
- তবে উপরের সাথে এটি আপনাকে দ্বিতীয়টি "রেখার সাথে প্রথমটি প্রতিস্থাপন করতে বলেছে" প্রতিটি লাইন জন্য "লাইন।