आदेश का उपयोग करके किसी फ़ाइल के भीतर पाठ ढूंढें और प्रतिस्थापित करें


जवाबों:


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

स्पष्टीकरण:

  • sed = स्ट्रीम एडिटर
  • -i = इन-प्लेस (यानी मूल फ़ाइल पर वापस सहेजें)
  • कमांड स्ट्रिंग:

    • s = स्थानापन्न आज्ञा
    • original = शब्द को प्रतिस्थापित करने के लिए एक नियमित अभिव्यक्ति (या केवल स्वयं शब्द)
    • new = इसे बदलने के लिए पाठ
    • g = वैश्विक (अर्थात सभी को बदलें और केवल पहली घटना नहीं)
  • file.txt = फ़ाइल का नाम


3
@ अकिवा यदि आप अपनी खोज में regex विशेष वर्णों को शामिल करते हैं, तो sedउनका मिलान होगा। -rयदि आप इसके बजाय विस्तारित REs का उपयोग करना चाहते हैं तो एक ध्वज जोड़ें ।
सीएसकेनी 12

32
@mcExchange यदि यह विशेष रूप से ऐसा /चरित्र है जिसे आपको मिलान करने की आवश्यकता है, तो आप विभाजक के रूप में कुछ अन्य वर्ण का उपयोग कर सकते हैं (जैसे 's_old/text_new/text_g')। अन्यथा, आप शाब्दिक चरित्र प्राप्त करने के लिए \ किसी के भी सामने रख सकते हैं $ * . [ \ ^
cscarney

3
@BrianZ जहाँ तक फ़ाइल सिस्टम का संबंध है, sed का आउटपुट उसी नाम से एक नई फ़ाइल है। यह आमतौर पर रिपोर्ट किए जाने वाले बग्स
सीएससी

16
OSX कमांड sed -i '.bak' 's/original/new/g' file.txtको शून्य-लंबाई एक्सटेंशन के साथ भी चलाया जा सकता है sed -i '' 's/original/new/g' file.txt, जो बिना बैकअप के उत्पन्न होगा।
कर्क

19
MacOS उन '' "मैं के बाद मैं के लिए एक पैरामीटर के रूप में जोड़ने के लिए होगा ed.gs/2016/01/26/os-x-sed-invalid-command-code ताकि फ़ाइल ओवरराइट किया जाएगा।
geoyws

32

ऐसा करने के लिए कई अलग-अलग तरीके हैं। एक का उपयोग कर रहा है sedऔर रेगेक्स। 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

6
ध्यान दें catमें cat file | sed '...'अनावश्यक है। आप सीधे कह सकते हैं sed '...' file
फेडोरक्वी

1
वास्तव में इसे और कम किया जा सकता है: sed -i'.bak' -e 's/unicorn/fox/g;s/hyper/brown/g' yarlyयारी को फ़ाइल करेगा और बैकअप बनाते समय 2 बदलाव इन-प्लेस करेगा। time bash -c "$COMMAND"समय का उपयोग करके यह पता चलता है कि यह संस्करण ~ 5 गुना तेज है।
pbhj

23

इसे प्राप्त करने के तरीकों की भीड़ है। स्ट्रिंग प्रतिस्थापन के साथ कोई भी क्या हासिल करने की कोशिश करता है, इसकी जटिलता पर निर्भर करता है, और उन उपकरणों पर निर्भर करता है जिनके साथ उपयोगकर्ता परिचित है, कुछ तरीकों को दूसरों के लिए अधिक पसंद किया जा सकता है।

इस उत्तर में मैं सरल input.txtफ़ाइल का उपयोग कर रहा हूं , जिसका उपयोग आप यहां दिए गए सभी उदाहरणों का परीक्षण करने के लिए कर सकते हैं। फ़ाइल सामग्री:

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

दे घुमा के

बाश वास्तव में पाठ प्रसंस्करण के लिए नहीं है, लेकिन साधारण प्रतिस्थापन पैरामीटर विस्तार के माध्यम से किया जा सकता है , विशेष रूप से यहां हम सरल संरचना का उपयोग कर सकते हैं ${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 's/blue/azure/' input.txt

इस टूल के बारे में अच्छा है कि इसमें इन-प्लेस एडिटिंग है, जिसे आप -iध्वज के साथ सक्षम कर सकते हैं ।

पर्ल

पर्ल एक और उपकरण है जो अक्सर टेक्स्ट प्रोसेसिंग के लिए उपयोग किया जाता है, लेकिन यह एक सामान्य उद्देश्य की भाषा है, और इसका उपयोग नेटवर्किंग, सिस्टम एडमिनिस्ट्रेशन, डेस्कटॉप ऐप और कई अन्य स्थानों में किया जाता है। इसने अन्य भाषाओं जैसे 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को कमांड-लाइन तर्क के रूप में बुलाया जाना है। कमांड-लाइन तर्क के साथ अजगर स्क्रिप्ट को चलाने के लिए सटीक कमांड होगी

 $ ./myscript.py input.txt

या

$ python ./myscript.py input.txt

बेशक, सुनिश्चित करें कि ./myscript.pyयह आपकी वर्तमान कार्यशील निर्देशिका में है और पहले तरीके से, यह सुनिश्चित करें कि यह निष्पादन योग्य हैchmod +x ./myscript.py

पायथन में नियमित रूप से अभिव्यक्ति भी हो सकती है, विशेष रूप से, इसमें reमॉड्यूल है, जिसमें re.sub()फ़ंक्शन है, जिसका उपयोग अधिक उन्नत प्रतिस्थापन के लिए किया जा सकता है।


1
अच्छा संकलन! यहां उल्लेख नहीं किया गया एक और संभावित तरीका trयूनिक्स में कमांड का उपयोग कर रहा है
तपजीत डे

1
@TapajitDey हाँ, tr एक और महान उपकरण है, लेकिन ध्यान दें कि यह सेट (उदाहरण के लिए वर्णों की जगह के लिए है tr abc cdeअनुवाद होगा aकरने के लिए c, bकरने के लिए dइसके साथ के रूप में पूरे शब्द की जगह से थोड़ा अलग है। sedयाpython
सर्गी Kolodyazhnyy

22

आप पूर्व मोड में विम का उपयोग कर सकते हैं:

ex -s -c '%s/OLD/NEW/g|x' file
  1. % सभी लाइनों का चयन करें

  2. s विकल्प

  3. g प्रत्येक पंक्ति में सभी उदाहरणों को बदलें

  4. x यदि परिवर्तन किए गए हैं (तो वे लिखें) और बाहर निकलें


21

जाग के gsub कमांड के माध्यम से,

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

यह केवल पहले कॉलम पर 0 के साथ 1 को प्रतिस्थापित करता है।

पर्ल के माध्यम से,

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

मैंने मैकओएस टर्मिनल पर इसका इस्तेमाल किया और इसने कुछ नहीं किया ...
जिम

अल्पाइन लिनक्स (
डॉकटर

@ SalathielGenèse आप क्या हासिल करने की कोशिश कर रहे हैं?
अविनाश राज

मैं के साथ फाइल देख रहा हूँ inotifywaitके तहत shenv, और रिपोर्टिंग सीएसवी प्रारूप में डेटा (क्योंकि कस्टम प्रारूप गाड़ी है)। मुझे लगा कि शेल स्क्रिप्ट में CSV दस्तावेज़ को संभालने का कोई सरल तरीका नहीं है ... और मैं इसे बहुत हल्का चाहता हूं। इसलिए मैंने CSV को पार्स करने और रिपोर्ट करने के लिए एक बहुत ही सरल स्क्रिप्ट शुरू की। मैंने CSV कल्पना पढ़ी और देखा कि यह मेरी अपेक्षा से अधिक विस्तृत है और दोहरे उद्धरण चिह्नों में लिपटी बहुस्तरीय मूल्य का समर्थन करता है। मैं sedटोकन के लिए भरोसा कर रहा था, लेकिन जल्द ही एहसास हुआ कि sedकॉल मल्टीलाइन भी दो लाइनों तक है। तब क्या होगा अगर मेरा एक CSV मान दो से अधिक लाइनों पर फैला हो?
सलाथिल जीनस

अपनी समस्या को प्रश्न के रूप में पूछना बेहतर है।
अविनाश राज

8

sedहै रों tream एड itor , कि आप उपयोग कर सकते हैं |भेजने के लिए (पाइप) मानक धाराओं के माध्यम से (STDIN और STDOUT विशेष रूप से) sedऔर उन्हें मक्खी पर प्रोग्राम के रूप में बदल सकता है, यह यूनिक्स दर्शन परंपरा में एक आसान उपकरण बना; लेकिन -iनीचे दिए गए पैरामीटर का उपयोग करके, सीधे भी फ़ाइलों को संपादित कर सकते हैं।
निम्नलिखित पर विचार करें :

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

s/करने के लिए प्रयोग किया जाता है रों पाया अभिव्यक्ति ubstitute fewसाथ asd:

कुछ, बहादुर।


अस्स, बहादुर।

/g"वैश्विक" के लिए खड़ा है, जिसका अर्थ है पूरी लाइन के लिए ऐसा करना। यदि आप एक साथ छोड़ देते हैं /g( s/few/asd/हमेशा, तीन स्लैश कोई फर्क नहीं पड़ता कि क्या होना चाहिए) और fewएक ही पंक्ति में दो बार दिखाई देता है, केवल पहले fewको बदल दिया जाता है asd:

कुछ पुरुष, कुछ महिलाएं, बहादुर।


असद पुरुषों, कुछ महिलाओं, बहादुर।

यह कुछ परिस्थितियों में उपयोगी है, जैसे लाइनों की शुरुआत में विशेष वर्णों में फेरबदल करना (उदाहरण के लिए, उन लोगों की तुलना में अधिक से अधिक प्रतीकों का उपयोग करते हैं जिन्हें कुछ लोग ईमेल थ्रेड में पिछली सामग्री को क्षैतिज टैब के साथ पंक्तिबद्ध बीजगणितीय असमानता के साथ लाइन में छोड़ते हुए उद्धृत करते हैं। अछूता), लेकिन आपके उदाहरण में जहां आप निर्दिष्ट करते हैं कि कहीं भी few होता है इसे प्रतिस्थापित किया जाना चाहिए, सुनिश्चित करें कि आपके पास वह है /g

निम्नलिखित दो विकल्प (झंडे) एक में संयुक्त हैं -ie:

-iविकल्प का उपयोग फ़ाइल पर i n स्थान को संपादित करने के लिए किया जाता है hello.txt

-eविकल्प इस मामले में xpression / कमांड को चलाने का संकेत देता है s/

नोट: यह महत्वपूर्ण है कि आप -i -eखोज / प्रतिस्थापन का उपयोग करें। यदि आप करते हैं -ie, तो आप 'ई' अक्षर के साथ हर फाइल का बैकअप बनाते हैं।


2

आप इस तरह कर सकते हैं:

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

उदाहरण: सभी आवृत्तियों को बदलने के लिए [logdir ',' '] (बिना []] [logdir', os.getcwd ()) के साथ सभी फाइलों में जो कि कमांड का पता लगाने का परिणाम है, करते हैं:

EX1:

locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"

ex2:

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

जहां [टेंसरबोर्ड / प्रोग्राम थिंकपैड] सर्च करने के लिए फाइल है


नमस्ते। तार की आपकी पसंद ( logdir', ''-> /logdir', os.getcwd()) पार्स करने के लिए इस उत्तर को कठिन बनाती है। इसके अलावा, यह निर्दिष्ट करने के लायक है कि आपका जवाब सबसे पहले फाइलों का पता लगाने के लिए sed का उपयोग करता है, क्योंकि यह सवाल का हिस्सा नहीं है।
mwfearnley

नमस्ते, यह उत्तर खोज और प्रतिस्थापित सभी है अगर यह फ़ाइल में <पुराना पाठ> मिला।
गुयेन

मैं यह जवाब उन सभी के लिए चुनता हूं जो किरस में टेंसरबोर्ड का उपयोग करते हैं, जो कमांड को बदलना चाहते हैं: टेंसोरबोर्ड - स्लोगर्ड = '/ पाथ / टू / लॉग / फोल्डर /' का उपयोग करने के लिए: टेंसोरबोर्ड केवल, जब लॉग फ़ोल्डर में रहते हैं। यह बहुत सुविधाजनक है
गुयेन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.