sed - dizeyi dosya içeriğiyle değiştirir


22

İki dosyam var: file1ve file2.

file1 aşağıdaki içeriğe sahiptir:

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

file2bir IP adresi içerir ( 1.1.1.1)

Yapmak istediğim şey localhostbununla değiştirmektir 1.1.1.1, böylece sonuç şöyledir:

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

Denedim:

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

Ama ya tüm çizgiyi değiştirdim, ya da IP değiştirmem gerekenden sonra çizgiye gidiyor.


1
emin değilim ama cat file1 | sed -e 's/localhost/1.1.1.1/g'çalışıyor mu?
dchirikov

1
\rSed komutuna bak .
Kevin

Yanıtlar:


14

İşte bir sedçözüm:

% 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 -iDeğişikliği yerinde yapmak için kullanmalısınız .

Kullanabiliyorsanız awk, işte yapmanın bir yolu:

% 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
İçin +1 awk. Hayal sed olduğunu bu yeteneğine, ancak korkunç hantal olacaktır. Burası awkparlıyor!
HalosGhost

1
@HalosGhost: Hem ben hem de OP sorusunu yanlış anladınız, cevabımı güncelledim.
cuonglm

Çözüm için komut değiştirme işlemi sed, dosyanın boşluk veya küre karakterleri içermesi durumunda iki kez alıntılanmalıdır.
Graeme

@Graeme: Teşekkürler, güncellendi! Düzenleme yapmaktan çekinmeyin.
cuonglm

2
İkisinden de /ve &yerine geçerek kaçmanız gerekir . İşte"$(sed 's:[/\\&]:\\&:g' file2)"
Toby Speight

6

sedKullanılmadan önce , dosyayı shell dizisi yerine kullanılan değiştirme dizgisiyle okuyabilirsiniz . Yani sednormal bir oyuncu değişikliği göreceksiniz:

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


18
Bu çok çizgili dosyalar ve özel karakterli dosyalar üzerinde çalışıyor mu?
Trevor Hickey

9
@TrevorHickey öyle değil. Sed, sadece "sonlandırılmamış" komutuyla "hata vererek başarısız oluyor.
DarioP,

1

Kullanmayı deneyin

join file1 file2

ve sonra istenmeyen alanları kaldırın.


1

Bugün bu "problemi" de vardı: bir metin bloğunun başka bir dosyadaki içerikle nasıl değiştirileceği.

Ben bir bash işlevi yaparak (komut dosyalarında yeniden kullanılabilir) çözdüm.

[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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.