كيف يمكنني العثور على واستبدال كلمات معينة في ملف نصي باستخدام سطر الأوامر?
sed -i 's/original/new/g' file.txt
الشرح:
-
sed
= محرر تيار -
-i
= في المكان (أي حفظ مرة أخرى إلى الملف الأصلي) -
سلسلة الأوامر:
-
s
= الأمر البديل -
original
= تعبير عادي يصف الكلمة المراد استبدالها (أو الكلمة نفسها فقط) -
new
= النص ليحل محله مع -
g
= عالمي (أي استبدال الكل وليس فقط التكرار الأول)
-
file.txt
= اسم الملف
هناك العديد من الطرق لتحقيق ذلك. اعتمادا على مدى تعقيد ما يحاول المرء تحقيقه باستبدال السلسلة ، واعتمادا على الأدوات التي يكون المستخدم مألوفا بها ، قد يتم تفضيل بعض الطرق أكثر من غيرها.
في هذه الإجابة أنا باستخدام بسيطة input.txt
ملف ، والتي يمكنك استخدامها لاختبار جميع الأمثلة المقدمة هنا. محتويات الملف:
roses are red , violets are blueThis is an input.txt and this doesn't rhyme
باش
باش ليس المقصود حقا لمعالجة النصوص، ولكن يمكن أن يتم بدائل بسيطة عن طريق توسيع المعلمة ، على وجه الخصوص هنا يمكننا استخدام بنية بسيطة ${parameter/old_string/new_string}
.
#!/bin/bashwhile IFS= read -r linedo case "$line" in *blue*) printf "%s\n" "${line/blue/azure}" ;; *) printf "%s\n" "$line" ;; esacdone < input.txt
لا يقوم هذا البرنامج النصي الصغير باستبدال موضعي ، مما يعني أنه سيتعين عليك حفظ نص جديد في ملف جديد ، والتخلص من الملف القديم ، أو mv new.txt old.txt
ملاحظة جانبية: إذا كنت مهتما بالسبب while IFS= read -r ; do ... done < input.txt
يستخدم ، انها في الأساس طريقة قذيفة لقراءة خط الملف عن طريق الخط. انظر هذا كمرجع.
أوك
أوك ، كونه أداة معالجة النصوص ، هو مناسب تماما لهذه المهمة. يمكن أن تفعل بدائل بسيطة وأخرى أكثر تقدما على أساس التعبيرات العادية. يوفر وظيفتين: 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
أوك يمكن أن تأخذ ملف الإدخال كوسيطة، لذلك تفعل نفس الأشياء مع input.txt
، سيكون من السهل:
awk '{sub(/blue/,"azure")}1' input.txt
اعتمادا على إصدار أوك لديك ، قد أو قد لا يكون التحرير في مكان ، وبالتالي فإن الممارسة المعتادة هي حفظ واستبدال النص الجديد. على سبيل المثال شيء من هذا القبيل:
awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt
سيد
سيد هو محرر خط. كما أنه يستخدم التعبيرات العادية ، ولكن بالنسبة للبدائل البسيطة ، يكفي القيام بذلك:
sed 's/blue/azure/' input.txt
ما هو جيد حول هذه الأداة هو أن لديها التحرير في المكان ، والتي يمكنك تمكين مع -i
علم.
بيرل
بيرل هو أداة أخرى والتي غالبا ما تستخدم لمعالجة النصوص ، ولكنها لغة للأغراض العامة ، ويستخدم في الشبكات ، وإدارة النظام ، وتطبيقات سطح المكتب ، والعديد من الأماكن الأخرى. اقترضت الكثير من المفاهيم/الميزات من لغات أخرى مثل ج ، سيد ، أوك ، وغيرها. يمكن إجراء استبدال بسيط على النحو التالي:
perl -pe 's/blue/azure/' input.txt
مثل سيد ، بيرل أيضا العلم ط.
بايثون
هذه اللغة متعددة الاستخدامات وتستخدم أيضا في مجموعة متنوعة من التطبيقات. لديها الكثير من الوظائف للعمل مع السلاسل، من بينها 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 pythonimport sysimport osimport tempfiletmp=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
كوسيطة سطر الأوامر. الأمر الدقيق لتشغيل البرنامج النصي بيثون مع وسيطة سطر الأوامر سيكون
$ ./myscript.py input.txt
أو
$ python ./myscript.py input.txt
بالطبع ، تأكد من ذلك ./myscript.py
هو في دليل العمل الحالي الخاص بك وللطريقة الأولى ، تأكد من تعيين قابل للتنفيذ مع chmod +x ./myscript.py
بيثون يمكن أن يكون أيضا التعبيرات العادية ، على وجه الخصوص، هناك re
الوحدة ، التي لديها re.sub()
وظيفة ، والتي يمكن استخدامها لاستبدال أكثر تقدما.
هناك عدد من الطرق المختلفة للقيام بذلك. واحد يستخدم sed
والتعبير العادي. سيد هو محرر تيار لتصفية وتحويل النص. مثال واحد هو كما يلي:
marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orlymarco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarlymarco@imacs-suck: ~$ cat yarlyThe quick brown unicorn jumped over the hyper sleeping dog
طريقة أخرى قد تكون أكثر منطقية من < strin
و > strout
هو مع الأنابيب!
marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowaimarco@imacs-suck: ~$ cat nowai The quick brown fox jumped over the lazy sleeping dog
من خلال قيادة غسوب أوك,
awk '{gsub(/pattern/,"replacement")}' file
مثال:
awk '{gsub(/1/,"0");}' file
في المثال أعلاه ، يتم استبدال جميع 1 من قبل 0 بغض النظر عن العمود حيث يقع.
إذا كنت تريد أن تفعل بديل على عمود معين، ثم تفعل مثل هذا,
awk '{gsub(/pattern/,"replacement",column_number)}' file
مثال:
awk '{gsub(/1/,"0",$1);}' file
يستبدل 1 بـ 0 في العمود الأول فقط.
من خلال بيرل,
$ echo 'foo' | perl -pe 's/foo/bar/g'bar