سؤال البحث عن واستبدال النص داخل ملف باستخدام الأوامر


كيف يمكنني العثور على كلمات معينة واستبدالها في ملف نصي باستخدام سطر الأوامر؟


437
2018-01-07 04:10


الأصل


نرجو من اهتمامك github.com/lucio-martinez/rch :-) - Lucio


الأجوبة:


sed -i 's/original/new/g' file.txt

تفسير:

  • sed = تيار المحرر
  • -i = في المكان (أي الحفظ إلى الملف الأصلي)
  • سلسلة الأوامر:

    • s = الأمر البديل
    • original = تعبير عادي يصف الكلمة لاستبدالها (أو الكلمة نفسها فقط)
    • new = النص ليحل محله
    • g = عالمي (أي استبدال الكل وليس التواجد الأول فقط)
  • file.txt = اسم الملف


728
2018-01-07 04:23



mcExchange إذا كان على وجه التحديد / شخصية تحتاج إلى مطابقتها ، يمكنك فقط استخدام بعض الأحرف الأخرى كفاصل (على سبيل المثال ، 's_old/text_new/text_g'). خلاف ذلك ، يمكنك وضع \  قبل أي من $ * . [ \ ^ للحصول على الشخصية الحرفية. - cscarney
BrianZ بقدر ما تشعر نظام الملفات بالقلق من إخراج سيد هو ملف جديد يحمل نفس الاسم. انها واحدة من الأخطاء الشائعة التي لا تعتبر أخطاء - cscarney
قد ترغب s/\boriginal\b/new/g بدلا من s/original/new/g (\b يتطابق مع حدود الكلمات) ليحل محل الكلمات الكاملة فقط. - Chris Martin
قيادة OSX sed -i '.bak' 's/original/new/g' file.txt يمكن أيضًا تشغيلها بامتداد صفري الطول sed -i '' 's/original/new/g' file.txt، والتي لن تولد أي نسخة احتياطية. - Kirk
سيضطر مستخدمو MacOS إلى إضافة '' 'بعد -i كمعلمة لـ -i ed.gs/2016/01/26/os-x-sed-invalid-command-code بحيث يتم الكتابة فوق الملف. - geoyws


هناك عدد من الطرق المختلفة للقيام بذلك. واحد يستخدم sed و Regex. SED هو محرر دفق لتصفية وتحويل النص. أحد الأمثلة على ما يلي:

marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orly
marco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarly
marco@imacs-suck: ~$ cat yarly
The quick brown unicorn jumped over the hyper sleeping dog

طريقة أخرى قد تكون أكثر منطقية من < strin و > strout مع الأنابيب!

marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowai
marco@imacs-suck: ~$ cat nowai 
The quick brown fox jumped over the lazy sleeping dog

26
2018-01-07 04:26



لاحظ ال cat في cat file | sed '...' غير ضروري. يمكنك القول مباشرة sed '...' file. - fedorqui
في الواقع يمكن تقليل هذا أكثر: sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarly سيستغرق الملف yarly والقيام بالتغييرات 2 في مكان في حين عمل نسخة احتياطية. عن طريق time bash -c "$COMMAND" إلى الوقت يقترح أن هذا الإصدار هو أسرع 5 مرات. - pbhj


يمكنك استخدام Vim in Ex mode:

ex -sc '%s/OLD/NEW/g|x' file
  1. % اختر جميع الخطوط

  2. s استبدل

  3. g استبدل كل المثيلات في كل سطر

  4. x الكتابة إذا تم إجراء تغييرات (لديهم) والخروج


15
2018-04-16 18:36





من خلال أمر gsub awk ،

awk '{gsub(/pattern/,"replacement")}' file

مثال:

awk '{gsub(/1/,"0");}' file

في المثال أعلاه ، يتم استبدال كل الأعداد بـ 0 بصرف النظر عن العمود الذي يقع فيه.


إذا كنت تريد إجراء استبدال على عمود محدد ، فافعل ذلك ،

awk '{gsub(/pattern/,"replacement",column_number)}' file

مثال:

awk '{gsub(/1/,"0",$1);}' file

يستبدل 1 مع 0 في العمود 1 فقط.

عبر بيرل

$ echo 'foo' | perl -pe 's/foo/bar/g'
bar

14
2017-07-02 12:59



اعتدت على هذا في محطة MacOS ولم يفعل شيئا ... - Jim


هناك العديد من الطرق لتحقيق ذلك. واعتمادًا على مدى تعقيد ما يحاول تحقيقه باستخدام استبدال السلسلة ، واعتمادًا على الأدوات التي يكون المستخدم مألوفًا بها ، قد تكون بعض الطرق المفضلة أكثر من غيرها.

في هذا الجواب أنا باستخدام بسيط input.txt الملف ، والذي يمكنك استخدامه لاختبار جميع الأمثلة المقدمة هنا. محتويات الملف:

roses are red , violets are blue
This is an input.txt and this doesn't rhyme

سحق

لا تعني Bash معالجة النصوص ، ولكن يمكن إجراء عمليات استبدال بسيطة عبر توسيع المعلمة ، على وجه الخصوص هنا يمكننا استخدام بنية بسيطة ${parameter/old_string/new_string}.

#!/bin/bash
while IFS= read -r line
do
    case "$line" in
       *blue*) printf "%s\n" "${line/blue/azure}" ;;
       *) printf "%s\n" "$line" ;;
    esac
done < input.txt

لا يقوم هذا النص الصغير باستبدال في المكان ، مما يعني أنه سيكون عليك حفظ نص جديد إلى ملف جديد ، والتخلص من الملف القديم ، أو mv new.txt old.txt

ملاحظة جانبية: إذا كنت مهتمًا بالسبب while IFS= read -r ; do ... done < input.txt يستخدم ، انها في الأساس قذيفة في طريقة قراءة ملف خط سطرا. نرى هذه كمرجع.

AWK

AWK ، كونها أداة معالجة النصوص ، مناسبة تماما لمثل هذه المهمة. يمكن أن تفعل بدائل بسيطة وأكثر تقدما منها على أساس التعبيرات العادية. يوفر وظيفتين: sub() و gsub(). يستبدل الأول فقط فقط التواجد الأول ، بينما يستبدل الثاني فقط الأحداث في السلسلة بأكملها. على سبيل المثال ، إذا كان لدينا سلسلة one potato two potato ، هذه ستكون النتيجة:

$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'
one banana two banana

$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1'                                      
one banana two potato 

يمكن لـ AWK أن يأخذ ملف الإدخال كحجة ، لذلك تفعل نفس الأشياء input.txt ، سيكون من السهل:

awk '{sub(/blue/,"azure")}1' input.txt

استنادًا إلى إصدار AWK لديك ، قد يكون أو لا يكون في موضع التحرير ، وبالتالي فإن الممارسة المعتادة هي حفظ واستبدال النص الجديد. على سبيل المثال شيء من هذا القبيل:

awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt

SED

سيد هو محرر خط. كما أنه يستخدم تعبيرات عادية ، ولكن بالنسبة للبدائل البسيطة ، يكفي القيام بما يلي:

sed 's/blue/azure/' input.txt

ما هو جيد في هذه الأداة هو أنه يحتوي على التحرير الموضعي ، والذي يمكنك تمكينه -i العلم.

بيرل

Perl أداة أخرى تستخدم غالباً لمعالجة النصوص ، ولكنها لغة عامة الغرض ، وتستخدم في الشبكات وإدارة الأنظمة وتطبيقات سطح المكتب والعديد من الأماكن الأخرى. اقترضت الكثير من المفاهيم / الميزات من اللغات الأخرى مثل C و sed و awk وغيرها. يمكن إجراء الاستبدال البسيط على النحو التالي:

perl -pe 's/blue/azure/' input.txt

مثل سيد ، بيرل أيضا لديه علم -i.

الثعبان

هذه اللغة متعددة الاستخدامات وتستخدم أيضًا في مجموعة متنوعة من التطبيقات. لديها الكثير من الوظائف للعمل مع السلاسل ، من بينها replace()، لذلك إذا كان لديك متغير مثل var="Hello World" ، يمكنك القيام به var.replace("Hello","Good Morning")

طريقة بسيطة لقراءة الملف واستبدال السلسلة فيه ستكون كما يلي:

python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt

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

#!/usr/bin/env python
import sys
import os
import tempfile

tmp=tempfile.mkstemp()

with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2:
    for line in fd1:
        line = line.replace('blue','azure')
        fd2.write(line)

os.rename(tmp[1],sys.argv[1])

هذا السيناريو هو ليتم استدعاؤه input.txt كوسيطة سطر أوامر.

يمكن أن تحتوي بايثون أيضًا على تعبيرات عادية ، على وجه الخصوص ، هناك re الوحدة ، والتي لديها re.sub() وظيفة ، والتي يمكن استخدامها لبدائل أكثر تقدما.


12
2018-02-03 07:49





sed هل الصورةtream إدitor، في ذلك يمكنك استخدامها | (الأنابيب) لإرسال تيارات القياسية (STDIN و STDOUT على وجه التحديد) من خلال sed وتغييرها برمجيًا على الطاير ، مما يجعلها أداة مفيدة في تقليد فلسفة يونكس ؛ ولكن يمكن تحرير الملفات مباشرة ، أيضا ، باستخدام -i المعلمة المذكورة أدناه.
النظر في ما يلي:

sed -i -e 's/few/asd/g' hello.txt

s/ يستخدم ل الصورةubstitute التعبير وجدت few مع asd:

القلة ، الشجعان.


Thed ، الشجعان.

/g لتقف على "عالمي" ، وهذا يعني أن تفعل هذا للخط بأكمله. إذا تركت /g (مع s/few/asd/، هناك دائما حاجة إلى أن تكون ثلاثة مائلة مهما كانت) و few يظهر مرتين على نفس السطر ، فقط الأول few يتم تغيير إلى asd:

الرجال القلائل ، النساء القلائل ، الشجعان.


الرجال asd ، وعدد قليل من النساء ، والشجعان.

وهذا مفيد في بعض الحالات ، مثل تغيير الأحرف الخاصة عند بدايات الخطوط (على سبيل المثال ، استبدال الرموز التي يستخدمها بعض الأشخاص بدلاً من اقتباس المادة السابقة في سلاسل رسائل البريد الإلكتروني بعلامة التبويب الأفقية مع ترك عدم المساواة الجبرية المقتبسة لاحقًا في السطر لم يمسها أحد) ، ولكن في المثال الذي حددت فيه ذلك في أى مكان  few يحدث يجب استبداله ، تأكد من أن لديك ذلك /g.

يتم الجمع بين الخيارين التاليين (الأعلام) في واحد ، -ie:

-i يستخدم الخيار لتحرير أنان مكان على الملف hello.txt.

-e الخيار يشير إلى البريدxpression / الأمر للتشغيل ، في هذه الحالة s/.

ملاحظة: من المهم أن تستخدمها -i -e للبحث / استبدال. اذا فعلت -ie، يمكنك إنشاء نسخة احتياطية من كل ملف مع إلحاق الحرف "e".


6
2017-11-23 09:00





يمكنك فعل هذا على النحو التالي:

locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g" 

أمثلة: لاستبدال كل التكرارات [logdir '،' '] (بدون []) بـ [logdir'، os.getcwd ()] في كل الملفات التي تنتج عن أمر تحديد الموقع ، قم بما يلي:

locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"

حيث [tensorboard / program.py] هو ملف للبحث


0
2017-07-24 02:13



مرحبا. اختيارك من الاوتار (logdir', '' -> /logdir', os.getcwd()) يجعل هذه الإجابة صعبة التحليل. أيضًا ، من الجدير تحديد أن إجابتك تحدد أولاً الملفات التي تستخدمها ، لأنها ليست جزءًا من السؤال. - mwfearnley
مرحبًا ، هذه الإجابة عبارة عن بحث واستبدال الكل إذا وجدت <النص القديم> في الملف. - Nguyễn Tuấn Anh
اخترت هذه الإجابة لكل ما يستخدمونه tensorboard في keras ، الذين يريدون تغيير الأمر من: tensorboard --logdir = '/ path / to / log / folder /' للاستخدام: tensorboard فقط ، عند البقاء في مجلد السجلات. هذا مناسب جدا - Nguyễn Tuấn Anh