sed - ganti string dengan konten file

22

Saya punya dua file: file1dan file2.

file1 memiliki konten berikut:

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

file2berisi alamat IP ( 1.1.1.1)

Yang ingin saya lakukan adalah mengganti localhostdengan 1.1.1.1, sehingga hasil akhirnya adalah:

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

Saya telah mencoba:

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

Tapi saya bisa mengganti seluruh baris, atau IP ke baris setelah saya perlu memodifikasi.

Jay Kah
sumber
1
tidak yakin, tetapi apakah cat file1 | sed -e 's/localhost/1.1.1.1/g'berhasil?
dchirikov
1
Lihatlah \rperintah sed.
Kevin

Jawaban:

14

Ini sedsolusinya:

% 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"

Anda harus menggunakan sed -iuntuk membuat perubahan di tempat.

Jika Anda dapat menggunakan awk, berikut adalah salah satu cara untuk melakukannya:

% 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"
cuonglm
sumber
4
+1 untuk awk. Aku membayangkan sed ini mampu ini, tetapi akan menjadi sangat canggung. Di sinilah awkbersinar!
HalosGhost
1
@HalosGhost: Sepertinya saya dan Anda salah paham tentang pertanyaan OP, saya memperbarui jawaban saya.
cuonglm
Substitusi perintah untuk sedsolusi harus dikutip ganda jika file tersebut berisi spasi atau karakter glob.
Graeme
@Graeme: Terima kasih, diperbarui! Merasa bebas untuk mengedit.
cuonglm
2
Anda perlu untuk melarikan diri baik /dan &di substitusi. Itu"$(sed 's:[/\\&]:\\&:g' file2)"
Toby Speight
6

Anda dapat membaca file dengan string pengganti menggunakan substitusi perintah shell, sebelum seddigunakan. Jadi sedhanya akan melihat substitusi normal:

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

Volker Siegel
sumber
18
Apakah ini berfungsi pada file multi-baris dan file dengan karakter khusus?
Trevor Hickey
9
@ TrevorHickey tidak. Sed hanya gagal dengan kesalahan "perintah` s 'yang tidak ditentukan ".
DarioP
1

Coba gunakan

join file1 file2

dan kemudian, hapus bidang yang tidak diinginkan.

unxnut
sumber
1

Saya juga punya "masalah" ini hari ini: bagaimana cara mengganti blok teks dengan konten dari file lain.

Saya telah menyelesaikannya dengan membuat fungsi bash (yang dapat digunakan kembali dalam skrip).

[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
zipizap
sumber