सेड का उपयोग करके स्ट्रिंग वाली पूरी लाइन बदलें


319

मेरे पास एक टेक्स्ट फाइल है जिसमें एक विशेष लाइन है जैसे कुछ

sometext sometext sometext TEXT_TO_BE_REPLACED sometext sometext sometext

मुझे पूरी लाइन को ऊपर से बदलना होगा

This line is removed by the admin.

खोज कीवर्ड है TEXT_TO_BE_REPLACED

मुझे इसके लिए एक शेल स्क्रिप्ट लिखने की जरूरत है। मैं इसका उपयोग करके कैसे प्राप्त कर सकता हूं sed?


@Scharron मैंने sed -rne 's / (TEXT_TO_BE_REPLACED) \ s + \ w + / \ 1 yyy / xxx' की कोशिश की, लेकिन यह सिर्फ स्ट्रिंग में xxx के साथ yyy को बदल देगा यदि कोई भीy मौजूद है। मेरे मामले में पाठ निश्चित नहीं है ... मेरे पास सभी TEXT_TO_BE_REPLACED हैं।
राहुल

यह मान्य sed अभिव्यक्ति नहीं है। क्या आप वाकई इसे सेड के साथ चाहते हैं? अच्छे regexps के साथ कोई भी प्रोग्रामिंग भाषा आपके लिए एक उप-फ़ंक्शन (उप फ़ंक्शन की खोज) कर सकती है। यह अपने आप में
सेड को

@ शचरॉन खैर, यह शेल स्क्रिप्ट के साथ किया जाता है इसलिए मुझे लगता है कि सेड मेरी सबसे अच्छी शर्त है।
राहुल

जवाबों:


483

आप पूरी लाइन को बदलने के लिए परिवर्तन कमांड का उपयोग कर सकते हैं , और -iफ्लैग को इन-प्लेस में बदलने के लिए। उदाहरण के लिए, GNU sed का उपयोग करना:

sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo

4
ध्यान दें कि आपको c \ _ से पहले एक स्थान चाहिए। मैंने अभी इसे जोड़ने के लिए संपादित किया है।
मार्कस डाउनिंग

27
@MarcusDowning GNU sed को स्थान की आवश्यकता नहीं है; यह मूल रूप से पोस्ट के रूप में ठीक काम करता है। यदि आपके विशेष सेड को स्पेस की आवश्यकता है, तो हर तरह से ध्यान दें कि कौन सा सेड असंगत है और टिप्पणी के रूप में आवश्यक इनवोकेशन जोड़ें। हालाँकि, कृपया स्वीकार किए गए उत्तर में कार्य कोड को न बदलें।
टॉड ए। जैकब्स

7
मैं "यह ..." पाठ के बजाय एक चर का उपयोग कैसे कर सकता हूं? यदि मैं इसे $ चर से प्रतिस्थापित करता हूं, तो यह अपनी सामग्री को नहीं बल्कि चर नाम से छापता है।
स्टीवन

18
c\ एक चर के बाद सीधे होने पर समस्या होती है : …c\$VAR…बैकस्लैश डॉलर बच जाएगा। इस मामले में मुझे (Ubuntu 15.10 पर bash / sed) लिखना था…c\\$VAR…
जनवरी

6
एक मैक उपयोग पर sed -i '' '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo:; (जब पहला
पैराम

152

आपको .*पूरी लाइन को बदलने से पहले और बाद में वाइल्डकार्ड ( ) का उपयोग करने की आवश्यकता है :

sed 's/.*TEXT_TO_BE_REPLACED.*/This line is removed by the admin./'

धन्यवाद, मेरा काम कर गया: sed 's /.* <अभिव्यक्ति>। * / <अभिव्यक्ति> SE_LABEL = ABC <अभिव्यक्ति> / g' MYR2.xml> test.txt
Nasri नजीब

9
यह मैक ओएस एक्स योसेमाइट पर इस अपवाद के साथ काम कर रहा है कि मैं -आई और -ई झंडे का उपयोग इस प्रकार कर रहा हूं:sed -i -e "s/.*search_string.*/Replacement_line/' file_being_searched.txt
केंट बुल

1
@KentJohnson मुझे लगता है कि आप अपने आदेश में बेमेल उद्धरण है।
हशहजार्ड

@ MBARnett आप सही हैं, मुझे वहां दो दोहरे उद्धरण होने चाहिए।
केंट बुल

2
बस पूरी जानकारी के लिए। इसे बनाने के लिए कोई भी -iविकल्प जोड़ सकता है
Temak

20

स्वीकृत उत्तर मेरे लिए कई कारणों से काम नहीं आया:

  • मेरे सेड का संस्करण -iशून्य लंबाई विस्तार के साथ पसंद नहीं है
  • c\कमांड का सिंटैक्स अजीब है और मैं इसे काम नहीं कर सका
  • मुझे महसूस नहीं हुआ कि मेरे कुछ मुद्दे अनपेक्षित स्लैश से आ रहे हैं

तो यहाँ समाधान है जो मुझे लगा कि मुझे लगता है कि ज्यादातर मामलों के लिए काम करना चाहिए:

function escape_slashes {
    sed 's/\//\\\//g' 
}

function change_line {
    local OLD_LINE_PATTERN=$1; shift
    local NEW_LINE=$1; shift
    local FILE=$1

    local NEW=$(echo "${NEW_LINE}" | escape_slashes)
    sed -i .bak '/'"${OLD_LINE_PATTERN}"'/s/.*/'"${NEW}"'/' "${FILE}"
    mv "${FILE}.bak" /tmp/
}

तो समस्या का हल करने के लिए नमूना उपयोग:

change_line "TEXT_TO_BE_REPLACED" "This line is removed by the admin." yourFile

18

उपरोक्त उत्तर:

sed -i '/TEXT_TO_BE_REPLACED/c\This line is removed by the admin.' /tmp/foo

ठीक काम करता है अगर प्रतिस्थापन स्ट्रिंग / लाइन एक चर नहीं है।

मुद्दा यह है कि रेडहैट 5 पर भागने के \बाद । एक डबल ने भी काम नहीं किया (कम से कम रेडहैट 5 पर)।c$\\

हिट एंड ट्रायल के माध्यम से, मुझे पता चला कि अतिरेक के \बाद cअगर आपकी रिप्लेसमेंट स्ट्रिंग / लाइन केवल एक ही लाइन है। इसलिए मैंने इसके \बाद उपयोग नहीं cकिया, एकल प्रतिस्थापन लाइन के रूप में एक चर का उपयोग किया और यह खुशी थी।

कोड कुछ इस तरह दिखाई देगा:

sed -i "/TEXT_TO_BE_REPLACED/c $REPLACEMENT_TEXT_STRING" /tmp/foo

एकल उद्धरणों के बजाय दोहरे उद्धरण चिह्नों के उपयोग पर ध्यान दें।


आप अभी भी इस तरह एकल उद्धरणों का उपयोग कर सकते हैं: sed -i '/ TEXT_TO_BE_REPLACED / c' "$ VARIABLE" '' / tmp / foo
Alistair McIntyre

4

अब तक प्रदान किए गए सभी उत्तर यह मानते हैं कि आप पाठ के बारे में कुछ जानते हैं जिसे प्रतिस्थापित किया जा सकता है, जो कि ओपी से पूछा गया है। मैं एक उत्तर प्रदान कर रहा हूं जो मानता है कि आपको पाठ के बारे में कुछ भी नहीं पता है कि प्रतिस्थापित किया जा सकता है और यह कि एक ही या समान सामग्री के साथ फाइल में एक अलग लाइन हो सकती है जिसे आप प्रतिस्थापित नहीं करना चाहते हैं। इसके अलावा, मैं मान रहा हूँ कि आपको पता है कि लाइन की लाइन संख्या को प्रतिस्थापित किया जाना है।

निम्नलिखित उदाहरण विशिष्ट पंक्ति संख्याओं द्वारा पाठ को हटाने या बदलने का प्रदर्शन करते हैं:

# replace line 17 with some replacement text and make changes in file (-i switch)
# the "-i" switch indicates that we want to change the file. Leave it out if you'd
#   just like to see the potential changes output to the terminal window.
# "17s" indicates that we're searching line 17
# ".*" indicates that we want to change the text of the entire line
# "REPLACEMENT-TEXT" is the new text to put on that line
# "PATH-TO-FILE" tells us what file to operate on
sed -i '17s/.*/REPLACEMENT-TEXT/' PATH-TO-FILE

# replace specific text on line 3
sed -i '3s/TEXT-TO-REPLACE/REPLACEMENT-TEXT/'

3

कॉन्फ़िगर फ़ाइलों के हेरफेर के लिए

मैं इस समाधान के साथ आया जो कि स्केंसल उत्तर से प्रेरित था

configLine [searchPattern] [replaceLine] [filePath]

यह:

  • मौजूद नहीं है तो फ़ाइल बनाएँ
  • पूरी पंक्ति (सभी पंक्तियों) को बदलें जहाँ सर्चपार्टन मेल खाता हो
  • यदि पैटर्न नहीं मिला तो फाइल के अंत में रिप्लेसमेंट जोड़ें

समारोह:

function configLine {
  local OLD_LINE_PATTERN=$1; shift
  local NEW_LINE=$1; shift
  local FILE=$1
  local NEW=$(echo "${NEW_LINE}" | sed 's/\//\\\//g')
  touch "${FILE}"
  sed -i '/'"${OLD_LINE_PATTERN}"'/{s/.*/'"${NEW}"'/;h};${x;/./{x;q100};x}' "${FILE}"
  if [[ $? -ne 100 ]] && [[ ${NEW_LINE} != '' ]]
  then
    echo "${NEW_LINE}" >> "${FILE}"
  fi
}

पागल निकास स्थिति जादू https://stackoverflow.com/a/12145797/1262663 से आता है


2
bash-4.1$ new_db_host="DB_HOSTNAME=good replaced with 122.334.567.90"
bash-4.1$ 
bash-4.1$ sed -i "/DB_HOST/c $new_db_host" test4sed
vim test4sed
'
'
'
DB_HOSTNAME=good replaced with 122.334.567.90
'

यह बढ़िया काम करता है


1

मेरे मेकफाइल में मैं इसका उपयोग करता हूं:

@sed -i '/.*Revision:.*/c\'"`svn info -R main.cpp | awk '/^Rev/'`"'' README.md

पुनश्च: यह मत भूलो कि -i वास्तव में फ़ाइल में पाठ को बदलता है ... इसलिए यदि आपने "संशोधन" के रूप में परिभाषित किया गया पैटर्न बदल जाएगा, तो आप बदलने के लिए पैटर्न भी बदल देंगे।

उदाहरण आउटपुट:

एबीसी-प्रोजेक्ट जॉन डो द्वारा लिखित

संशोधन: ११ ९ ०

इसलिए यदि आप पैटर्न "रिविजन: 1190" सेट करते हैं, तो यह स्पष्ट रूप से वैसा नहीं है जैसा आपने उन्हें "रिविजन:" केवल के रूप में परिभाषित किया है ...


1
cat find_replace | while read pattern replacement ; do
sed -i "/${pattern}/c ${replacement}" file    
done 

find_replace फ़ाइल में 2 कॉलम, मैच के लिए पैटर्न के साथ c1, प्रतिस्थापन के साथ c2 है, sed लूप प्रत्येक रेखा को चर के पैटर्न में से एक को बदलते हुए प्रतिस्थापित करता है 1


नहीं, यह कई मामलों में गलत है। sedस्क्रिप्ट फ़ाइल के साथ एक बार चलाएं जिसमें सभी प्रतिस्थापन हैं जो आप करना चाहते हैं। sed -iएक ही फाइल पर बार-बार दौड़ना एक भयानक एंटीपैटर्न है।
ट्रिपलए

0

यह ऊपर के समान है ।।

sed 's/[A-Za-z0-9]*TEXT_TO_BE_REPLACED.[A-Za-z0-9]*/This line is removed by the admin./'

3
ऐसा FOO=TEXT_TO_BE_REPLACEDकरने के लिए परिवर्तन FOO=This line ...विनिर्देश को पूरा नहीं करता है।
जेन्स

हां .. हमारी आवश्यकता पूरी लाइन को 'इस लाइन को व्यवस्थापक द्वारा हटाए जाने के साथ' बदलने की है। अगर हमें प्रमुख संरक्षक 'TEXT_TO_BE_REPLACED' मिला। उपरोक्त आदेश संतोषजनक है। अगर मेरी समझ गलत है तो मुझे ठीक करें .. @ जैन
अन्नपूर्णे हरि

@AnnapureddyHari यह उत्तर काम नहीं करता है यदि खोज स्ट्रिंग से पहले या बाद के पाठ में ए-ज़-ज़0-9 के अलावा इसमें कुछ भी है। यह बराबर होता है अगर वहाँ एक समान संकेत है, जैसा कि जेन्स ने बताया। "FOO =" भाग रहेगा; आपने पूरी लाइन नहीं बदली है। यह कोड फ़ाइल में क्या हो सकता है, इस बारे में कम देखा गया है। यदि आपका मतलब वाइल्डकार्ड से है, तो आपको वाइल्डकार्ड लगाना चाहिए, जैसा कि थोर के जवाब से पता चलता है।
21

0

नीचे कमांड मेरे लिए काम कर रहा है। जो चरों के साथ काम कर रहा है

sed -i "/\<$E\>/c $D" "$B"

लेकिन मेरी नई आवश्यकता एसकेआईपी की जगह लेती है (# के साथ शुरू होती है)। जैसा कि हम पूरी लाइन की जगह ले रहे हैं, यह टिप्पणी की गई लाइनों को भी बदल देगा और आप डुप्लिकेट गुणों के साथ समाप्त हो जाएंगे। अगर किसी के पास इसका समाधान है तो कृपया मुझे बताएं।
रितेश बोरकर

-1

मैं बहुत बार regex का उपयोग उन फ़ाइलों से डेटा निकालने के लिए करता हूं, जिनका उपयोग मैंने शाब्दिक उद्धरण \"को //कुछ नहीं करने के लिए किया है :-)

cat file.csv | egrep '^\"([0-9]{1,3}\.[0-9]{1,3}\.)' | sed  s/\"//g  | cut -d, -f1 > list.txt
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.