sed - प्रतिस्थापित स्ट्रिंग को फ़ाइल सामग्री के साथ


22

मेरे पास दो फाइलें हैं: file1और file2

file1 निम्नलिखित सामग्री है:

---
  host: "localhost"
  port: 3000
  reporter_type: "zookeeper"
  zk_hosts: 
    - "localhost:2181"

file2एक आईपी पता शामिल है ( 1.1.1.1)

मैं जो करना चाहता हूं, उसे बदल दिया localhostजाता है 1.1.1.1, ताकि अंतिम परिणाम हो:

---
  host: "1.1.1.1"
  port: 3000
  reporter_type: "zookeeper"
  zk_hosts: 
    - "1.1.1.1:2181"

मैंने कोशिश की है:

sed -i -e "/localhost/r file2" -e "/localhost/d" file1
sed '/localhost/r file2' file1 |sed '/localhost/d'
sed -e '/localhost/r file2' -e "s///" file1

लेकिन मुझे या तो पूरी लाइन बदलनी है, या जिस आईपी को मैं संशोधित करने की आवश्यकता है उसके बाद लाइन पर जा रहा हूं।


1
यकीन नहीं है, लेकिन cat file1 | sed -e 's/localhost/1.1.1.1/g'काम करता है ?
डचीरिकोव

1
को देखो \rsed कमान।
केविन

जवाबों:


14

यहाँ एक sedसमाधान है:

% sed -e "s/localhost/$(sed 's:/:\\/:g' file2)/" file1
---
  host: "1.1.1.1"
  port: 3000
  reporter_type: "zookeeper"
  zk_hosts: 
    - "1.1.1.1:2181"

आपको sed -iपरिवर्तन करने के लिए उपयोग करना चाहिए ।

यदि आप उपयोग कर सकते हैं awk, तो यहां एक तरीका है:

% awk 'BEGIN{getline l < "file2"}/localhost/{gsub("localhost",l)}1' file1
---
  host: "1.1.1.1"
  port: 3000
  reporter_type: "zookeeper"
  zk_hosts: 
    - "1.1.1.1:2181"

4
के लिए +1 awk। मुझे लगता है कि sed यह सक्षम है, लेकिन यह बहुत ही भद्दा होगा। यह वह जगह है जहाँ awkचमकता है!
हालोसगॉस्ट जूल

1
@ हेलोसगॉस्ट: ऐसा लगता है कि मैं और आप दोनों ओपी प्रश्न को गलत समझ रहे थे, मैंने अपना उत्तर अपडेट कर दिया।
congonglm

sedयदि फ़ाइल में स्थान या ग्लोब वर्ण हैं , तो समाधान के लिए कमांड प्रतिस्थापन डबल उद्धृत होना चाहिए।
ग्रीम

@ ग्रेमी: धन्यवाद, अपडेट किया गया! एक संपादन करने के लिए स्वतंत्र महसूस करें।
congonglm

2
आप दोनों से बचने के लिए की जरूरत है /और &प्रतिस्थापन में। वह"$(sed 's:[/\\&]:\\&:g' file2)"
टोबी स्पाइट

6

आप शेल कमांड प्रतिस्थापन का उपयोग करके फ़ाइल को प्रतिस्थापन स्ट्रिंग के साथ पढ़ सकते हैं, इससे पहले कि sedइसका उपयोग किया जाता है। तो sedबस एक सामान्य प्रतिस्थापन देखेंगे:

sed "s/localhost/$(cat file2)/" file1 > changed.txt


18
क्या यह बहु-पंक्तिबद्ध फाइलों और विशेष वर्णों वाली फाइलों पर काम करता है?
ट्रेवर हिक्की

9
@TrevorHickey यह नहीं है। सिड सिर्फ एक "अनमैरीनेटेड` s कमांड "त्रुटि के साथ विफल होता है।
DaroPP

1

प्रयोग करके देखें

join file1 file2

और फिर, किसी भी अवांछित फ़ील्ड को हटा दें।


1

मुझे आज यह "समस्या" भी थी: किसी अन्य फ़ाइल से सामग्री के साथ पाठ के ब्लॉक को कैसे बदलना है।

मैंने इसे बैश फंक्शन बनाकर हल किया है (जो स्क्रिप्ट में पुन: उपयोग किया जा सकता है)।

[cent@pcmk-1 tmp]$ cat the_function.sh
# This function reads text from stdin, and substitutes a *BLOCK* with the contents from a FILE, and outputs to stdout
# The BLOCK is indicated with BLOCK_StartRegexp and BLOCK_EndRegexp
#
# Usage:
#    seq 100 110 | substitute_BLOCK_with_FILEcontents '^102' '^104' /tmp/FileWithContents > /tmp/result.txt
function substitute_BLOCK_with_FILEcontents {
  local BLOCK_StartRegexp="${1}"
  local BLOCK_EndRegexp="${2}"
  local FILE="${3}"
  sed -e "/${BLOCK_EndRegexp}/a ___tmpMark___" -e "/${BLOCK_StartRegexp}/,/${BLOCK_EndRegexp}/d" | sed -e "/___tmpMark___/r ${FILE}" -e '/___tmpMark___/d'
}

[cent@pcmk-1 tmp]$
[cent@pcmk-1 tmp]$
[cent@pcmk-1 tmp]$ cat /tmp/FileWithContents
We have deleted everyhing between lines 102 and 104 and
replaced with this text, which was read from a file
[cent@pcmk-1 tmp]$
[cent@pcmk-1 tmp]$
[cent@pcmk-1 tmp]$ source the_function.sh
[cent@pcmk-1 tmp]$ seq 100 110 | substitute_BLOCK_with_FILEcontents '^102' '^104' /tmp/FileWithContents > /tmp/result.txt
[cent@pcmk-1 tmp]$
[cent@pcmk-1 tmp]$
[cent@pcmk-1 tmp]$ cat /tmp/result.txt
100
101
We have deleted everyhing between lines 102 and 104 and
replaced with this text, which was read from a file
105
106
107
108
109
110
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.