it-swarm.asia

العثور على واستبدالها في ملف والكتابة فوق الملف لا يعمل ، فإنه يفرغ الملف

أرغب في تشغيل بحث واستبدال ملف HTML من خلال سطر الأوامر.

تبدو أمري مثل هذا:

sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html > index.html

عندما أقوم بتشغيل هذا وإلقاء نظرة على الملف بعد ذلك ، فإنه فارغ. حذف محتويات ملفي.

عندما أقوم بتشغيل هذا بعد استعادة الملف مرة أخرى:

sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html

stdout هي محتويات الملف ، وتم تنفيذ عملية البحث والاستبدال.

لماذا يحدث هذا؟

570
BBales

عندما يقوم Shell يرى > index.html في سطر الأوامر ، فإنه يفتح الملف index.html لـ كتابة ، محو جميع محتوياته السابقة.

لإصلاح هذا الأمر ، يتعين عليك تمرير الخيار -i إلى sed لإجراء التغييرات في السطر وإنشاء نسخة احتياطية من الملف الأصلي قبل إجراء التغييرات في مكانها:

sed -i.bak s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html

بدون .bak ، سيفشل الأمر في بعض الأنظمة الأساسية ، مثل Mac OSX.

874
codaddict

بديل ، مفيد ، هو نمط:

sed -e 'script script' index.html > index.html.tmp && mv index.html.tmp index.html

هذا له نفس التأثير إلى حد كبير ، دون استخدام الخيار -i ، ويعني بالإضافة إلى ذلك أنه إذا فشل البرنامج النصي sed لسبب ما ، فإن ملف الإدخال لا يتم تجميعه. علاوة على ذلك ، إذا كان التعديل ناجحًا ، فلن يتبقى ملف نسخ احتياطي. يمكن أن يكون هذا النوع من المصطلحات مفيدًا في Makefiles.

يحتوي الكثير من المخدرات على خيار -i ، ولكن ليس جميعهم ؛ و sedix هو واحد الذي لا. إذا كنت تهدف إلى قابلية النقل ، فمن الأفضل تجنبه.

201
Norman Gray
sed -i 's/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' index.html

يقوم هذا باستبدال عام في مكان على ملف index.html. نقلاً عن السلسلة يمنع مشاكل المسافة البيضاء في الاستعلام والاستبدال.

86
Rich Apodaca

استخدم خيار sed's -i ، على سبيل المثال.

sed -i bak -e s/STRING_TO_REPLACE/REPLACE_WITH/g index.html
56
Kevin

لتغيير ملفات متعددة (وحفظ نسخة احتياطية لكل منها كـ * .bak):

Perl -p -i -e "s/\|/x/g" *  

سيأخذ جميع الملفات في الدليل ويستبدل | بـ x وهذا ما يسمى بـ "Perl pie" (سهل مثل دائري)

18
Stenemo

يجب أن تحاول استخدام الخيار -i للتحرير الموضعي.

14
uloBasEI
sed -i.bak "s#https.*\.com#$pub_url#g" MyHTMLFile.html

إذا كان لديك رابط لإضافته ، فجرب هذا. ابحث عن عنوان URL كما هو مذكور أعلاه (بدءًا من https ثم ينتهي بـ.com هنا) واستبدله بسلسلة URL. لقد استخدمت متغير $pub_url هنا. s هنا تعني البحث و g تعني الاستبدال الشامل.

إنها تعمل !

6
Kaey

تحذير: هذه طريقة خطيرة! يسيء إلى المخازن المؤقتة للإدخال/الإخراج في نظام التشغيل Linux ومع وجود خيارات محددة للتخزين المؤقت ، يمكنه العمل على الملفات الصغيرة. إنه فضول مثير للاهتمام. لكن لا تستخدمه في موقف حقيقي!

إلى جانب خيار -i الخاص بـ sed ، يمكنك استخدام tee الأداة المساعدة.

من man:

كوم - قراءة من المدخلات القياسية والكتابة إلى الإخراج والملفات القياسية

لذلك ، سيكون الحل:

sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee | tee index.html

- هنا يتم تكرار tee للتأكد من تخزين خط الأنابيب. ثم يتم حظر جميع الأوامر في خط الأنابيب حتى يحصلوا على بعض المدخلات للعمل عليها. يبدأ كل أمر في خط الأنابيب عندما تكون أوامر upstream قد كتبت مخزن مؤقت واحد للبايت (يتم تعريف الحجم في مكان ما ) لإدخال الأمر. لذا فإن الأمر الأخير tee index.html ، الذي يفتح الملف للكتابة وبالتالي يفرغ منه ، يعمل بعد انتهاء خط أنابيب المنبع والإخراج في المخزن المؤقت داخل خط الأنابيب.

على الأرجح لن يعمل ما يلي:

sed s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html | tee index.html

- سيتم تشغيل كلا الأمرين لخط الأنابيب في نفس الوقت دون أي حظر. (بدون حظر ، يجب أن يمر خط الأنابيب بخط البايت سطراً بدلاً من المخزن المؤقت بواسطة المخزن المؤقت. كما هو الحال عند تشغيل cat | sed s/bar/GGG/. دون حظر ، يكون أكثر تفاعلية وعادة ما يتم تشغيل خطوط الأنابيب من أمرين فقط دون تخزين مؤقت وحجب. يتم تخزين خطوط الأنابيب الأطول.) tee index.html سيفتح الملف للكتابة وسيتم إفراغه. ومع ذلك ، إذا قمت بتشغيل التخزين المؤقت دائمًا ، فستعمل النسخة الثانية أيضًا.

4
xealits

المشكلة مع الأمر

sed 'code' file > file

هو أن file يتم اقتطاعها من قِبل Shell قبل أن يتمكن sed من معالجتها بالفعل. نتيجة لذلك ، تحصل على ملف فارغ.

طريقة sed للقيام بذلك هي استخدام -i للتعديل في المكان ، كما اقترحت الإجابات الأخرى. ومع ذلك ، هذا ليس دائما ما تريد. سيقوم -i بإنشاء ملف مؤقت سيتم استخدامه بعد ذلك لاستبدال الملف الأصلي. هذا مشكلة إذا كان الملف الأصلي رابطًا (سيتم استبدال الرابط بملف عادي). إذا كنت بحاجة إلى الحفاظ على الروابط ، يمكنك استخدام متغير مؤقت لتخزين إخراج sed قبل إعادة كتابته مرة أخرى إلى الملف ، مثل هذا:

tmp=$(sed 'code' file); echo -n "$tmp" > file

الأفضل من ذلك ، استخدم printf بدلاً من echo لأن echo من المحتمل أن تعالج \\ كـ \ في بعض الأصداف (على سبيل المثال ، الشرطة):

tmp=$(sed 'code' file); printf "%s" "$tmp" > file
4
Andrzej Pronobis

والإجابة ed:

printf "%s\n" '1,$s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g' w q | ed index.html

لتكرار ما أجابه codaddict ، تعالج Shell إعادة التوجيه أولاً ، محو ملف "input.html" ، و {ثم تستدعي Shell أمر "sed" المار انها ملف فارغ الآن.

3
glenn jackman

يمكنك استخدام Vim في وضع Ex:

ex -sc '%s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g|x' index.html
  1. % حدد جميع الخطوط

  2. x حفظ وإغلاق

2
Steven Penny

كنت أبحث عن الخيار حيث يمكنني تحديد نطاق السطر والعثور على الإجابة. على سبيل المثال ، أريد تغيير Host1 إلى Host2 من السطر 36-57.

sed '36,57 s/Host1/Host2/g' myfile.txt > myfile1.txt

يمكنك استخدام خيار gi أيضًا لتجاهل حالة الأحرف.

sed '30,40 s/version/story/gi' myfile.txt > myfile1.txt
0
user8117884

مع كل الاحترام الواجب للإجابات الصحيحة المذكورة أعلاه ، من الأفضل دائمًا "نصوص التشغيل الجاف" من هذا القبيل ، بحيث لا تفسد ملفك ويجب أن تبدأ من جديد من البداية.

ما عليك سوى الحصول على البرنامج النصي لإخراج الإخراج إلى سطر الأوامر بدلاً من كتابته إلى الملف ، على سبيل المثال ، مثل:

sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g index.html

OR

less index.html | sed -e s/STRING_TO_REPLACE/STRING_TO_REPLACE_IT/g 

وبهذه الطريقة يمكنك رؤية والتحقق من إخراج الأمر دون الحصول على الملف الخاص بك مبتوراً.

0
Nestor Milyaev