sed - заменить строку содержимым файла


22

У меня есть два файла: file1и file2.

file1 имеет следующее содержание:

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

file2содержит IP-адрес ( 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

Но я либо заменяю всю строку, либо IP-адрес идет на линию после той, которую мне нужно изменить.


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светит!
HalosGhost

1
@HalosGhost: Кажется, я и ты неправильно поняли вопрос ОП, я обновил свой ответ.
Cuonglm

Подстановка команды для sedрешения должна быть заключена в двойные кавычки, если файл содержит пробелы или символы глобуса.
Грэм

@Graeme: Спасибо, обновлено! Не стесняйтесь делать редактирование.
Cuonglm

2
Вам нужно сбежать /и &в замене. Это"$(sed 's:[/\\&]:\\&:g' file2)"
Тоби Спейт

6

Вы можете прочитать файл со строкой замены, используя подстановку команд оболочки, прежде чем sedиспользовать. Так sedчто увидим просто нормальную замену:

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


18
Работает ли это на многострочных файлах и файлах со специальными символами?
Тревор Хикки

9
@TrevorHickey это не так. Sed просто терпит неудачу с ошибкой «неопределенная команда s».
DarioP

1

Попробуйте использовать

join file1 file2

а затем удалите все ненужные поля.


1

У меня сегодня тоже была такая «проблема»: как заменить блок текста содержимым из другого файла.

Я решил это, создав функцию bash (которую можно использовать в скриптах).

[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 и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.